[
  {
    "name": "a11y-keyboard",
    "tier": "free",
    "category": "component",
    "description": "Collect focusable menu items inside a menu container.",
    "usage": "focusMenuItemTypeahead(root, event.key, document.activeElement)",
    "keywords": [
      "a11y-keyboard",
      "a11y",
      "keyboard"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "e2d5928e1acdaadcd37900eac6cd763e22a3fa90f4573fd9c102ed83d39252ed"
  },
  {
    "name": "accordion",
    "tier": "free",
    "category": "component",
    "description": "A container component for accordion items.",
    "usage": "<ply-accordion [multi]=\"false\">",
    "keywords": [
      "accordion",
      "collapse",
      "disclosure"
    ],
    "dependencies": [
      "rxjs"
    ],
    "registryDependencies": [
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "b928964517a12df462561a2e58b23f55c51dcf910ec003a6fdfcbf87471264aa"
  },
  {
    "name": "alert",
    "tier": "free",
    "category": "component",
    "description": "A highly configurable alert component for displaying important messages.",
    "usage": "<ply-alert color=\"danger\" variant=\"soft\" [close]=\"true\" (closed)=\"onClose()\">",
    "keywords": [
      "alert"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "4dcf71467b849cef6e3a89b4f179ea2b35dbace7e91a78c882f5daee0aca082d"
  },
  {
    "name": "animated-counter",
    "tier": "free",
    "category": "component",
    "description": "Free tier. Animates a number from a start value to the target the first time the host element enters the viewport (IntersectionObserver, threshold 0.2).",
    "usage": "<ply-animated-counter [value]=\"48295\" prefix=\"$\" separator=\",\"></ply-animated-counter>",
    "keywords": [
      "animated-counter",
      "animated",
      "counter"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "20e1122893ac5c19009e610faf9f238875fd68498afc05fc1d0283538a5e8cd8"
  },
  {
    "name": "animations",
    "tier": "free",
    "category": "component",
    "description": "Slide-down fade-in animation for dropdown menus and overlays.",
    "usage": "<div [@dropdown]>",
    "keywords": [
      "animations"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "1e7899f90f8da242a4e3f4a0fadf029122cc949e1dea342656cbdb5b1f42bbe0"
  },
  {
    "name": "article-card-editorial",
    "tier": "pro",
    "category": "block",
    "description": "Editorial-style article card with fully hard-coded demo content, composed from `ply-card`/`ply-card-body`.",
    "usage": "<ply-article-card-editorial></ply-article-card-editorial>",
    "keywords": [
      "article-card-editorial",
      "block",
      "article",
      "card",
      "editorial"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon",
      "quote"
    ],
    "type": "components:ui",
    "digest": "5d323882558ea9eb31e71c3d28ab5ec85534659ae4bedcce6c274f1f3d93f132"
  },
  {
    "name": "article-card-full-reader",
    "tier": "pro",
    "category": "block",
    "description": "Full article reading experience rendered inside a `ply-card`: byline header with prev/more icon buttons, centered title, view/comment/share stats, hero image with caption, numbered content sections (one with a side-by-side image layout), an avatar-left `ply-quote` block, an autho…",
    "usage": "<ply-article-card-full-reader></ply-article-card-full-reader>",
    "keywords": [
      "article-card-full-reader",
      "block",
      "article",
      "card",
      "full",
      "reader"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon",
      "input-group",
      "quote"
    ],
    "type": "components:ui",
    "digest": "9d80ff8921ff0ee054ad1cd9391c02716c48509f6fb8cbbb3ab9c957502fc497"
  },
  {
    "name": "article-card-hero-gallery",
    "tier": "pro",
    "category": "block",
    "description": "Static, pre-composed article card (pro tier) with a full-width hero image section and a mini image gallery.",
    "usage": "<ply-article-card-hero-gallery></ply-article-card-hero-gallery>",
    "keywords": [
      "article-card-hero-gallery",
      "block",
      "article",
      "card",
      "hero",
      "gallery"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "badge",
      "button",
      "card",
      "icon",
      "quote"
    ],
    "type": "components:ui",
    "digest": "89b50dc8a5f34fb277d033dc6650d163d16e3f280b4fba8e76668d29531b54d7"
  },
  {
    "name": "article-card-hero-tags",
    "tier": "pro",
    "category": "block",
    "description": "Pre-composed article/blog-post card with a full-bleed hero image header (dark overlay, back/share/more icon buttons, date, title, and view count rendered over the image).",
    "usage": "<ply-article-card-hero-tags></ply-article-card-hero-tags>",
    "keywords": [
      "article-card-hero-tags",
      "block",
      "article",
      "card",
      "hero",
      "tags"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "badge",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "e4122c8350c64c15c7849ace38c5c113efd8cbb3caca83f375afc3da588c0a99"
  },
  {
    "name": "aspect-ratio",
    "tier": "free",
    "category": "component",
    "description": "Box that preserves a width-to-height ratio via CSS `aspect-ratio`.",
    "usage": "<ply-aspect-ratio ratio=\"16/9\">",
    "keywords": [
      "aspect-ratio",
      "aspect",
      "ratio"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "3447737a0b463e69c5f789c51ed1cd81b63e4727ebd685dda30a4003a4b4e095"
  },
  {
    "name": "avatar",
    "tier": "free",
    "category": "component",
    "description": "A highly customizable avatar component for displaying user profile images or initials.",
    "usage": "<ply-avatar [avatarUrl]=\"user.image\" size=\"lg\" shape=\"circle\" status=\"active\"></ply-avatar>",
    "keywords": [
      "avatar"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "9ae3a7517071954d1db73a0bd53992eba8e03a7a9e5b55e1664e5707c5120a46"
  },
  {
    "name": "avatar-group",
    "tier": "free",
    "category": "component",
    "description": "Displays a stack of overlapping circular avatars with an overflow count badge.",
    "usage": "<ply-avatar-group [items]=\"users\" [max]=\"4\" size=\"md\"></ply-avatar-group>",
    "keywords": [
      "avatar-group",
      "avatar",
      "group"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "045981edc32aabc9283ef823d9c6c51782b546d78989a9ed34268d62baab28ec"
  },
  {
    "name": "badge",
    "tier": "free",
    "category": "component",
    "description": "A configurable badge component to display tiny statuses, counts, or tags.",
    "usage": "<ply-badge color=\"danger\" size=\"sm\" shape=\"rectangular\">New</ply-badge>",
    "keywords": [
      "badge"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "fbfd1d0be65588ff31d3ff5627f1aee4e782031b59f793dd4ad2d7f4800c5592"
  },
  {
    "name": "base-context-menu-item",
    "tier": "free",
    "category": "component",
    "description": "Styles a button or link as a context menu item (`role=\"menuitem\"`).",
    "usage": "<button ply-context-menu-item (click)=\"copy()\">Copy</button>",
    "keywords": [
      "base-context-menu-item",
      "context",
      "menu",
      "item",
      "context-menu-item"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "daf62940a2b73f64355d5f495d2a71795bf6141f07c2925f7082d2e9fadbf61f"
  },
  {
    "name": "base-dropdown-menu-item",
    "tier": "free",
    "category": "component",
    "description": "An individual item within a `ply-dropdown-menu`.",
    "usage": "<button ply-dropdown-menu-item (click)=\"doSomething()\">Click Me</button>",
    "keywords": [
      "base-dropdown-menu-item",
      "dropdown",
      "menu",
      "item",
      "dropdown-menu-item"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "a9b740fff9b185bafb947ffffd30cdec7e5fae31cd334d30824261aaaa370970"
  },
  {
    "name": "base-group-button",
    "tier": "free",
    "category": "component",
    "description": "A standard group button directive applying Lussos theme styles.",
    "usage": "<button ply-group-button color=\"primary\" size=\"lg\">Button</button>",
    "keywords": [
      "base-group-button",
      "group",
      "button",
      "group-button"
    ],
    "dependencies": [],
    "registryDependencies": [
      "types"
    ],
    "type": "components:ui",
    "digest": "993b26c6914545c1276a694503ebef2de68999e57eee086dcc9a582ccac34af9"
  },
  {
    "name": "base-list-item",
    "tier": "free",
    "category": "component",
    "description": "A stylistic directive that applies standardized padding, height, and hover effects for an item within a generic list view.",
    "usage": "<ul>",
    "keywords": [
      "base-list-item",
      "list",
      "item",
      "list-item"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "952e1d9a8d8dff57fc8168dd0139a94d5b91932ec144c85fb42856c97d834654"
  },
  {
    "name": "base-tab-icon",
    "tier": "free",
    "category": "component",
    "description": "A structural directive that styles a `<ply-icon>` projected inside a `ply-tab-label`.",
    "usage": "<ply-tab-label>",
    "keywords": [
      "base-tab-icon",
      "tab",
      "icon",
      "plyTabIcon"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "355a4dc4ae04409bb4e1a83659e39ff71a0d0d54920fd1c97c06059da40f304a"
  },
  {
    "name": "blog-card-centered-hero",
    "tier": "pro",
    "category": "block",
    "description": "Static blog-post card with a centered hero layout, composed from `ply-card`, `ply-card-body`, and `ply-card-footer`.",
    "usage": "<ply-blog-card-centered-hero></ply-blog-card-centered-hero>",
    "keywords": [
      "blog-card-centered-hero",
      "block",
      "blog",
      "card",
      "centered",
      "hero"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "ae64049a6cdad480bf0ebf9884d2c432ddcc82c6293e65ef9b703883f01f2b6e"
  },
  {
    "name": "blog-card-collage",
    "tier": "pro",
    "category": "block",
    "description": "Pre-composed blog post card with a two-image collage header, a category eyebrow label (\"Feature\"), a title, and a footer showing an author avatar/name plus date and comment-count icon stats.",
    "usage": "<ply-blog-card-collage></ply-blog-card-collage>",
    "keywords": [
      "blog-card-collage",
      "block",
      "blog",
      "card",
      "collage"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "147aeb111dc0ce1695a777ff6c206967d919a09fae66d310515ee16bf945a1a7"
  },
  {
    "name": "blog-card-compact",
    "tier": "pro",
    "category": "block",
    "description": "Compact blog-post card block (pro tier) composed from `ply-card`, `ply-card-body`, `ply-card-footer`, `ply-avatar`, and `ply-icon`.",
    "usage": "<ply-blog-card-compact></ply-blog-card-compact>",
    "keywords": [
      "blog-card-compact",
      "block",
      "blog",
      "card",
      "compact"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "9fabf88a227bd8969c952778d1eb17f9e71f8f94fa048c411c8e9e0caf1b592b"
  },
  {
    "name": "blog-card-floating-panel",
    "tier": "pro",
    "category": "block",
    "description": "Preset blog-post card rendering a full-height cover image with a frosted-glass (backdrop-blur) panel floating over its bottom edge; the panel shows a category eyebrow, post title, and a footer with author avatar/name plus calendar-date and comment-count icon stats.",
    "usage": "<ply-blog-card-floating-panel></ply-blog-card-floating-panel>",
    "keywords": [
      "blog-card-floating-panel",
      "block",
      "blog",
      "card",
      "floating",
      "panel"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "289b13a5e8f553212f9b89e9f869d4fd848ae4c9588c890a9a615ef802d41fbf"
  },
  {
    "name": "blog-card-gradient-hero",
    "tier": "pro",
    "category": "block",
    "description": "Pre-composed blog hero card (pro tier) built from `ply-card`, `ply-card-body`, `ply-card-footer`, `ply-avatar`, and `ply-icon`.",
    "usage": "<ply-blog-card-gradient-hero></ply-blog-card-gradient-hero>",
    "keywords": [
      "blog-card-gradient-hero",
      "block",
      "blog",
      "card",
      "gradient",
      "hero"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "96904e841f124995d047d5be7cfb91615d195d74de84406c9529cc10a1bba502"
  },
  {
    "name": "blog-card-horizontal-feature",
    "tier": "pro",
    "category": "block",
    "description": "Static horizontal featured blog card composed from `ply-card`, `ply-card-body`, `ply-card-footer`, `ply-avatar`, and `ply-icon`.",
    "usage": "<ply-blog-card-horizontal-feature></ply-blog-card-horizontal-feature>",
    "keywords": [
      "blog-card-horizontal-feature",
      "block",
      "blog",
      "card",
      "horizontal",
      "feature"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "fdc87e345c5344a7a0d0be1493b1cf1ac256b483eb90c474a13e66cbdb2e27de"
  },
  {
    "name": "blog-card-image-top",
    "tier": "pro",
    "category": "block",
    "description": "Pre-composed blog/article preview card with a top cover image, built from `ply-card`, `ply-card-body`, `ply-card-footer`, `ply-avatar`, and `ply-icon`.",
    "usage": "<ply-blog-card-image-top></ply-blog-card-image-top>",
    "keywords": [
      "blog-card-image-top",
      "block",
      "blog",
      "card",
      "image",
      "top"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "70e153c5f7ec233bb8dbd68a0529c4291a42d97725b1eadbc9e48d7aff17ff4a"
  },
  {
    "name": "blog-card-inline-image",
    "tier": "pro",
    "category": "block",
    "description": "Blog post card with the article image inset between the title block and the footer (title above, full-width 180px cover image in the middle, meta footer below).",
    "usage": "<ply-blog-card-inline-image></ply-blog-card-inline-image>",
    "keywords": [
      "blog-card-inline-image",
      "block",
      "blog",
      "card",
      "inline",
      "image"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "05a5e2d8e384f5e82fce61930dc27789d7227ddeb3b34884c393a7caf253a925"
  },
  {
    "name": "blog-card-mini-grid",
    "tier": "pro",
    "category": "block",
    "description": "Compact blog-list card built on `ply-card`/`ply-card-body`, rendering four hardcoded mini blog entries (64px square thumbnail plus bold title) in a responsive grid — single column on small screens, 2x2 on `lg`.",
    "usage": "<ply-blog-card-mini-grid></ply-blog-card-mini-grid>",
    "keywords": [
      "blog-card-mini-grid",
      "block",
      "blog",
      "card",
      "mini",
      "grid"
    ],
    "dependencies": [],
    "registryDependencies": [
      "card"
    ],
    "type": "components:ui",
    "digest": "208cddd947920d4c3094b48c28682462879be399f5cc78737b590effc4ed03b6"
  },
  {
    "name": "blog-card-newsletter",
    "tier": "pro",
    "category": "block",
    "description": "Static newsletter signup promo card styled as an indigo gradient panel, composed from `ply-card`, `ply-card-body`, and `ply-card-footer` with a large decorative `ply-icon` (\"mail\") watermark.",
    "usage": "<ply-blog-card-newsletter></ply-blog-card-newsletter>",
    "keywords": [
      "blog-card-newsletter",
      "block",
      "blog",
      "card",
      "newsletter"
    ],
    "dependencies": [],
    "registryDependencies": [
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "147af63197b3e88ea2d924bee8073ec623224b0074fe3aa51f2382b32c3ec2c4"
  },
  {
    "name": "blog-card-overlay-featured",
    "tier": "pro",
    "category": "block",
    "description": "Featured blog card with a full-bleed background image and a left-side gradient overlay panel (dark slate to transparent) containing an eyebrow label, large title, and excerpt, plus a footer row with author avatar, name, and a publish date (date hidden below the `sm` breakpoint).",
    "usage": "<ply-blog-card-overlay-featured></ply-blog-card-overlay-featured>",
    "keywords": [
      "blog-card-overlay-featured",
      "block",
      "blog",
      "card",
      "overlay",
      "featured"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "fd910c1d354e0e4ef172c3fce51ef8f4337791bb1ee75394a685063c95dea418"
  },
  {
    "name": "blog-card-overlay-marketing",
    "tier": "pro",
    "category": "block",
    "description": "Pre-styled marketing blog card with a full-bleed cover image and a bottom-anchored text overlay on a dark gradient.",
    "usage": "<ply-blog-card-overlay-marketing></ply-blog-card-overlay-marketing>",
    "keywords": [
      "blog-card-overlay-marketing",
      "block",
      "blog",
      "card",
      "overlay",
      "marketing"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "406774df40d6fe88028281b818316f23540421312247bd290e42d90550fecd8c"
  },
  {
    "name": "blog-card-quote",
    "tier": "pro",
    "category": "block",
    "description": "Pre-styled blog quote card with fully static content: an orange-tinted `ply-card` (left orange accent border, light/dark variants) containing a large serif italic pull-quote, a decorative rotated quotation-mark SVG watermark, and a footer with a `ply-avatar` plus hardcoded author…",
    "usage": "<ply-blog-card-quote></ply-blog-card-quote>",
    "keywords": [
      "blog-card-quote",
      "block",
      "blog",
      "card",
      "quote"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card"
    ],
    "type": "components:ui",
    "digest": "28c9248c6c16aa4e1ffdb426ca6f1a6c743786ab3e05254901db57f4942368f5"
  },
  {
    "name": "blog-card-split-image",
    "tier": "pro",
    "category": "block",
    "description": "Pre-composed blog post card with a split two-image header: two side-by-side cover images (each 50% width) above a category label, title, and a footer with author avatar/name plus date and comment-count icon stats.",
    "usage": "<ply-blog-card-split-image></ply-blog-card-split-image>",
    "keywords": [
      "blog-card-split-image",
      "block",
      "blog",
      "card",
      "split",
      "image"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "1b24e8e21c682f86e68003da706e6cd4cb1844c88d4abacc21b26e0d3f95d4f0"
  },
  {
    "name": "blog-card-stats",
    "tier": "pro",
    "category": "block",
    "description": "Preset statistic blog card built from `ply-card`, `ply-card-body`, and `ply-card-footer`.",
    "usage": "<ply-blog-card-stats></ply-blog-card-stats>",
    "keywords": [
      "blog-card-stats",
      "block",
      "blog",
      "card",
      "stats"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card"
    ],
    "type": "components:ui",
    "digest": "a6295e233d4ea36ee9a963c8a5f3f09a9bac8a4a8cb8d4721890860bcc594df6"
  },
  {
    "name": "blog-card-video",
    "tier": "pro",
    "category": "block",
    "description": "Static video-teaser blog card built on `ply-card`/`ply-card-body`: a full-bleed cover image (hardcoded to `assets/images/modern_office_architecture_1776362675453.png`) under a dark overlay with a centered frosted-glass \"Play Video\" pill containing a `play-circle` icon.",
    "usage": "<ply-blog-card-video></ply-blog-card-video>",
    "keywords": [
      "blog-card-video",
      "block",
      "blog",
      "card",
      "video"
    ],
    "dependencies": [],
    "registryDependencies": [
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "2b1419cf599f25c6314ee3700887735b9e3c0f491558eea6eb30b3a6f43e0c2a"
  },
  {
    "name": "bottom-sheet",
    "tier": "free",
    "category": "component",
    "description": "Mobile-style modal panel that slides up from the bottom of the screen with a fading, blurred backdrop.",
    "usage": "<ply-bottom-sheet [(open)]=\"isOpen\" height=\"half\" (closed)=\"onClosed()\">",
    "keywords": [
      "bottom-sheet",
      "bottom",
      "sheet",
      "drawer"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "animations",
      "button",
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "47d098371a4c043fa2946735472b1b4c419d0ef5bb7e56908e7e7b3352506c91"
  },
  {
    "name": "breadcrumb",
    "tier": "free",
    "category": "component",
    "description": "A container component for breadcrumb navigation.",
    "usage": "<ply-breadcrumb>",
    "keywords": [
      "breadcrumb"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "57306b288c7d386c8f57b6713177376112b49c88823927428dfc7244275e66d2"
  },
  {
    "name": "button",
    "tier": "free",
    "category": "component",
    "description": "A standard button directive.",
    "usage": "<button ply-button color=\"primary\" size=\"lg\">Submit</button>",
    "keywords": [
      "button",
      "cta",
      "submit"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "f29c477f04aa95023a7a80ad307b8dce2e74f4d8f3ed381ef8f3497ae4961ffb"
  },
  {
    "name": "button-group",
    "tier": "free",
    "category": "component",
    "description": "A container for grouping multiple toggle buttons.",
    "usage": "<ply-button-group size=\"sm\" [(ngModel)]=\"viewMode\">",
    "keywords": [
      "button-group",
      "button",
      "group",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [
      "rxjs"
    ],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "ec53e5c3ce4bb4995b8366cfa4f75eda6aa5c3501f94fe4388405ca9d6cb98c1"
  },
  {
    "name": "calendar",
    "tier": "free",
    "category": "component",
    "description": "A date picker calendar component that supports single date and date-range selection.",
    "usage": "<ply-calendar mode=\"single\" (dateSelected)=\"onDateChange($event)\"></ply-calendar>",
    "keywords": [
      "calendar",
      "datepicker",
      "date"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "21311efb9b422e0d13737bf182355dfe19818773e17c30d06966f8c08004e97c"
  },
  {
    "name": "card",
    "tier": "free",
    "category": "component",
    "description": "A flexible card container component used for grouping related content.",
    "usage": "<ply-card [horizontal]=\"true\">",
    "keywords": [
      "card"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "661be36d75241a82bd3eb7b5522839fc64e3b2e029c2a0b39545fc627d2f485e"
  },
  {
    "name": "carousel",
    "tier": "free",
    "category": "component",
    "description": "A horizontally scrollable container component for presenting multiple items in a row.",
    "usage": "<ply-horizontal-carousel title=\"Featured\">",
    "keywords": [
      "carousel",
      "horizontal-carousel"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "969963ac20b91c9dc62fc2c347028ac32dbd8089d9ab94492226e4b27a3490df"
  },
  {
    "name": "chart",
    "tier": "pro",
    "category": "component",
    "description": "Native SVG chart for dashboards and analytics.",
    "usage": "<ply-chart type=\"bar\" [data]=\"monthlyRevenue\" color=\"primary\"></ply-chart>",
    "keywords": [
      "chart"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "998e9297a85ef866a9f1e3f9c1447eca9e1ec5ce8f025bd77053bdbc00cfee8c"
  },
  {
    "name": "chat",
    "tier": "free",
    "category": "component",
    "description": "AI chat kit: message list, streaming cursor, tool-call rows, and a prompt composer.",
    "usage": "<ply-chat [messages]=\"thread\" [streaming]=\"busy\" (send)=\"ask($event)\" (stop)=\"abort()\"></ply-chat>",
    "keywords": [
      "chat",
      "ai",
      "streaming",
      "llm"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "badge",
      "button",
      "empty-state",
      "icon",
      "spinner",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "fe1000036a5e919cff2d4e69939be9fd400e077c09c3869f102f1b133a3fe3e2"
  },
  {
    "name": "checkbox",
    "tier": "free",
    "category": "component",
    "description": "A custom styled checkbox component that integrates seamlessly with Angular Forms.",
    "usage": "<ply-checkbox [(ngModel)]=\"agree\" color=\"primary\">I agree to the terms</ply-checkbox>",
    "keywords": [
      "checkbox",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "ad7058d84631727d1f5520e2f0b72952a778cf652053643e3db3464557ba4458"
  },
  {
    "name": "chips",
    "tier": "free",
    "category": "component",
    "description": "Pill-shaped chip that projects its label via `ng-content`, with an optional leading `ply-icon` and an optional remove button.",
    "usage": "<ply-chip></ply-chip>",
    "keywords": [
      "chips",
      "chip"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "595987ca44d8060b72ea7a8c895177124015d17631a50130772d6c12c71526a7"
  },
  {
    "name": "click-outside",
    "tier": "free",
    "category": "component",
    "description": "A behavior directive that emits an event whenever the user clicks outside the host element's bounds.",
    "usage": "<div (plyClickOutside)=\"closeMenu()\">Menu Content</div>",
    "keywords": [
      "click-outside",
      "click",
      "outside",
      "plyClickOutside"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "b30fa4b2170b68ba87d3339f56166397803d202596f5f7e33d562f1d149e8e01"
  },
  {
    "name": "code",
    "tier": "free",
    "category": "component",
    "description": "A component to display formatted code blocks with syntax highlighting and a copy-to-clipboard button.",
    "usage": "<ply-code language=\"HTML\" [showCode]=\"true\">",
    "keywords": [
      "code"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "animations",
      "button",
      "icon",
      "safe-timer",
      "toast",
      "tooltip"
    ],
    "type": "components:ui",
    "digest": "8ad20c64a9c309fe02236fb248b47e65a82d0705d92ab9a34d255a3c5a76923e"
  },
  {
    "name": "color-picker",
    "tier": "free",
    "category": "component",
    "description": "Color picker rendered as a swatch trigger button that opens a `position: fixed` panel containing a native `<input type=\"color\">`, a hex text field (validated against `#RRGGBB` before committing), and a grid of preset swatches.",
    "usage": "<ply-color-picker [(ngModel)]=\"brandColor\"></ply-color-picker>",
    "keywords": [
      "color-picker",
      "color",
      "picker",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "4e1f12b1a399ef0e8f019278fe3121b263d7a791b23bca8ef18363cbca4766a8"
  },
  {
    "name": "combobox",
    "tier": "free",
    "category": "component",
    "description": "Searchable single-select with keyboard navigation, optional create, local or async filtering, and Angular Forms (`string | null`).",
    "usage": "<ply-combobox [(ngModel)]=\"userId\" [options]=\"users\" placeholder=\"Search users…\">",
    "keywords": [
      "combobox",
      "autocomplete",
      "typeahead",
      "option-template",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "i18n",
      "icon",
      "spinner",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "7b068b972d1adf77d81f516ad4ed3d94e7207860345f53c8773881c174a42104"
  },
  {
    "name": "coming-soon",
    "tier": "free",
    "category": "component",
    "description": "A placeholder component used to indicate that a feature or page is under construction.",
    "usage": "<ply-coming-soon title=\"Dashboard Analytics\" description=\"We're currently building advanced reporting features. Check back soon!\">",
    "keywords": [
      "coming-soon",
      "coming",
      "soon"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon"
    ],
    "type": "components:ui",
    "digest": "e6cbb268b49e95d1c7dfd8beec8381832177a094514aa7f878591f4a6d9802b1"
  },
  {
    "name": "command-palette",
    "tier": "pro",
    "category": "component",
    "description": "Cmd+K style command palette: when `open` is true it renders a full-screen backdrop plus a centered dialog panel with a search input, grouped command list, and keyboard-hints footer.",
    "usage": "<ply-command-palette [(open)]=\"isOpen\" [items]=\"commands\" (selected)=\"onCommand($event)\">",
    "keywords": [
      "command-palette",
      "command",
      "palette",
      "cmdk",
      "fuzzy",
      "search"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "i18n",
      "icon",
      "input-group",
      "safe-timer"
    ],
    "type": "components:ui",
    "digest": "d4b92d8ed36dd1599601e441744f92900a4f7243264e7874e1d24f3804cf28d5"
  },
  {
    "name": "config",
    "tier": "free",
    "category": "component",
    "description": "Library defaults for sprite paths and icon size.",
    "usage": "provideBaseUI({ iconPath: 'assets/icons.svg' })",
    "keywords": [
      "config",
      "provideBaseUI",
      "iconPath",
      "sprite",
      "icon-path"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "6b7b3cfbe5906fda39dcc4052f5b3f508f6fd82522d9d93627d20d4522251d4f"
  },
  {
    "name": "container",
    "tier": "free",
    "category": "component",
    "description": "A structural directive that forces the host element to act as a centered, max-width container.",
    "usage": "<div container>",
    "keywords": [
      "container"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "e10a7a49e312d97803c5f8932befe050c7d02fb827e8692051862289f7a11b9d"
  },
  {
    "name": "context-menu",
    "tier": "free",
    "category": "component",
    "description": "Right-click context menu panel.",
    "usage": "<div [ply-context-menu-trigger]=\"menu\">Right-click me</div>",
    "keywords": [
      "context-menu",
      "context",
      "menu"
    ],
    "dependencies": [
      "@angular/cdk",
      "rxjs"
    ],
    "registryDependencies": [
      "a11y-keyboard",
      "safe-timer"
    ],
    "type": "components:ui",
    "digest": "c492a9637d4759e64297795482037b6a0ebffe1d40f2a68df0517d9ad78edfc8"
  },
  {
    "name": "cookie-banner",
    "tier": "free",
    "category": "component",
    "description": "Consent banner. Fixed to the viewport by default; pass `inline` to render in document flow (docs/demo surfaces).",
    "usage": "<ply-cookie-banner (accepted)=\"enableAnalytics()\" (rejected)=\"disableAnalytics()\"></ply-cookie-banner>",
    "keywords": [
      "cookie-banner",
      "cookie",
      "banner"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "045e811e736d78e7fa6eaffa3a7be778d20d1bf2c5de1b63b3df86aa26430f8e"
  },
  {
    "name": "countdown",
    "tier": "free",
    "category": "component",
    "description": "Countdown timer that renders a horizontal row (`flex gap-2` host) of boxed digit tiles — days, hours, minutes, seconds — each with a label underneath.",
    "usage": "<ply-countdown [targetDate]=\"launchDate\" (finished)=\"onLaunch()\"></ply-countdown>",
    "keywords": [
      "countdown"
    ],
    "dependencies": [],
    "registryDependencies": [
      "safe-timer",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "3ff539c72ba3db95a83f7b3b592620757a9b0bc34b0688c223dbdf32f24a11fe"
  },
  {
    "name": "crop-image",
    "tier": "pro",
    "category": "component",
    "description": "Pro tier. A component for cropping images, typically used for avatars or profile pictures.",
    "usage": "<ply-crop-image (cropped)=\"onImageCropped($event)\"></ply-crop-image>",
    "keywords": [
      "crop-image",
      "crop",
      "image",
      "cropper"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "spinner",
      "tooltip"
    ],
    "type": "components:ui",
    "digest": "8ebdd07fba0b916d4b66bf8e589cbd1832cfcff7f6074a6850d08b66010a70d0"
  },
  {
    "name": "currency-input",
    "tier": "free",
    "category": "component",
    "description": "Locale-aware currency field.",
    "usage": "<ply-currency-input [(ngModel)]=\"price\" currency=\"USD\"></ply-currency-input>",
    "keywords": [
      "currency-input",
      "currency",
      "input",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "9a6ef03b4b199e7cad4c6f5fe8a118f814696fdf3eaeba609405b328bd118242"
  },
  {
    "name": "current-screen-size",
    "tier": "free",
    "category": "component",
    "description": "A service that monitors viewport resizing and provides the current Tailwind breakpoint (XSmall, Small, Medium, Large, XLarge).",
    "usage": "screen = inject(CurrentScreenSizeService);",
    "keywords": [
      "current-screen-size",
      "current",
      "screen",
      "size",
      "service"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "49268eec38b9dc228f33030403a9895209512bdd13f9560aadcf3db17a323e16"
  },
  {
    "name": "custom-select",
    "tier": "free",
    "category": "component",
    "description": "A highly customizable dropdown select component.",
    "usage": "<ply-custom-select [(ngModel)]=\"selectedId\" [options]=\"users\" displayKey=\"name\" valueKey=\"id\">",
    "keywords": [
      "custom-select",
      "custom",
      "select",
      "dropdown",
      "option-template",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "i18n",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "a5a2602edee95275983cd7ee0091398c618a4970647be5c62bac80c6f93b7f5a"
  },
  {
    "name": "data-table",
    "tier": "pro",
    "category": "component",
    "description": "For a static HTML table without sort/page/select, use free `table` (`npx ply-ui-cli add table`) instead.",
    "usage": "<ply-data-table [columns]=\"columns\" [data]=\"rows\" sortable pageable selectable resizable [(selected)]=\"selectedIds\" (sortChange)=\"onSort($event)\" (pageChange)=\"onPage($event)\">",
    "keywords": [
      "data-table",
      "data",
      "table",
      "datagrid",
      "grid",
      "cell-template",
      "ops-table"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "i18n",
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "e36a7118845ba6ea199b2bc53e684b5725439d9d6557ff0cb87da99dc5b4e277"
  },
  {
    "name": "date-range-picker",
    "tier": "pro",
    "category": "component",
    "description": "An input field that opens a calendar popup specifically for picking start and end date ranges.",
    "usage": "<ply-date-range-picker [(ngModel)]=\"myDateRange\" label=\"Event Period\"></ply-date-range-picker>",
    "keywords": [
      "date-range-picker",
      "date",
      "range",
      "picker",
      "daterange",
      "calendar",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "calendar",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "8d0d6aaccd8762634e7f1a068a9c2f7f1a07da3e12cc314e26cdc202135c53d1"
  },
  {
    "name": "datepicker",
    "tier": "pro",
    "category": "component",
    "description": "A standard date picker input field that opens an overlay calendar popup.",
    "usage": "<ply-datepicker [(ngModel)]=\"startDate\" label=\"Start Date\" placeholder=\"Pick a day\"></ply-datepicker>",
    "keywords": [
      "datepicker",
      "calendar",
      "date",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "button",
      "calendar",
      "icon",
      "input-group",
      "time-picker",
      "types"
    ],
    "type": "components:ui",
    "digest": "4ff0dda9634a8edb430141adc33aa41e5b93f95505494948f35dd9b3d60f399a"
  },
  {
    "name": "dialog",
    "tier": "free",
    "category": "component",
    "description": "A service for dynamically rendering and managing dialogs/modals.",
    "usage": "inject(DialogService).confirm({ title: 'Delete?' })",
    "keywords": [
      "dialog",
      "modal",
      "overlay",
      "popup",
      "confirm",
      "alertdialog",
      "service"
    ],
    "dependencies": [
      "@angular/cdk",
      "rxjs"
    ],
    "registryDependencies": [
      "button",
      "i18n",
      "icon",
      "safe-timer"
    ],
    "type": "components:ui",
    "digest": "f9a42224cf92b1d3eb6e3cb3de05d5f5e925f0f16081e0841ebe2a9d424a1aeb"
  },
  {
    "name": "divider",
    "tier": "free",
    "category": "component",
    "description": "A layout component used to separate content visually.",
    "usage": "<ply-divider></ply-divider>",
    "keywords": [
      "divider"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "45e38df29dd45c610f887e620d5cb6ff8c001bf43e6b7ba670073a2ea3089a48"
  },
  {
    "name": "drawer",
    "tier": "free",
    "category": "component",
    "description": "A side-drawer/offcanvas component that slides in from the edge of the screen.",
    "usage": "<ply-drawer position=\"right\" size=\"lg\" (closed)=\"onDrawerClose()\"></ply-drawer>",
    "keywords": [
      "drawer",
      "sidebar",
      "sheet"
    ],
    "dependencies": [
      "@angular/cdk",
      "rxjs"
    ],
    "registryDependencies": [
      "animations",
      "button",
      "icon",
      "types"
    ],
    "type": "components:ui",
    "digest": "269cf62cc55c947330de84a6065c7acb13affa1b87328685da30c490312af9d5"
  },
  {
    "name": "dropdown",
    "tier": "free",
    "category": "component",
    "description": "A directive that attaches a `ply-dropdown-menu` to a trigger element (like a button).",
    "usage": "<button [ply-dropdown-menu-trigger]=\"myMenu\" placement=\"end\">Open</button>",
    "keywords": [
      "dropdown",
      "dropdown-menu-trigger"
    ],
    "dependencies": [
      "@angular/cdk",
      "rxjs"
    ],
    "registryDependencies": [
      "dropdown-menu",
      "dropdown-menu-stack",
      "types"
    ],
    "type": "components:ui",
    "digest": "f8f55a3218e2222edb4c917690bf6c265135690cb92652e004f2377c08792374"
  },
  {
    "name": "dropdown-menu",
    "tier": "free",
    "category": "component",
    "description": "The container component for a dropdown menu.",
    "usage": "<ply-dropdown-menu #myMenu size=\"200px\">",
    "keywords": [
      "dropdown-menu",
      "dropdown",
      "menu"
    ],
    "dependencies": [],
    "registryDependencies": [
      "a11y-keyboard",
      "dropdown-menu-stack",
      "icon",
      "safe-timer",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "2a9a951e1bf92b6ce99d790350adad9089ebdba7d9c7109721a6c5419070ba6a"
  },
  {
    "name": "dropdown-menu-stack",
    "tier": "free",
    "category": "component",
    "description": "Root-level stack of open `ply-dropdown-menu` overlays for cascade support.",
    "usage": "inject(DropdownMenuStack).closeAll();",
    "keywords": [
      "dropdown-menu-stack",
      "dropdown",
      "menu",
      "stack",
      "service"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "53362d4ae519bdbb89d31e3647f9bdfc7584242609707ef83ecc9b71c5b60635"
  },
  {
    "name": "dual-range-slider",
    "tier": "free",
    "category": "component",
    "description": "Dual-thumb range slider for selecting a numeric span (`{ start, end }`) within `min`–`max`.",
    "usage": "<ply-dual-range-slider [(ngModel)]=\"priceRange\" [min]=\"10\" [max]=\"100\"></ply-dual-range-slider>",
    "keywords": [
      "dual-range-slider",
      "dual",
      "range",
      "slider",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "45896e20b1a7044da9076e439a8d90d71169b11094e1449025fc6bd72fc0cef9"
  },
  {
    "name": "ecommerce-block-dual-promo",
    "tier": "pro",
    "category": "block",
    "description": "Static two-column promo row (stacking to one column below `lg`): a product spotlight card with a \"Just In\" `ply-badge`, product title, price, image, and a primary \"Shop Now\" button, alongside a full-bleed image sale banner with a dark overlay, headline, and a white \"Shop Sale\" bu…",
    "usage": "<ply-ecommerce-block-dual-promo></ply-ecommerce-block-dual-promo>",
    "keywords": [
      "ecommerce-block-dual-promo",
      "block",
      "ecommerce",
      "dual",
      "promo"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button"
    ],
    "type": "components:ui",
    "digest": "e307a7835b21ac958e0a010cdfb06172a86776e39ea00d9771b389216b78f855"
  },
  {
    "name": "ecommerce-block-hero-banner",
    "tier": "pro",
    "category": "block",
    "description": "Full-width ecommerce hero banner block with a fixed-height (600px) rounded background image, a dark overlay, and centered content: a heading, a subtitle, and a pill-shaped \"Explore Now\" CTA rendered with `[ply-button]` (`color=\"primary\"`).",
    "usage": "<ply-ecommerce-block-hero-banner></ply-ecommerce-block-hero-banner>",
    "keywords": [
      "ecommerce-block-hero-banner",
      "block",
      "ecommerce",
      "hero",
      "banner"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button"
    ],
    "type": "components:ui",
    "digest": "ab343891d8902d8d2f0f5f9743eff59626d85c4d9ed9c9c594732cbb9655e756"
  },
  {
    "name": "ecommerce-block-lifestyle-grid",
    "tier": "pro",
    "category": "block",
    "description": "Static, presentational ecommerce lifestyle grid block with hardcoded demo content: a large hero image tile (\"Denim Collection\") with a gradient overlay and a \"Shop Collection\" button (via `BaseButtonDirective`), a featured product card (portable speaker with name and price), and….",
    "usage": "<ply-ecommerce-block-lifestyle-grid></ply-ecommerce-block-lifestyle-grid>",
    "keywords": [
      "ecommerce-block-lifestyle-grid",
      "block",
      "ecommerce",
      "lifestyle",
      "grid"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button"
    ],
    "type": "components:ui",
    "digest": "33ae299ab8c61a8661a0eeef236fdddfc07050b9f9009ba5e8175755601c2b8a"
  },
  {
    "name": "ecommerce-block-product-card",
    "tier": "pro",
    "category": "block",
    "description": "Merchandising card for a single product — badge, wishlist, rating, swatches, and quick-view hover.",
    "usage": "<ply-ecommerce-block-product-card [product]=\"product\" [wishlisted]=\"wishlist.has(product.id)\" (wishlistToggle)=\"onWishlistToggle()\" />",
    "keywords": [
      "ecommerce-block-product-card",
      "block",
      "ecommerce",
      "product",
      "card"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "icon",
      "star-rating",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "fabd6f114dfc712adf09da3c3f815e32d743694ffa5d45bdf60253955095866c"
  },
  {
    "name": "ecommerce-block-product-detail",
    "tier": "pro",
    "category": "block",
    "description": "Pre-built (pro tier) horizontal product detail block: a two-column card with product info on the left and a full-bleed product image on the right.",
    "usage": "<ply-ecommerce-block-product-detail></ply-ecommerce-block-product-detail>",
    "keywords": [
      "ecommerce-block-product-detail",
      "block",
      "ecommerce",
      "product",
      "detail"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "input-spinner",
      "radio-group",
      "star-rating"
    ],
    "type": "components:ui",
    "digest": "0e0530202e5bb7f93b61c0763c0af4772990ca0384f5d697ceda9dadc72a17b4"
  },
  {
    "name": "ecommerce-block-product-tabs",
    "tier": "pro",
    "category": "block",
    "description": "Static pro-tier ecommerce block rendering a split product detail layout: a large product image panel on the left and, on the right, the product name, price with an \"In Stock\" tonal success badge, and an underline-type `ply-tabs` group with three tabs — Overview (description plus….",
    "usage": "<ply-ecommerce-block-product-tabs></ply-ecommerce-block-product-tabs>",
    "keywords": [
      "ecommerce-block-product-tabs",
      "block",
      "ecommerce",
      "product",
      "tabs"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "icon",
      "star-rating",
      "tabs"
    ],
    "type": "components:ui",
    "digest": "36ef6ca8a551425e48fa4634e7f39f9a17bf4df4e22c0ed685132018f26c7489"
  },
  {
    "name": "ecommerce-block-split-banner",
    "tier": "pro",
    "category": "block",
    "description": "Split ecommerce banner block with marketing copy on one side and a product image on the other, arranged in a responsive two-column grid (stacked on small screens) inside a rounded container.",
    "usage": "<ply-ecommerce-block-split-banner></ply-ecommerce-block-split-banner>",
    "keywords": [
      "ecommerce-block-split-banner",
      "block",
      "ecommerce",
      "split",
      "banner"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button"
    ],
    "type": "components:ui",
    "digest": "3526765e8e29478145cfd8d0fce2e8fc230d155876b025a41a6dc9e0e166e88f"
  },
  {
    "name": "empty-state",
    "tier": "free",
    "category": "component",
    "description": "A standard layout component to display when a list or view has no data.",
    "usage": "<ply-empty-state iconName=\"inbox\" title=\"No Messages\" description=\"You have read all your messages.\">",
    "keywords": [
      "empty-state",
      "empty",
      "state"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon"
    ],
    "type": "components:ui",
    "digest": "c19ee12b1651d1371ef38036637dcbc3c8ad9de5215ed9c503f902cfd5c2bfa5"
  },
  {
    "name": "file-upload",
    "tier": "pro",
    "category": "component",
    "description": "A highly versatile file upload component supporting buttons, standard inputs, and drag-and-drop zones.",
    "usage": "<ply-file-upload variant=\"dropzone\" multiple=\"true\" [(ngModel)]=\"files\"></ply-file-upload>",
    "keywords": [
      "file-upload",
      "file",
      "upload",
      "dropzone",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "popover",
      "types"
    ],
    "type": "components:ui",
    "digest": "3619634c8cc820aca5d3f260e8b70f425e2cc7600f23bc03645db0db466881ca"
  },
  {
    "name": "filter",
    "tier": "free",
    "category": "component",
    "description": "A generic data transformation pipe that filters an array of objects or strings based on a search term.",
    "usage": "<li *ngFor=\"let user of users | filter:searchQuery:['name', 'email']\">",
    "keywords": [
      "filter"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "fcd1c5bd9816ca1d2215a5a6112eadcc14bf399ecab746e087f7e0eaedf0ee67"
  },
  {
    "name": "floating-input",
    "tier": "free",
    "category": "component",
    "description": "Text input with a material-style floating label: the label sits inside the field and shrinks/floats up (via Tailwind `peer` classes) when the input is focused or has a value.",
    "usage": "<ply-floating-input label=\"Email Address\" type=\"email\" [(ngModel)]=\"email\"></ply-floating-input>",
    "keywords": [
      "floating-input",
      "floating",
      "input",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "5c70a3f46748253e85a9ff595059574d27c09687788ab0b34dee1e2cace5f05b"
  },
  {
    "name": "form-billing",
    "tier": "free",
    "category": "block",
    "description": "Pre-built billing/plan form block rendered inside a `ply-card`: three selectable plan cards (Starter $9, Pro $29, Enterprise $99) with a \"Popular\" badge on Pro, a seat stepper, a promo-code input with Apply button, and a full-width \"Upgrade Plan\" button.",
    "usage": "<ply-form-billing></ply-form-billing>",
    "keywords": [
      "form-billing",
      "block",
      "form",
      "billing"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "df8e283799c4b81680c4fa6475ef679bbed842ace24c51c0048ad1e5d88a968b"
  },
  {
    "name": "form-cart",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt static shopping-cart card block composed of `ply-card`/`ply-card-body` with a \"Cart\" header showing two overlapping avatar images, two hardcoded product line items (thumbnail, name, quantity with +/- buttons, price), a totals breakdown (subtotal, promo code, tax, total),…",
    "usage": "<ply-form-cart></ply-form-cart>",
    "keywords": [
      "form-cart",
      "block",
      "form",
      "cart"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card"
    ],
    "type": "components:ui",
    "digest": "773432b907d785fd3462b2c9edc546b688e440474412b2f94244a6b34b39fb1d"
  },
  {
    "name": "form-checkout-summary",
    "tier": "free",
    "category": "block",
    "description": "Pre-built checkout confirmation/order summary block composed from `ply-card`, `ply-card-body`, `ply-icon`, `ply-checkbox`, and `[ply-button]`.",
    "usage": "<ply-form-checkout-summary></ply-form-checkout-summary>",
    "keywords": [
      "form-checkout-summary",
      "block",
      "form",
      "checkout",
      "summary"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "checkbox",
      "icon"
    ],
    "type": "components:ui",
    "digest": "7ee78650f9830162af94096baa14d178406d63015cb10efbbaface5a995b5eca"
  },
  {
    "name": "form-delete-account",
    "tier": "free",
    "category": "block",
    "description": "Pre-built \"delete account\" danger-zone form rendered inside a `ply-card`: a red warning banner with an alert-triangle icon, static consequence bullet points (deleted projects, lost team access, cancelled subscriptions) with links to export data or transfer ownership, a type-to-co…",
    "usage": "<ply-form-delete-account></ply-form-delete-account>",
    "keywords": [
      "form-delete-account",
      "block",
      "form",
      "delete",
      "account"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "e7471ace614741ece47c9869bc9b883fe895a149d0b356a43818fb5666c6b566"
  },
  {
    "name": "form-feedback",
    "tier": "free",
    "category": "block",
    "description": "Pre-composed \"Feedback\" form card built from library primitives: a `ply-card` containing a heading, side-by-side Name and Email inputs, a feedback-type `<select>` (single \"General\" option) with a chevron-down end-addon icon, a 5-row Message textarea, and a full-width primary \"Sen…",
    "usage": "<ply-form-feedback></ply-form-feedback>",
    "keywords": [
      "form-feedback",
      "block",
      "form",
      "feedback"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "bb23a5f3291b7f93c14171e97caf7ac18811603a48e636d0d9e7095cb56141fa"
  },
  {
    "name": "form-filter",
    "tier": "free",
    "category": "block",
    "description": "Self-contained filter/search panel rendered inside a `ply-card`: a search input with a start-addon icon, toggleable status chips, a from/to date range, a sort-by `<select>` with a chevron end-addon, toggleable tag chips, and Apply Filters / Reset actions.",
    "usage": "<ply-form-filter></ply-form-filter>",
    "keywords": [
      "form-filter",
      "block",
      "form",
      "filter"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "0ab0e3df3aec1113421dd1338012b787adad4a6d5b32dd013d20f5d09c06b240"
  },
  {
    "name": "form-login",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt login form block rendered inside a `ply-card`: email and password `ply-input-group` fields, a \"Keep me logged in\" `ply-checkbox` with a \"Forgot password?\" link, a full-width primary \"Sign In\" `ply-button`, and a \"Sign up\" footer link.",
    "usage": "<ply-form-login></ply-form-login>",
    "keywords": [
      "form-login",
      "block",
      "form",
      "login"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "checkbox",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "ec4bcb15957f95dc44d456844238b2cfda520b842787880f347a56a500c64ce9"
  },
  {
    "name": "form-login-tabs",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt authentication block: a `ply-card` containing an underline-style `ply-tabs` with two tabs — \"Sign Up\" (name, lastname, phone, email, password, confirm-password inputs, a Terms and Conditions checkbox, and a primary Sign Up button) and \"Login\" (login and password inputs w…",
    "usage": "<ply-form-login-tabs></ply-form-login-tabs>",
    "keywords": [
      "form-login-tabs",
      "block",
      "form",
      "login",
      "tabs"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "checkbox",
      "icon",
      "input-group",
      "tabs"
    ],
    "type": "components:ui",
    "digest": "9ce2e92c1b4fa302d2f65794fb8be0aeeb24872bc86086871645a0ffe66c68e2"
  },
  {
    "name": "form-newsletter",
    "tier": "free",
    "category": "block",
    "description": "Pre-built newsletter signup card: a `ply-card` containing a centered email icon in a rounded tile, a \"Subscribe to Our Weekly Newsletter\" heading, a \"no spam\" tagline, a `ply-input-group` with a center-aligned email text input, and a full-width primary Subscribe button.",
    "usage": "<ply-form-newsletter></ply-form-newsletter>",
    "keywords": [
      "form-newsletter",
      "block",
      "form",
      "newsletter"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "e80cb4745974a5d456d210c55b24a3e1bcea2230d726d6351bb09f6524f79cae"
  },
  {
    "name": "form-notifications",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt notification-settings card widget.",
    "usage": "<ply-form-notifications></ply-form-notifications>",
    "keywords": [
      "form-notifications",
      "block",
      "form",
      "notifications"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group",
      "toggle"
    ],
    "type": "components:ui",
    "digest": "42b4618876e3c737de8d4f210ac74a574556256b3dcab1155ee9dc002e50af51"
  },
  {
    "name": "form-payment",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt static payment form section: a `ply-card` with a \"Payment Info\" header showing a 3-step progress indicator (two check-circle icons and a numbered dot), payment-method selector buttons (VISA active, PayPal dimmed), and inputs for cardholder name, card number, expiry date,…",
    "usage": "<ply-form-payment></ply-form-payment>",
    "keywords": [
      "form-payment",
      "block",
      "form",
      "payment"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "546493fb9bfe8896a3dcf408ca543e5726bbdaaae70075bbc3c8a1684bee60f9"
  },
  {
    "name": "form-profile-settings",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt profile-settings form block rendered inside a `ply-card`: a cover-image header with an overlaid title, avatar, and round icon-button actions (edit, delete, user, more), followed by a card body with two-column text inputs (first/last name, phone, email with a green check-…",
    "usage": "<ply-form-profile-settings></ply-form-profile-settings>",
    "keywords": [
      "form-profile-settings",
      "block",
      "form",
      "profile",
      "settings"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "24bb136461e1067cad3e3ccbc4b7722f930c456ac711bc62db907e8b307d10f2"
  },
  {
    "name": "form-review",
    "tier": "free",
    "category": "block",
    "description": "Pre-composed \"Write a Review\" form card.",
    "usage": "<ply-form-review></ply-form-review>",
    "keywords": [
      "form-review",
      "block",
      "form",
      "review"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group",
      "star-rating"
    ],
    "type": "components:ui",
    "digest": "825b83270f7e1def99bf56322b32b510cdebea74e8fb8dc0722f310b927780cc"
  },
  {
    "name": "form-shipping",
    "tier": "free",
    "category": "block",
    "description": "Prebuilt shipping-information form block rendered inside a `ply-card`.",
    "usage": "<ply-form-shipping></ply-form-shipping>",
    "keywords": [
      "form-shipping",
      "block",
      "form",
      "shipping"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "132a17a2ba40df96bbb2bc7e6ffdf2b51819f19411538e7b609b2e6dbc91cddc"
  },
  {
    "name": "form-signup",
    "tier": "free",
    "category": "block",
    "description": "Pre-built static sign-up form rendered inside a `ply-card`: side-by-side First Name / Last Name inputs, Email and Password fields (each a `ply-input-group` with `ply-label` and `ply-input`), a full-width primary `ply-button` \"Sign Up\" button, and an \"Already have an account? Log….",
    "usage": "<ply-form-signup></ply-form-signup>",
    "keywords": [
      "form-signup",
      "block",
      "form",
      "signup"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "e40694835ca7a41640569ff7ecc6c19bc39d97c3b34993c9c5a8c60fd7c46021"
  },
  {
    "name": "form-signup-tabs",
    "tier": "free",
    "category": "block",
    "description": "Pre-built signup/login form block: a `ply-card` containing underline-style `ply-tabs` with two tabs — \"Sign Up\" (name, lastname, phone, email, password and confirm-password inputs with eye-icon end addons, a Terms and Conditions checkbox, a primary Sign Up button, and Facebook/Li…",
    "usage": "<ply-form-signup-tabs></ply-form-signup-tabs>",
    "keywords": [
      "form-signup-tabs",
      "block",
      "form",
      "signup",
      "tabs"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "checkbox",
      "icon",
      "input-group",
      "tabs"
    ],
    "type": "components:ui",
    "digest": "918b15f0dceda7ee397715f76611d46578b240ae8287d666c0ee6321d2c1699a"
  },
  {
    "name": "form-success-message",
    "tier": "free",
    "category": "block",
    "description": "Pre-built order-confirmation success card (OnPush).",
    "usage": "<ply-form-success-message></ply-form-success-message>",
    "keywords": [
      "form-success-message",
      "block",
      "form",
      "success",
      "message"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "06cc7c2972dde9c34676a38fe0fc9eb3cb0fdc1b7349c86e7ea5cba21634ea85"
  },
  {
    "name": "form-team-invite",
    "tier": "free",
    "category": "block",
    "description": "Pre-composed \"Invite Team Members\" form block rendered inside a `ply-card`: an email input paired with a role `<select>` (Admin/Member/Viewer, with a chevron-down icon via `ply-addon-end`), a full-width primary \"Send Invitation\" button, and a static \"Pending Invitations\" list sho…",
    "usage": "<ply-form-team-invite></ply-form-team-invite>",
    "keywords": [
      "form-team-invite",
      "block",
      "form",
      "team",
      "invite"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "card",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "ef03d9ace3d7369a9d571b68a87da170755069782baf09e5e3007bc594d6c2a3"
  },
  {
    "name": "form-wizard",
    "tier": "free",
    "category": "block",
    "description": "Self-contained three-step account signup wizard rendered inside a `ply-card`, with a progress stepper (completed steps show a check icon, the active step is highlighted), an account-details form step, a plan-selection step (Starter/Pro cards with a \"Popular\" badge), and a confirm…",
    "usage": "<ply-form-wizard></ply-form-wizard>",
    "keywords": [
      "form-wizard",
      "block",
      "form",
      "wizard"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "card",
      "checkbox",
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "656d7a2f3376d06505b224e76ee29fa31049e90c7f274556117a29acc9bb1663"
  },
  {
    "name": "hover-card",
    "tier": "free",
    "category": "component",
    "description": "Rich preview panel that opens when the pointer (or keyboard focus) rests on the trigger.",
    "usage": "<ply-hover-card>",
    "keywords": [
      "hover-card",
      "hover",
      "card"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "overlay-position",
      "safe-timer",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "07c875c20909dfc16c8b044f7cffef057d620f4bf3d2d50f5b0012ceac9158f1"
  },
  {
    "name": "i18n",
    "tier": "free",
    "category": "component",
    "description": "Chrome strings for Ply primitives (empty states, paginator, dialog close).",
    "usage": "provideBaseUiI18n({ close: 'Fermer' })",
    "keywords": [
      "i18n",
      "locale",
      "localization",
      "translate",
      "provideBaseUiI18n"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "4bb4cffe9740c3733cbaa1b6a87ed4ba83bc1a6d62319ce08add45ab14fd0c94"
  },
  {
    "name": "icon",
    "tier": "free",
    "category": "component",
    "description": "A highly optimized SVG icon component.",
    "usage": "<ply-icon name=\"home\" size=\"32\" class=\"stroke-blue-500\"></ply-icon>",
    "keywords": [
      "icon"
    ],
    "dependencies": [],
    "registryDependencies": [
      "config",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "bc40e128477bd01812c50c75de4985ad017bf205b09d765e9a572b87ab51e8c1"
  },
  {
    "name": "input-autocomplete",
    "tier": "free",
    "category": "component",
    "description": "A wrapper component that combines an input field with a native HTML datalist for autocomplete suggestions.",
    "usage": "<ply-input-autocomplete suggestions=\"country-list\">",
    "keywords": [
      "input-autocomplete",
      "input",
      "autocomplete"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "input-group"
    ],
    "type": "components:ui",
    "digest": "507f217d61813fa93c107bd55031b645d7b5f72db48f4b727f567ef165da5215"
  },
  {
    "name": "input-group",
    "tier": "free",
    "category": "component",
    "description": "A structural container wrapping form controls.",
    "usage": "<ply-input-group>",
    "keywords": [
      "input-group",
      "input",
      "group",
      "form",
      "field"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "035281a039406ff055c6991ec6bd71b7e33a9a0d9e48f9080d567c27ee02c862"
  },
  {
    "name": "input-mask",
    "tier": "free",
    "category": "component",
    "description": "Dynamically masks a native `<input>` while typing.",
    "usage": "<input ply-input plyMask=\"(000) 000-0000\" [(ngModel)]=\"phone\" />",
    "keywords": [
      "input-mask",
      "input",
      "mask",
      "input[plyMask"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "e9188fd659f98d6422a05da83ab73209400d6773bd3e07975d310efed1c169a9"
  },
  {
    "name": "input-spinner",
    "tier": "free",
    "category": "component",
    "description": "A numeric input component with increment and decrement buttons.",
    "usage": "<ply-input-spinner [(ngModel)]=\"quantity\" [min]=\"1\" [max]=\"10\"></ply-input-spinner>",
    "keywords": [
      "input-spinner",
      "input",
      "spinner",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "00b412f3aa197ebcb41f3b73f3bfeb7c3b814ac98fd8d5a090ad205ceadda98b"
  },
  {
    "name": "kbd",
    "tier": "free",
    "category": "component",
    "description": "Inline keyboard glyph for shortcuts in copy, menus, and docs.",
    "usage": "Press <ply-kbd>⌘</ply-kbd> <ply-kbd>K</ply-kbd> to open the command palette.",
    "keywords": [
      "kbd"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "b66edff7942ee3ce07e76d97cd1133678f433b9bf0c456683ba91cf1ec353ca6"
  },
  {
    "name": "knob",
    "tier": "pro",
    "category": "component",
    "description": "Pro rotary dial for selecting a numeric value along a 270° arc.",
    "usage": "<ply-knob [(ngModel)]=\"volume\" [min]=\"0\" [max]=\"100\"></ply-knob>",
    "keywords": [
      "knob",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "a63d2b2841288b6af86c547b9b980b328767dcc3d1fcf868098f4ea16b4d2c05"
  },
  {
    "name": "layout-admin-data-table",
    "tier": "pro",
    "category": "application",
    "description": "Full-page admin CRUD layout (pro tier) rendering a self-contained \"Team Members\" management screen backed by 24 seeded demo `UserRecord` rows: a debounce-free search box, status/role select filters, sortable column headers (asc → desc → unsorted cycle), page-size-8 pagination, an…",
    "usage": "<ply-layout-admin-data-table></ply-layout-admin-data-table>",
    "keywords": [
      "layout-admin-data-table",
      "application",
      "layout",
      "admin",
      "data",
      "table"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "checkbox",
      "dialog",
      "drawer",
      "empty-state",
      "icon",
      "input-group",
      "safe-timer",
      "select",
      "skeleton",
      "toast",
      "types"
    ],
    "type": "components:ui",
    "digest": "685e75cf1c4d42a4d7e36a0ae19c64106ef82a30d95b33af1dab3170cb355035"
  },
  {
    "name": "layout-bento-grid",
    "tier": "pro",
    "category": "page-layout",
    "description": "Self-contained full-page marketing/dashboard layout (pro tier) for a fictional \"Arc\" platform: sticky navbar, hero section, an interactive bento grid, a CTA band, and a footer.",
    "usage": "<ply-layout-bento-grid></ply-layout-bento-grid>",
    "keywords": [
      "layout-bento-grid",
      "page-layout",
      "layout",
      "bento",
      "grid"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "badge",
      "button",
      "icon",
      "safe-timer",
      "skeleton",
      "toast",
      "tooltip"
    ],
    "type": "components:ui",
    "digest": "ad3e4c02d43550a9b9f15f0bce99b1abaf8787be66d6d6958c9c7eff5b911dcf"
  },
  {
    "name": "layout-blog-sidebar",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page blog article layout with a sticky navbar, article body, and a sticky right sidebar (table of contents, tags, newsletter signup, related posts) — all content is hardcoded demo data.",
    "usage": "<ply-layout-blog-sidebar></ply-layout-blog-sidebar>",
    "keywords": [
      "layout-blog-sidebar",
      "page-layout",
      "layout",
      "blog",
      "sidebar"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "badge",
      "breadcrumb",
      "button",
      "card",
      "divider",
      "icon",
      "input-group",
      "toast",
      "types"
    ],
    "type": "components:ui",
    "digest": "1c43847275ab0d84ada88472a44db55ef450e8a8811dbbfd59359ed2b2557aa5"
  },
  {
    "name": "layout-dashboard",
    "tier": "pro",
    "category": "application",
    "description": "Full-page admin dashboard layout (pro tier) with a responsive dark sidebar (fixed slide-in on mobile, icon-only mini rail on lg, full labels on xl), a sticky header (breadcrumb, order search, theme toggle, notifications popover, profile dropdown menu), and six switchable views dr…",
    "usage": "<ply-layout-dashboard></ply-layout-dashboard>",
    "keywords": [
      "layout-dashboard",
      "application",
      "layout",
      "dashboard"
    ],
    "dependencies": [],
    "registryDependencies": [
      "animated-counter",
      "avatar",
      "badge",
      "base-dropdown-menu-item",
      "breadcrumb",
      "button",
      "card",
      "command-palette",
      "data-table",
      "drawer",
      "dropdown",
      "dropdown-menu",
      "empty-state",
      "icon",
      "input-group",
      "popover",
      "safe-timer",
      "skeleton",
      "stat-card",
      "tabs",
      "theme",
      "toast",
      "types"
    ],
    "type": "components:ui",
    "digest": "ce4955bc0271bcd4c016350d0a6efd69d9c37ef482864c9dca79a34688d46f88"
  },
  {
    "name": "layout-docs-kb",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page documentation / knowledge-base layout template (pro tier) with a sticky header, a left `ply-tree` navigation sidebar, a center content column of documentation sections with `ply-code` snippets, and a right \"On this page\" TOC that scrollspies the reader's position via an…",
    "usage": "<ply-layout-docs-kb></ply-layout-docs-kb>",
    "keywords": [
      "layout-docs-kb",
      "page-layout",
      "layout",
      "docs",
      "kb"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "badge",
      "breadcrumb",
      "button",
      "card",
      "code",
      "command-palette",
      "divider",
      "icon",
      "theme",
      "toast",
      "tree"
    ],
    "type": "components:ui",
    "digest": "a894131cca44c3bd24f42e828991e0bfd46e3b57054795bf569790582c92eafc"
  },
  {
    "name": "layout-ecommerce-grid",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page e-commerce storefront layout (pro tier) with a sticky navbar (cart/wishlist count badges), breadcrumb + sort/view-mode toolbar, a filter sidebar (categories, price-range checkboxes, color swatches, star ratings — rendered as a desktop column and a mobile slide-in panel)…",
    "usage": "<ply-layout-ecommerce-grid></ply-layout-ecommerce-grid>",
    "keywords": [
      "layout-ecommerce-grid",
      "page-layout",
      "layout",
      "ecommerce",
      "grid"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "breadcrumb",
      "button",
      "checkbox",
      "dialog",
      "divider",
      "drawer",
      "icon",
      "safe-timer",
      "select",
      "toast",
      "types"
    ],
    "type": "components:ui",
    "digest": "1bc0dbe0d887d08906c7b5a0ece820226f27e5b845b208c86c040fb5ed55f394"
  },
  {
    "name": "layout-file-manager",
    "tier": "pro",
    "category": "application",
    "description": "Full-page file manager application layout (pro tier): `ply-tree` folder sidebar, path breadcrumbs, grid/list views, search + starred filter, `ply-file-upload` dropzone, item actions (open/rename/star/download/delete) via dropdown menus, rename via `BaseFileManagerRenameDialogComp…",
    "usage": "<ply-layout-file-manager></ply-layout-file-manager>",
    "keywords": [
      "layout-file-manager",
      "application",
      "layout",
      "file",
      "manager"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "base-dropdown-menu-item",
      "button",
      "button-group",
      "dialog",
      "drawer",
      "dropdown",
      "dropdown-menu",
      "empty-state",
      "file-upload",
      "icon",
      "input-group",
      "safe-timer",
      "select",
      "skeleton",
      "toast",
      "tooltip",
      "tree"
    ],
    "type": "components:ui",
    "digest": "b095c2d39b91cf3872c25055c550c13f543bc3f9bde7ce81d4914e170c7d45f6"
  },
  {
    "name": "layout-hero-features",
    "tier": "pro",
    "category": "page-layout",
    "description": "A complete marketing landing page layout: sticky header with anchor navigation and scroll shadow, hero with tilt-on-scroll product mockup, animated stats strip, logo cloud, features grid with scroll reveal, testimonials carousel, pricing with monthly/yearly toggle, install snippe…",
    "usage": "<ply-layout-hero-features brandName=\"Acme\" [stats]=\"stats\" [plans]=\"plans\" (primaryCtaClick)=\"signup()\" (secondaryCtaClick)=\"openDemo()\" (newsletterSubmit)=\"subscribe($event)\">",
    "keywords": [
      "layout-hero-features",
      "page-layout",
      "layout",
      "hero",
      "features"
    ],
    "dependencies": [],
    "registryDependencies": [
      "accordion",
      "animated-counter",
      "badge",
      "button",
      "carousel",
      "code",
      "dialog",
      "drawer",
      "icon",
      "input-group",
      "quote",
      "reveal",
      "safe-timer",
      "star-rating",
      "tabs",
      "theme",
      "timeline",
      "toggle",
      "types"
    ],
    "type": "components:ui",
    "digest": "95eee98a2ee0ee24ae8478311657ab8dcd536942c59893d17d55feaa5d2165f0"
  },
  {
    "name": "layout-inbox-messaging",
    "tier": "pro",
    "category": "application",
    "description": "A three-pane inbox / support-ticket messaging layout: a searchable, status-filterable conversation list (All / Unread / Open / Closed), a message thread with an @-mention reply composer (auto-growing textarea, Enter sends, Shift+Enter for a newline, Enter is ignored while the men…",
    "usage": "<ply-layout-inbox-messaging></ply-layout-inbox-messaging>",
    "keywords": [
      "layout-inbox-messaging",
      "application",
      "layout",
      "inbox",
      "messaging"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "avatar-group",
      "badge",
      "button",
      "chips",
      "dropdown",
      "dropdown-menu",
      "empty-state",
      "file-upload",
      "icon",
      "input-group",
      "mention-input",
      "safe-timer",
      "tooltip",
      "types"
    ],
    "type": "components:ui",
    "digest": "4d7d245316edd1537edf0b86ec13c1a0b3c3071c184d272df87c60af3d71f781"
  },
  {
    "name": "layout-inbox-workspace",
    "tier": "pro",
    "category": "application",
    "description": "Linear-style workspace inbox (pro application layout), distinct from `layout-inbox-messaging`.",
    "usage": "<ply-layout-inbox-workspace />",
    "keywords": [
      "layout-inbox-workspace",
      "application",
      "layout",
      "inbox",
      "workspace"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "avatar-group",
      "badge",
      "button",
      "chips",
      "dropdown",
      "dropdown-menu",
      "empty-state",
      "file-upload",
      "icon",
      "input-group",
      "mention-input",
      "safe-timer",
      "select",
      "toast",
      "types"
    ],
    "type": "components:ui",
    "digest": "620d341c726c87a270a9252b74b7ac58371a136368b4675d1499985e95797362"
  },
  {
    "name": "layout-kanban-board",
    "tier": "pro",
    "category": "application",
    "description": "Full-page kanban board (pro application layout) — bind `columns` from a store or use the seed.",
    "usage": "<ply-layout-kanban-board />",
    "keywords": [
      "layout-kanban-board",
      "application",
      "layout",
      "kanban",
      "board",
      "drag",
      "columns",
      "tasks",
      "store",
      "embedded"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "button",
      "click-outside",
      "dialog",
      "icon",
      "input-group",
      "safe-timer",
      "select",
      "skeleton",
      "toast"
    ],
    "type": "components:ui",
    "digest": "36df0cf70fa8ee9c72390008937d9b7f32ae1cf5bd37f8aa948b2344ef826752"
  },
  {
    "name": "layout-magazine-grid",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page magazine/blog landing layout (\"Meridian\") with a sticky blurred navbar, mobile slide-in category menu, featured hero article (with expandable \"reader mode\" excerpt), secondary article stack, numbered Editor's Picks strip, a Latest Stories grid with 2-column/3-column/lis…",
    "usage": "<ply-layout-magazine-grid></ply-layout-magazine-grid>",
    "keywords": [
      "layout-magazine-grid",
      "page-layout",
      "layout",
      "magazine",
      "grid"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "badge",
      "button",
      "card",
      "icon",
      "input-group",
      "safe-timer",
      "toast",
      "types"
    ],
    "type": "components:ui",
    "digest": "cbd7ed60cb3432b5c0749ccd3fa5503e62f751584ff184469e74531168574699"
  },
  {
    "name": "layout-onboarding-flow",
    "tier": "pro",
    "category": "application",
    "description": "Full-page four-step signup/onboarding layout (Account, Verify, Workspace, Invite) built on `BaseStepper`/`BaseStep` with hidden built-in navigation and its own Back/Next/Submit controls.",
    "usage": "<ply-onboarding-flow-layout></ply-onboarding-flow-layout>",
    "keywords": [
      "layout-onboarding-flow",
      "application",
      "layout",
      "onboarding",
      "flow",
      "onboarding-flow-layout"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "chips",
      "icon",
      "input-group",
      "otp-input",
      "password-strength",
      "safe-timer",
      "select",
      "spinner",
      "stepper",
      "toast"
    ],
    "type": "components:ui",
    "digest": "57c3fd6c17b0688fd95210341ef6d9d3b37c72d73ddc5c10bbdd9e14e12f4043"
  },
  {
    "name": "layout-portfolio-gallery",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page portfolio/agency layout (\"Aria Studio\") with sticky navbar, mobile slide-in menu, hero with featured project card, stats strip, services grid, filterable masonry project gallery, testimonials, process steps, gradient CTA, and footer.",
    "usage": "<ply-layout-portfolio-gallery></ply-layout-portfolio-gallery>",
    "keywords": [
      "layout-portfolio-gallery",
      "page-layout",
      "layout",
      "portfolio",
      "gallery"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "dialog",
      "icon",
      "input-group",
      "select",
      "toast"
    ],
    "type": "components:ui",
    "digest": "7a977467837d322135428679f82f251b5198c4c2b2f417d89e0fa7647c93feae"
  },
  {
    "name": "layout-pricing",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page pricing layout (pro tier): sticky navbar, hero with a monthly/annual billing toggle and a team-size `ply-input-spinner` (1–500 seats), three hardcoded plan cards (Starter/Professional/Enterprise), a trusted-by logo strip, a feature comparison table, an FAQ accordion, a….",
    "usage": "<ply-layout-pricing-page></ply-layout-pricing-page>",
    "keywords": [
      "layout-pricing",
      "page-layout",
      "layout",
      "pricing",
      "layout-pricing-page"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "dialog",
      "icon",
      "input-group",
      "input-spinner",
      "safe-timer",
      "skeleton",
      "toast"
    ],
    "type": "components:ui",
    "digest": "ea4a8aa35a6e9798120856609616f8b70fce989d8372f47abadbaa8e9f48dda7"
  },
  {
    "name": "layout-scheduler",
    "tier": "pro",
    "category": "application",
    "description": "Full-page scheduler / full-calendar application layout (pro tier): month, week, and day views with seeded demo events, Work/Personal/Team calendar filters, search, a mini `ply-calendar` sidebar, create/edit/delete via `BaseSchedulerEventFormDialogComponent` + `DialogService`, toa…",
    "usage": "<ply-layout-scheduler></ply-layout-scheduler>",
    "keywords": [
      "layout-scheduler",
      "application",
      "layout",
      "scheduler"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "button",
      "calendar",
      "dialog",
      "icon",
      "input-group",
      "safe-timer",
      "select",
      "skeleton",
      "toast",
      "tooltip"
    ],
    "type": "components:ui",
    "digest": "8008ed030325c1b0b81a7b1a85cfc4276b55ec18aca767ff58732058d44a9d59"
  },
  {
    "name": "layout-settings-account",
    "tier": "pro",
    "category": "application",
    "description": "Full-page account settings layout with a desktop sidebar (avatar/user header, \"Back to Dashboard\" routerLink to `/layouts/dashboard`) and a sticky mobile tab bar, switching between five tabs — Profile, Billing, Notifications, and Team delegate to `ply-form-profile-settings`, `ply…",
    "usage": "<ply-layout-settings-account></ply-layout-settings-account>",
    "keywords": [
      "layout-settings-account",
      "application",
      "layout",
      "settings",
      "account"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "form-billing",
      "form-delete-account",
      "form-notifications",
      "form-profile-settings",
      "form-team-invite",
      "icon",
      "input-group",
      "password-strength",
      "safe-timer",
      "skeleton",
      "toast",
      "toggle"
    ],
    "type": "components:ui",
    "digest": "6f7e5d4e0578e43a471c046d76c3dc2c8d29497b0580d7e2ae796d7b66c8ea62"
  },
  {
    "name": "layout-split-screen",
    "tier": "pro",
    "category": "page-layout",
    "description": "Full-page SaaS marketing landing layout (fictional \"Pulse\" product) built from alternating 50/50 split sections: sticky navbar, hero split with a simulated dashboard card (Deployments/Analytics/Logs tabs driven by a signal), \"trusted by\" logo strip, terminal-simulation feature sp…",
    "usage": "<ply-layout-split-screen></ply-layout-split-screen>",
    "keywords": [
      "layout-split-screen",
      "page-layout",
      "layout",
      "split",
      "screen"
    ],
    "dependencies": [],
    "registryDependencies": [
      "badge",
      "button",
      "dialog",
      "icon",
      "input-group",
      "safe-timer",
      "skeleton",
      "toast"
    ],
    "type": "components:ui",
    "digest": "10c73bf923324108839bea92805f9a4641f93217cbb6d09ab50a2735844b2dc9"
  },
  {
    "name": "lightbox",
    "tier": "free",
    "category": "component",
    "description": "Free lightbox gallery. Project one or more `[ply-lightbox-thumb]` images; thumb size and aspect ratio are controlled with Tailwind on each thumb (`class` on `ply-lightbox` lays out the thumbs wrapper — host itself is `contents`).",
    "usage": "<ply-lightbox class=\"grid grid-cols-3 gap-2\">",
    "keywords": [
      "lightbox"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "e6e9a7c06139a229dad5f7b9ebed7f27bdee18010f5ece29887cde837e110fa3"
  },
  {
    "name": "loading-overlay",
    "tier": "free",
    "category": "component",
    "description": "Blocks a region (or the viewport) with `ply-spinner` while work is in progress.",
    "usage": "<ply-loading-overlay [visible]=\"saving()\" message=\"Saving…\">",
    "keywords": [
      "loading-overlay",
      "loading",
      "overlay"
    ],
    "dependencies": [],
    "registryDependencies": [
      "spinner",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "b49446ea3b6a0aa59813c091df2f3fced3aded5dfcc0381c12cce213a61196d9"
  },
  {
    "name": "media-widget-album-carousel",
    "tier": "pro",
    "category": "widget",
    "description": "Pre-built media widget (pro tier) rendering a `ply-card` containing a `ply-horizontal-carousel` titled \"Albums\" with eight hard-coded album items.",
    "usage": "<ply-media-widget-album-carousel></ply-media-widget-album-carousel>",
    "keywords": [
      "media-widget-album-carousel",
      "widget",
      "media",
      "album",
      "carousel"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "carousel",
      "icon",
      "star-rating",
      "tooltip"
    ],
    "type": "components:ui",
    "digest": "0c6b0dfe946b90457ab8eaa8cf32cd71890bd2c61da54cf1283406a63337668a"
  },
  {
    "name": "media-widget-album-player",
    "tier": "pro",
    "category": "widget",
    "description": "Static album-player media widget rendered inside a `ply-card`: a cover-image panel with share/bookmark/download icon buttons and an album info overlay (artist, title, stats), beside a scrollable track list where the active track shows animated equalizer bars, plus a footer bar wi…",
    "usage": "<ply-media-widget-album-player></ply-media-widget-album-player>",
    "keywords": [
      "media-widget-album-player",
      "widget",
      "media",
      "album",
      "player"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "1a4dabf56fe86e83e04399a52153f949dee20647a4fee7ffae02c95486c8ea3f"
  },
  {
    "name": "media-widget-audio-player-compact",
    "tier": "pro",
    "category": "widget",
    "description": "Compact audio-player media widget rendered inside a `ply-card`: a round stroked pause icon-button, hard-coded track title/artist (\"Hold On, We're Going Home\" / \"Drake\"), a \"more\" icon-button, a decorative static waveform made of bars, elapsed/total time labels, like and play-coun…",
    "usage": "<ply-media-widget-audio-player-compact></ply-media-widget-audio-player-compact>",
    "keywords": [
      "media-widget-audio-player-compact",
      "widget",
      "media",
      "audio",
      "player",
      "compact"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "7cf77e1675cb4fce240e670e51ccd92dcb2b6b8567e7911e88bab21b543d95a1"
  },
  {
    "name": "media-widget-audio-player-dark",
    "tier": "pro",
    "category": "widget",
    "description": "Static dark-themed audio player widget rendered inside a `ply-card` with a forced `bg-slate-900!` background (always dark regardless of theme).",
    "usage": "<ply-media-widget-audio-player-dark></ply-media-widget-audio-player-dark>",
    "keywords": [
      "media-widget-audio-player-dark",
      "widget",
      "media",
      "audio",
      "player",
      "dark"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "9b350b7647b0b0ae5b928c31492b86215075c86be78bff335da426f6888b146c"
  },
  {
    "name": "media-widget-audio-player-hero",
    "tier": "pro",
    "category": "widget",
    "description": "Full-height hero audio player card (pro tier) built on `ply-card`.",
    "usage": "<ply-media-widget-audio-player-hero></ply-media-widget-audio-player-hero>",
    "keywords": [
      "media-widget-audio-player-hero",
      "widget",
      "media",
      "audio",
      "player",
      "hero"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "922e3c4f8391a3475c9a086ef51a8986e5ba3a5d5932bf4a281857576bd2184f"
  },
  {
    "name": "media-widget-playlist",
    "tier": "pro",
    "category": "widget",
    "description": "Static (display-only) music playlist widget rendered inside a `ply-card`: a \"Playlist\" header with a more-options icon button, a transport bar with backward/pause/forward icon buttons and a decorative hover-reveal volume slider (shown only at `sm`–`lg` and `xl+` breakpoints), and…",
    "usage": "<ply-media-widget-playlist></ply-media-widget-playlist>",
    "keywords": [
      "media-widget-playlist",
      "widget",
      "media",
      "playlist"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "3a909d56c4acb7929cd60321dc8bf395a96d60156ba17eeac75ba893a3100601"
  },
  {
    "name": "media-widget-related-videos",
    "tier": "pro",
    "category": "widget",
    "description": "Static \"Related Videos\" showcase widget rendered inside a `ply-card`: a header row with a \"Related Videos\" title and a transparent `ply-icon-button` (\"More\"), above a vertically scrollable list of seven hardcoded video entries.",
    "usage": "<ply-media-widget-related-videos></ply-media-widget-related-videos>",
    "keywords": [
      "media-widget-related-videos",
      "widget",
      "media",
      "related",
      "videos"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "f75d01947ea071f89c07538d302f298bd0510c2cf724d6e3f9bef1330bba2ed4"
  },
  {
    "name": "media-widget-top-singles",
    "tier": "pro",
    "category": "widget",
    "description": "Music chart card (\"Top Singles\") built on `ply-card`, with a header row containing a \"More\" icon button, a Week/Month/Year tab strip (static, non-interactive — \"Week\" is styled as selected), and a hardcoded ranked list of 5 tracks showing rank number, cover image, title/artist, a…",
    "usage": "<ply-media-widget-top-singles></ply-media-widget-top-singles>",
    "keywords": [
      "media-widget-top-singles",
      "widget",
      "media",
      "top",
      "singles"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "bf0a315837c49dbece3a999de439113c1bc54fe84b29e38a9eca05a4a315d93f"
  },
  {
    "name": "media-widget-video-hero",
    "tier": "pro",
    "category": "widget",
    "description": "Pro-tier showcase widget rendering a static video-player hero inside a `ply-card` with a 16:9 (`aspect-video`) frame.",
    "usage": "<ply-media-widget-video-hero></ply-media-widget-video-hero>",
    "keywords": [
      "media-widget-video-hero",
      "widget",
      "media",
      "video",
      "hero"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon",
      "select"
    ],
    "type": "components:ui",
    "digest": "6d5c417016ba3379a86e8eb1f6fb0f97ac79258e4310131d551892456d3b27d5"
  },
  {
    "name": "media-widget-video-post",
    "tier": "pro",
    "category": "widget",
    "description": "Pre-composed social video post card (pro tier) built on `ply-card`, using `OnPush` change detection.",
    "usage": "<ply-media-widget-video-post></ply-media-widget-video-post>",
    "keywords": [
      "media-widget-video-post",
      "widget",
      "media",
      "video",
      "post"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "544f4ea2a4b9b0af0cf62db64a081ff5ccf627d69dc4ed53da1ce26d3fa6e971"
  },
  {
    "name": "mega-menu",
    "tier": "pro",
    "category": "component",
    "description": "Full-width mega menu with a trigger slot and a dropdown panel.",
    "usage": "<ply-mega-menu>",
    "keywords": [
      "mega-menu",
      "mega",
      "menu"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "z-index"
    ],
    "type": "components:ui",
    "digest": "cc5b1d1dcea0cc12cdb6a886e6b58155a4b37099336ada7d33a26e73fecfdb35"
  },
  {
    "name": "mention-input",
    "tier": "pro",
    "category": "component",
    "description": "Pro tier. Wrapper that adds @-mention autocomplete to a projected native `<input>` or `<textarea>` (via `<ng-content>`).",
    "usage": "<ply-mention-input [users]=\"users\" [(ngModel)]=\"message\">",
    "keywords": [
      "mention-input",
      "mention",
      "input",
      "autocomplete",
      "mentions",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "318d0e42edbf170401765351e46e8fdf926d898f534fb10668ce63a394b2ab73"
  },
  {
    "name": "menubar",
    "tier": "free",
    "category": "component",
    "description": "Horizontal application menubar.",
    "usage": "<ply-menubar>",
    "keywords": [
      "menubar"
    ],
    "dependencies": [],
    "registryDependencies": [
      "dropdown",
      "dropdown-menu",
      "dropdown-menu-stack",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "a54677f25363727158bc33917df2a8fc21f9b2c9c1d4b1651c426502e07004d4"
  },
  {
    "name": "meter-group",
    "tier": "free",
    "category": "component",
    "description": "Stacked multi-value meter with optional legend.",
    "usage": "<ply-meter-group [value]=\"[ { label: 'Apps', value: 16, color: 'primary' }, { label: 'Messages', value: 8, color: 'success' }, { label: 'Media', value: 24, color: 'warning' }, ]\">…",
    "keywords": [
      "meter-group",
      "meter",
      "group"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "8962b36045f52fa978deb5dc0a29fe3477d2aa2602300c148d38ba5eb0d0b9bf"
  },
  {
    "name": "multi-select",
    "tier": "pro",
    "category": "component",
    "description": "Searchable multi-select dropdown that renders selected values as removable chips inside a combobox trigger.",
    "usage": "<ply-multi-select [options]=\"skills\" [(ngModel)]=\"selectedSkills\"></ply-multi-select>",
    "keywords": [
      "multi-select",
      "multi",
      "select",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "i18n",
      "icon",
      "overlay-position",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "4093670884ecd1909720aab98cd8b9dd7ab97f35c364be82eeece89dd96b1f2e"
  },
  {
    "name": "nav-list",
    "tier": "free",
    "category": "component",
    "description": "A navigation list container.",
    "usage": "<ply-nav-list>",
    "keywords": [
      "nav-list",
      "nav",
      "list"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "8bbb5f8ce6d82de53b74caeacf25ee54933c5307a889021db9813ca0c15252ab"
  },
  {
    "name": "otp-input",
    "tier": "free",
    "category": "component",
    "description": "PIN / OTP input rendering `length` individually-focusable single-character boxes.",
    "usage": "<ply-otp-input [length]=\"6\" (completed)=\"onVerify($event)\"></ply-otp-input>",
    "keywords": [
      "otp-input",
      "otp",
      "input",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "62480b04fa2e8c2b6d1bb3fafe2f9901d70a557599ef382a729a80777c385bb0"
  },
  {
    "name": "overlay-position",
    "tier": "free",
    "category": "component",
    "description": "Placement union shared by popover/hover-card overlays.",
    "usage": "npx ply-ui-cli add overlay-position",
    "keywords": [
      "overlay-position",
      "overlay",
      "position"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "27a9e0654a84b7ad9cf5fe9cbe043d679e4118d6e7f069661cfeb9915fffaede"
  },
  {
    "name": "page-main",
    "tier": "free",
    "category": "shell",
    "description": "The primary layout wrapper for a main page view.",
    "usage": "<ply-page-main>",
    "keywords": [
      "page-main",
      "shell",
      "page",
      "main"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "4d7603e5623e41a388425fc63ff3819fb5e6442e27db1b9e2bd86d1746052805"
  },
  {
    "name": "paginator",
    "tier": "free",
    "category": "component",
    "description": "A pagination control component.",
    "usage": "<ply-paginator [plyPaginator]=\"true\" [pageSizeOptions]=\"[10, 20, 50]\"></ply-paginator>",
    "keywords": [
      "paginator"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "i18n",
      "icon",
      "input-spinner",
      "select"
    ],
    "type": "components:ui",
    "digest": "022c08d5da54d8d46d6f785b327f076441eccaa361f472137796a9683c1cc8a1"
  },
  {
    "name": "password-input",
    "tier": "free",
    "category": "component",
    "description": "Password field with a show/hide toggle.",
    "usage": "<ply-password-input label=\"Password\" formControlName=\"password\" [showStrength]=\"true\">",
    "keywords": [
      "password-input",
      "password",
      "input",
      "reveal",
      "visibility",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "i18n",
      "icon",
      "input-group",
      "password-strength",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "2d652e31fb926b909fa582a2820349575916e85c74e3d0540b9289fdc4b2cfdf"
  },
  {
    "name": "password-strength",
    "tier": "free",
    "category": "component",
    "description": "Four-segment password strength meter bar with a text label below it.",
    "usage": "<ply-password-strength></ply-password-strength>",
    "keywords": [
      "password-strength",
      "password",
      "strength"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "bd122b1b1a5a2814c8bca3ef0c1a5b1fa7113ccafcc13a81a72acf45ebfc8c45"
  },
  {
    "name": "phone-input",
    "tier": "free",
    "category": "component",
    "description": "Phone number field with a country dial-code selector.",
    "usage": "<ply-phone-input></ply-phone-input>",
    "keywords": [
      "phone-input",
      "phone",
      "input",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "9a3764ebb1b7c31d0c6ccc9254db33727cac866e7f6995d7f011f73345d71ace"
  },
  {
    "name": "pick-list",
    "tier": "pro",
    "category": "component",
    "description": "Pro dual-listbox that moves items between available (source) and selected (target) panes.",
    "usage": "<ply-pick-list [options]=\"cities\" [(ngModel)]=\"selected\"></ply-pick-list>",
    "keywords": [
      "pick-list",
      "pick",
      "list",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "54c4c3d4f77bf6477660c8335228462e12292330428ee01fd59132393d5bcb1a"
  },
  {
    "name": "popover",
    "tier": "free",
    "category": "component",
    "description": "Self-contained popover with a trigger slot and a panel slot: project the trigger element into `[popover-trigger]` and the panel content as default children.",
    "usage": "<ply-popover placement=\"bottom-start\">",
    "keywords": [
      "popover"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "overlay-position",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "9c76d833e33903c5c7bcd4adc3338b0b2d0f0cd93ff8b84bd034252baf0a8c7d"
  },
  {
    "name": "product-gallery",
    "tier": "pro",
    "category": "component",
    "description": "Pro tier. A highly interactive product gallery component supporting images, videos, thumbnails, and zooming.",
    "usage": "<ply-product-gallery [items]=\"mediaItems\" thumbnailsPosition=\"left\" [zoomOnClick]=\"true\" (indexChange)=\"onSlideChanged($event)\">",
    "keywords": [
      "product-gallery",
      "product",
      "gallery"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "safe-timer",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "da7d4832a8629ea6289f82a37eb12e0efb697684e89bb815fdb2f631f7e1692f"
  },
  {
    "name": "progress",
    "tier": "free",
    "category": "component",
    "description": "A linear progress bar. On hover (or keyboard focus), a tip bubble appears at the leading edge of the fill showing the current percentage.",
    "usage": "<ply-progress [value]=\"75\" color=\"success\" size=\"lg\"></ply-progress>",
    "keywords": [
      "progress"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "c18915f0d9be0d8a2c921a98067b3e641e0bf47531fe6477544df003a31d5281"
  },
  {
    "name": "progress-button",
    "tier": "free",
    "category": "component",
    "description": "A button with built-in progress state: while `loading` is true the label fades out (keeping the button's width stable) and a centered spinner is shown instead.",
    "usage": "<ply-progress-button color=\"primary\" [loading]=\"saving()\" (clicked)=\"save()\">",
    "keywords": [
      "progress-button",
      "progress",
      "button"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "62551fbb355280bb648f4adf394fc484d22c0281f80da3987c667d19261e7cc9"
  },
  {
    "name": "quote",
    "tier": "free",
    "category": "component",
    "description": "A stylized blockquote component for displaying testimonials, reviews, or pull quotes.",
    "usage": "<ply-quote variant=\"avatar-left\" authorName=\"John Doe\" authorRole=\"CEO\" avatarUrl=\"user.jpg\">",
    "keywords": [
      "quote"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "d28b278404982e37f4206397a151a0832d4370f65ac1d784efaef4255c92aed5"
  },
  {
    "name": "radio-group",
    "tier": "free",
    "category": "component",
    "description": "A container component for a group of `ply-radio-button` elements.",
    "usage": "<ply-radio-group groupLabel=\"Notification preference\" [(ngModel)]=\"selectedValue\">",
    "keywords": [
      "radio-group",
      "radio",
      "group",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "3defa877b9311e9c662e5d8046ccdf927721c72228159f803475bd3ed9e7bff2"
  },
  {
    "name": "range-slider",
    "tier": "free",
    "category": "component",
    "description": "Single-value range slider built on a native `<input type=\"range\">`, styled with Tailwind accent-color classes per `color`.",
    "usage": "<ply-range-slider></ply-range-slider>",
    "keywords": [
      "range-slider",
      "range",
      "slider",
      "input-slider",
      "volume",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "types"
    ],
    "type": "components:ui",
    "digest": "5acfe4e79a200ce94c6bc7db2dca29c6bad02f68fb114c1c215472d465ccbb4d"
  },
  {
    "name": "responsive-nav",
    "tier": "free",
    "category": "component",
    "description": "Progressive (priority+) horizontal navigation.",
    "usage": "<ply-responsive-nav>",
    "keywords": [
      "responsive-nav",
      "responsive",
      "nav"
    ],
    "dependencies": [],
    "registryDependencies": [
      "base-dropdown-menu-item",
      "button",
      "dropdown",
      "dropdown-menu",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "472a0b5c215dd2ef7abeff6ad2a33ddb3f12cc558baeea5212c4db209c64a96d"
  },
  {
    "name": "reveal",
    "tier": "free",
    "category": "component",
    "description": "Reveals the host element with a fade + slide-up animation the first time it scrolls into the viewport (IntersectionObserver).",
    "usage": "<div plyReveal>Fades in on scroll</div>",
    "keywords": [
      "reveal",
      "plyReveal"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "1b06edc83015d03ad880fdf380bec1da9cc2a49e643d0b89bb80a1f93e8e6d4c"
  },
  {
    "name": "rich-text-editor",
    "tier": "pro",
    "category": "component",
    "description": "Lightweight WYSIWYG editor with a themed toolbar (`ply-stroked-icon-button`, tooltips, dropdown, divider) and a `contenteditable` body.",
    "usage": "<ply-rich-text-editor [(ngModel)]=\"bioHtml\" placeholder=\"Write something...\"></ply-rich-text-editor>",
    "keywords": [
      "rich-text-editor",
      "rich",
      "text",
      "editor",
      "wysiwyg",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "base-dropdown-menu-item",
      "button",
      "divider",
      "dropdown",
      "dropdown-menu",
      "icon",
      "tooltip",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "09a9e4894e039a31aee4c7786494740098e60709453e1d89eca897e79447c10e"
  },
  {
    "name": "ripple",
    "tier": "free",
    "category": "component",
    "description": "Material-style ink ripple on pointer press (primary button) or Enter/Space.",
    "usage": "<button ply-button color=\"primary\" ply-ripple>Click me</button>",
    "keywords": [
      "ripple"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "1da6e63ba041697f085360bbaf6238d1a9a53e4a98d9fc33495f04c1f1fe42d2"
  },
  {
    "name": "safe-timer",
    "tier": "free",
    "category": "component",
    "description": "Timers scoped to the lifetime of the component or directive that created them.",
    "usage": "private readonly timers = injectTimers();",
    "keywords": [
      "safe-timer",
      "safe",
      "timer"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "45def2faa6246a432f2ceb513e08ed518ef5cc120a97c933a0e062fd7de507bb"
  },
  {
    "name": "scroll-area",
    "tier": "free",
    "category": "component",
    "description": "Overflow container with a thin, theme-aware scrollbar.",
    "usage": "<ply-scroll-area class=\"h-64\">",
    "keywords": [
      "scroll-area",
      "scroll",
      "area"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "b7da6de5171cc2315a860cdff7574c43a2809eed94efad35de88490d43b42ea4"
  },
  {
    "name": "scroll-buttons",
    "tier": "free",
    "category": "component",
    "description": "Floating scroll-to-bottom button.",
    "usage": "<ply-scroll-bottom threshold=\"200\" color=\"primary\"></ply-scroll-bottom>",
    "keywords": [
      "scroll-buttons",
      "scroll",
      "buttons",
      "scroll-bottom"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "scroll-container",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "ee1c41f9137c4c5733fb63db2bb9c65a2dc0b7b74cffac8e73e5261f06688464"
  },
  {
    "name": "scroll-container",
    "tier": "free",
    "category": "component",
    "description": "Scroll container resolution for scroll-top / scroll-bottom buttons.",
    "usage": "npx ply-ui-cli add scroll-container",
    "keywords": [
      "scroll-container",
      "scroll",
      "container"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "5313ebcbc0638a91a8a1277c423a750a69925b38a41f8de45939415c6d2e8698"
  },
  {
    "name": "scroll-nav",
    "tier": "free",
    "category": "shell",
    "description": "A highly interactive layout component that synchronizes a sidebar navigation list with scrollable content.",
    "usage": "<ply-scroll-nav>",
    "keywords": [
      "scroll-nav",
      "shell",
      "scroll",
      "nav"
    ],
    "dependencies": [
      "rxjs"
    ],
    "registryDependencies": [
      "safe-timer",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "1d086841e74b6408a18f508e84fa5c02202aedebc0b612f55f05610e21b3f7ea"
  },
  {
    "name": "scroll-to",
    "tier": "free",
    "category": "component",
    "description": "A behavior directive that smoothly scrolls the window to a target element when the host is clicked.",
    "usage": "<button [plyScrollTo]=\"'#footer'\">Scroll to Footer</button>",
    "keywords": [
      "scroll-to",
      "scroll",
      "to",
      "plyScrollTo"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "2273823b412574f7d5b9c50a42db1da0cb155ff45cd84ca7149772d73f82debc"
  },
  {
    "name": "select",
    "tier": "free",
    "category": "component",
    "description": "A native HTML `<select>` wrapper component.",
    "usage": "<ply-select [(ngModel)]=\"selectedValue\" placeholder=\"Select an option\">",
    "keywords": [
      "select",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "b975aba0b401f8b3153647e182f6cb32e03b495191c791c4181e4beaec7dd437"
  },
  {
    "name": "select-tree",
    "tier": "pro",
    "category": "component",
    "description": "Pro single-select dropdown that presents options as an expandable tree (combobox trigger + fixed panel).",
    "usage": "<ply-select-tree [nodes]=\"locations\" [(ngModel)]=\"selected\"></ply-select-tree>",
    "keywords": [
      "select-tree",
      "select",
      "tree",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "i18n",
      "icon",
      "overlay-position",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "1371479bec20b6c5a6c959b60faa7c86fd8f926335b2fbb52fb951784606ea8e"
  },
  {
    "name": "shell",
    "tier": "pro",
    "category": "shell",
    "description": "Unified Pro application shell.",
    "usage": "<ply-shell mode=\"page\">",
    "keywords": [
      "shell"
    ],
    "dependencies": [
      "@angular/cdk",
      "rxjs"
    ],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "ad3b0116a540b67f6988eae0cca3d27dfb0bb621e835e0ecf68c7e069d05e389"
  },
  {
    "name": "sidebar",
    "tier": "free",
    "category": "component",
    "description": "A service to control the visibility state of the application sidebar.",
    "usage": "sidebar = inject(SidebarService);",
    "keywords": [
      "sidebar",
      "service"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "09af937be658d2920ad237c1adcdbecf7dfdebeee490e13cb22ab4bb15844ee1"
  },
  {
    "name": "sidenav",
    "tier": "free",
    "category": "shell",
    "description": "Responsive section shell with a left nav rail and scrollable body.",
    "usage": "<ply-sidenav>",
    "keywords": [
      "sidenav",
      "shell",
      "sidebar",
      "navigation"
    ],
    "dependencies": [
      "rxjs"
    ],
    "registryDependencies": [
      "breadcrumb",
      "button",
      "icon",
      "safe-timer",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "006e5616908a0d3131d3766b2db3bf3f2256522d9a0348493fd47f295981258b"
  },
  {
    "name": "skeleton",
    "tier": "free",
    "category": "component",
    "description": "Loading-placeholder skeleton that renders `count` pulsing gray blocks (`animate-pulse`, light/dark aware) in the chosen variant.",
    "usage": "<ply-skeleton></ply-skeleton>",
    "keywords": [
      "skeleton"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "728efa1c78adfc3ce0e470260da34179178eb98041f73ea6a865e0fb6503157b"
  },
  {
    "name": "slider",
    "tier": "free",
    "category": "component",
    "description": "A highly configurable image/content carousel component.",
    "usage": "<ply-gallery-slider [interval]=\"3000\" transition=\"crossfade\" [wrap]=\"true\">",
    "keywords": [
      "slider",
      "carousel",
      "gallery",
      "slideshow",
      "gallery-slider, ply-carousel"
    ],
    "dependencies": [
      "rxjs"
    ],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "4f4971104e40668a21933c1cc2a1573311d2bb865909610cd6c9daace604b9b3"
  },
  {
    "name": "social-widget-activity",
    "tier": "pro",
    "category": "widget",
    "description": "Static, presentational social activity feed widget built on `ply-card` with `OnPush` change detection.",
    "usage": "<ply-social-widget-activity></ply-social-widget-activity>",
    "keywords": [
      "social-widget-activity",
      "widget",
      "social",
      "activity"
    ],
    "dependencies": [],
    "registryDependencies": [
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "dafeb2c96e76cebaf8bfb5d9d06f91ca6d633102be8fda111d35436377710617"
  },
  {
    "name": "social-widget-article-comments",
    "tier": "pro",
    "category": "widget",
    "description": "Static social-feed article card with a comment thread, composed from `ply-card`, `ply-avatar`, `ply-icon`, `ply-icon-button`, and `ply-button`.",
    "usage": "<ply-social-widget-article-comments></ply-social-widget-article-comments>",
    "keywords": [
      "social-widget-article-comments",
      "widget",
      "social",
      "article",
      "comments"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "ef5c2b5343f59d27faf553d9a0d2e830ba7f718dad999f1a72d5253faeefc369"
  },
  {
    "name": "social-widget-calendar",
    "tier": "pro",
    "category": "widget",
    "description": "Pro-tier social widget that renders the library's `CalendarComponent` (`<ply-calendar>`) horizontally centered via `mx-auto`.",
    "usage": "<ply-social-widget-calendar></ply-social-widget-calendar>",
    "keywords": [
      "social-widget-calendar",
      "widget",
      "social",
      "calendar"
    ],
    "dependencies": [],
    "registryDependencies": [
      "calendar"
    ],
    "type": "components:ui",
    "digest": "7c2aa005a22e57b74b94a7cb93faed1c7fe7ada325aed78847634e0e36a73a75"
  },
  {
    "name": "social-widget-chat",
    "tier": "pro",
    "category": "widget",
    "description": "Static, fixed-height (540px) one-to-one chat conversation mockup rendered inside a `ply-card`.",
    "usage": "<ply-social-widget-chat></ply-social-widget-chat>",
    "keywords": [
      "social-widget-chat",
      "widget",
      "social",
      "chat"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "39e78409e3ed217603a644997a7a7279a7189ec3679541d32b8b980efc8a7167"
  },
  {
    "name": "social-widget-feed-post",
    "tier": "pro",
    "category": "widget",
    "description": "Pre-built social feed post widget: a `ply-card` with a header row (avatar, author name, timestamp, and a \"more\" icon button), a fixed-height cover image, and a footer action bar with like, comment, and share buttons showing hardcoded counts.",
    "usage": "<ply-social-widget-feed-post></ply-social-widget-feed-post>",
    "keywords": [
      "social-widget-feed-post",
      "widget",
      "social",
      "feed",
      "post"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "d8eb999e4757fe191432ada12a2e9c834419769b8b0ffd924f9b6684344922dd"
  },
  {
    "name": "social-widget-follow-suggestions",
    "tier": "pro",
    "category": "widget",
    "description": "Static \"Who to follow\" social suggestion card built from `ply-card`, `ply-card-header`, and `ply-card-body`, with a \"View All\" text button in the header.",
    "usage": "<ply-social-widget-follow-suggestions></ply-social-widget-follow-suggestions>",
    "keywords": [
      "social-widget-follow-suggestions",
      "widget",
      "social",
      "follow",
      "suggestions"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card"
    ],
    "type": "components:ui",
    "digest": "ad20453625ab48403e8ef3dfcbd7f22c13c73c4e6b2d59f3df93caec61808088"
  },
  {
    "name": "social-widget-image-caption",
    "tier": "pro",
    "category": "widget",
    "description": "Social-media style image card (pro tier) rendering a fixed-height (`h-80`) `ply-card` with a full-bleed background photo and gradient overlays.",
    "usage": "<ply-social-widget-image-caption></ply-social-widget-image-caption>",
    "keywords": [
      "social-widget-image-caption",
      "widget",
      "social",
      "image",
      "caption"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "26987721955fad8df0d17e192648d0f6cb6de66f103773434a76a5722d18bc1e"
  },
  {
    "name": "social-widget-image-overlay",
    "tier": "pro",
    "category": "widget",
    "description": "Social media post card with a full-bleed background image and gradient overlays (fixed height `h-80`, OnPush).",
    "usage": "<ply-social-widget-image-overlay></ply-social-widget-image-overlay>",
    "keywords": [
      "social-widget-image-overlay",
      "widget",
      "social",
      "image",
      "overlay"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "6831d5dad7fc618a14a8841200ce8e3d64416afb5804061a2fc55abb4f1bd7d8"
  },
  {
    "name": "social-widget-inbox",
    "tier": "pro",
    "category": "widget",
    "description": "Compact inbox/message-list card: a header with an \"Inbox\" title, unread-count `ply-badge`, and a search icon button, above a divided list of three conversation rows (avatar with online dot, sender name, one-line message preview, timestamp).",
    "usage": "<ply-social-widget-inbox></ply-social-widget-inbox>",
    "keywords": [
      "social-widget-inbox",
      "widget",
      "social",
      "inbox"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "badge",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "9d93f9724fc3bf22c9097f7ac8c75afa8cb8f4a8a9e229e6761402aef862cc4b"
  },
  {
    "name": "social-widget-platform-stats",
    "tier": "pro",
    "category": "widget",
    "description": "2×2 grid of social-platform stat tiles (Facebook likes, X/Twitter followers, Instagram tags, video subs), each a `ply-card` with a platform `ply-icon`, a large count, and an uppercase label, with hover lift/shadow effects.",
    "usage": "<ply-social-widget-platform-stats></ply-social-widget-platform-stats>",
    "keywords": [
      "social-widget-platform-stats",
      "widget",
      "social",
      "platform",
      "stats"
    ],
    "dependencies": [],
    "registryDependencies": [
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "b7495c96c7895d722bc0f4f02f91d6357a2b9ea42036bdca18838ab35b98be3a"
  },
  {
    "name": "social-widget-profile-centered",
    "tier": "pro",
    "category": "widget",
    "description": "Centered profile card: gradient cover strip with a settings icon button, an overlapping circular `ply-avatar`, name, @handle, an italic bio quote, and a 3-column Posts/Followers/Following stats row divided by hairlines.",
    "usage": "<ply-social-widget-profile-centered></ply-social-widget-profile-centered>",
    "keywords": [
      "social-widget-profile-centered",
      "widget",
      "social",
      "profile",
      "centered"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "3674a15021b70e91694577f052a85d6b20a76398bc60a99413b7a86c1fde6080"
  },
  {
    "name": "social-widget-profile-cover",
    "tier": "pro",
    "category": "widget",
    "description": "Profile card with a photo cover: a 160px lazy-loaded cover image (hover zoom, dark gradient overlay) with the avatar, name, and role overlaid bottom-left.",
    "usage": "<ply-social-widget-profile-cover></ply-social-widget-profile-cover>",
    "keywords": [
      "social-widget-profile-cover",
      "widget",
      "social",
      "profile",
      "cover"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "2499d26179b2fab151ca3497090623902440f5dfda0fe4fdc6f858cdc3dabe68"
  },
  {
    "name": "social-widget-settings-menu",
    "tier": "pro",
    "category": "widget",
    "description": "Account/settings menu card: a blue gradient header with avatar, name, plan label and an \"Upgrade to Pro\" `ply-stroked-button`, followed by a divided menu of three rows (Account Settings, Notifications with an unread dot, Privacy) each with a tinted icon bubble, title, subtitle, a…",
    "usage": "<ply-social-widget-settings-menu></ply-social-widget-settings-menu>",
    "keywords": [
      "social-widget-settings-menu",
      "widget",
      "social",
      "settings",
      "menu"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "ec32b5f00f01d482ff649af97bdeac0a89e9b4c1ac128a3ae5258bdc4fbc52a7"
  },
  {
    "name": "social-widget-text-post",
    "tier": "pro",
    "category": "widget",
    "description": "Text-only social post card: author header (avatar, name, @handle · time, more icon button), a short text body, and a footer bar with reply/repost/like buttons and counts.",
    "usage": "<ply-social-widget-text-post></ply-social-widget-text-post>",
    "keywords": [
      "social-widget-text-post",
      "widget",
      "social",
      "text",
      "post"
    ],
    "dependencies": [],
    "registryDependencies": [
      "avatar",
      "button",
      "card",
      "icon"
    ],
    "type": "components:ui",
    "digest": "98432a96eb9482401f3241d0349216553176e336619c5495d0a1124a2ea59003"
  },
  {
    "name": "social-widget-trending-topics",
    "tier": "pro",
    "category": "widget",
    "description": "\"Trending Topics\" card with a wrap of hashtag pill chips (#photography, #uiux, #angular highlighted in blue, #frontend, #webdesign) with hover states.",
    "usage": "<ply-social-widget-trending-topics></ply-social-widget-trending-topics>",
    "keywords": [
      "social-widget-trending-topics",
      "widget",
      "social",
      "trending",
      "topics"
    ],
    "dependencies": [],
    "registryDependencies": [
      "card"
    ],
    "type": "components:ui",
    "digest": "cca0a9b161481ae9547014fc1c8f0664082270b8e91e39225d7036529062b4c5"
  },
  {
    "name": "social-widget-upload-dropzone",
    "tier": "pro",
    "category": "widget",
    "description": "Thin preset wrapper around `ply-file-upload` configured as a multi-file dropzone (\"Drop files here to upload\").",
    "usage": "<ply-social-widget-upload-dropzone></ply-social-widget-upload-dropzone>",
    "keywords": [
      "social-widget-upload-dropzone",
      "widget",
      "social",
      "upload",
      "dropzone"
    ],
    "dependencies": [],
    "registryDependencies": [
      "file-upload"
    ],
    "type": "components:ui",
    "digest": "44c8cbd82c5eaa8afcc2087bf3fe1e4292c9e1dcd4ecfb4fa09a3b2472621345"
  },
  {
    "name": "speed-dial",
    "tier": "free",
    "category": "component",
    "description": "Free floating action button that expands a stack of secondary actions.",
    "usage": "<ply-speed-dial [actions]=\"actions\" (actionClick)=\"onAction($event)\"></ply-speed-dial>",
    "keywords": [
      "speed-dial",
      "speed",
      "dial"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "562d8a985a9693c6f8a7b701558bbba4a0d09854177d931e492aba5cdf1d93e6"
  },
  {
    "name": "spinner",
    "tier": "free",
    "category": "component",
    "description": "A standard circular loading spinner component.",
    "usage": "<ply-spinner size=\"lg\" color=\"primary\"></ply-spinner>",
    "keywords": [
      "spinner"
    ],
    "dependencies": [],
    "registryDependencies": [
      "types"
    ],
    "type": "components:ui",
    "digest": "823c8e648121ad22582b4bba43d68443cccf29a796e03e7d2d32e07744f3affe"
  },
  {
    "name": "splitter",
    "tier": "pro",
    "category": "component",
    "description": "Two-pane resizable layout.",
    "usage": "<ply-splitter class=\"h-64\" [(size)]=\"leftPct\">",
    "keywords": [
      "splitter",
      "splitpane"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "48a75961c626ef746d6eac58a6e4aa6e16189aa0cb40c5f655080e5e7a1489f9"
  },
  {
    "name": "star-rating",
    "tier": "free",
    "category": "component",
    "description": "A flexbox container wrapper for `ply-star` components.",
    "usage": "<ply-star-rating ariaLabel=\"Product rating\">",
    "keywords": [
      "star-rating",
      "star",
      "rating"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "b92b7e73755eb66c0c79bc0cd3eeac41ac6eee2cdf88ab349f3afe395c1fa2c9"
  },
  {
    "name": "stat-card",
    "tier": "free",
    "category": "component",
    "description": "Dashboard metric card with two layouts.",
    "usage": "<ply-stat-card label=\"Revenue\" value=\"$48,295\" trend=\"+12.5%\" [trendUp]=\"true\" icon=\"dollar-sign\"></ply-stat-card>",
    "keywords": [
      "stat-card",
      "stat",
      "card"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "6ba5553321619ce360af166750ed075e956ad754d5f380c0185bbd7190f90f1b"
  },
  {
    "name": "stepper",
    "tier": "free",
    "category": "component",
    "description": "A multi-step workflow container component.",
    "usage": "<ply-stepper linear hideNavigation (stepChange)=\"onStep($event)\">",
    "keywords": [
      "stepper"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "efb3d56e00e2d7775e7d104e5dcbcdd284aa3c0eac0de4d94d1b0f43a7f167c4"
  },
  {
    "name": "table",
    "tier": "free",
    "category": "component",
    "description": "Free HTML table primitive.",
    "usage": "<div class=\"relative w-full overflow-auto\">",
    "keywords": [
      "table",
      "thead",
      "tbody",
      "html-table",
      "spreadsheet",
      "table[ply-table"
    ],
    "dependencies": [],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "f42fe4412c09b98b2ebe222c6b3de37cd1cae701702db9454c150e05e21f381f"
  },
  {
    "name": "tabs",
    "tier": "free",
    "category": "component",
    "description": "A container component for rendering tabbed navigation and content.",
    "usage": "<ply-tabs [defaultTab]=\"1\">",
    "keywords": [
      "tabs"
    ],
    "dependencies": [],
    "registryDependencies": [
      "button",
      "icon",
      "safe-timer",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "3ee6ab14dd315990bc060ff61802f76cec50288af05ebc2242b32719792b3ae4"
  },
  {
    "name": "tags-input",
    "tier": "free",
    "category": "component",
    "description": "Tag field bound to `string[]` via Angular Forms.",
    "usage": "<ply-tags-input [(ngModel)]=\"labels\" placeholder=\"Add a tag…\"></ply-tags-input>",
    "keywords": [
      "tags-input",
      "tags",
      "input",
      "chips",
      "tokens",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "chips",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "091e13ee3e6f5b5732572368ae6a16109230656772b2ea78d053b7735bf78a6d"
  },
  {
    "name": "theme",
    "tier": "free",
    "category": "component",
    "description": "A service that manages the application's light/dark mode state.",
    "usage": "theme = inject(ThemeService);",
    "keywords": [
      "theme",
      "service"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "4745ed6ecdca7bcccc005fbfe90ab1aa734ef504a5dd1a443e5127835c13373a"
  },
  {
    "name": "time-picker",
    "tier": "free",
    "category": "component",
    "description": "Overlay time picker bound to an `HH:mm` string via Angular Forms.",
    "usage": "<ply-time-picker [(ngModel)]=\"startTime\" label=\"Start\"></ply-time-picker>",
    "keywords": [
      "time-picker",
      "time",
      "picker",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "button-group",
      "icon",
      "input-group",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "80fc4ca46da511ccc3d1f70a895d74bc379b408ab63695436c2cc20f12524632"
  },
  {
    "name": "timeline",
    "tier": "free",
    "category": "component",
    "description": "Vertical timeline container (`flex flex-col` host) that projects `ply-timeline-item` children via `ng-content`.",
    "usage": "<ply-timeline>",
    "keywords": [
      "timeline"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "bf98df7c63eb8b0661e97d805232e09b8908be21d0ef5e02cccd4dd0e01cec63"
  },
  {
    "name": "toast",
    "tier": "free",
    "category": "component",
    "description": "Imperative stacked toast API with expandable deck, swipe-to-dismiss, hover pause, and a reduced-motion static list.",
    "usage": "inject(ToastService).success('Saved')",
    "keywords": [
      "toast",
      "snackbar",
      "notification",
      "sonner",
      "stack",
      "swipe",
      "service"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "safe-timer",
      "types"
    ],
    "type": "components:ui",
    "digest": "56387885e951244f153734b9399f6669a9a2b3203805c2079e32bf5493706e0f"
  },
  {
    "name": "toggle",
    "tier": "free",
    "category": "component",
    "description": "A highly customizable toggle/switch component.",
    "usage": "<ply-toggle [(ngModel)]=\"isActive\" color=\"success\" size=\"lg\" shape=\"rounded\"></ply-toggle>",
    "keywords": [
      "toggle",
      "switch",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "types"
    ],
    "type": "components:ui",
    "digest": "e7d7d01127acc20ec14e5d4544f03bdcbacf586dd832821d1e064e16440d0c9a"
  },
  {
    "name": "tooltip",
    "tier": "free",
    "category": "component",
    "description": "An attribute directive that attaches a floating tooltip to any element.",
    "usage": "<button ply-tooltip=\"This is a helpful tip\" tooltipPlacement=\"right\" type=\"light\">Hover Me</button>",
    "keywords": [
      "tooltip",
      "hint",
      "popover"
    ],
    "dependencies": [],
    "registryDependencies": [
      "overlay-position",
      "types"
    ],
    "type": "components:ui",
    "digest": "06dc6f380575ec0df99a482c7431303da9ca5e83cd56d08e46adae456c740334"
  },
  {
    "name": "tree",
    "tier": "pro",
    "category": "component",
    "description": "A hierarchical tree view component for displaying nested data structures.",
    "usage": "<ply-tree [nodes]=\"myFiles\" (nodeClick)=\"onFileSelected($event)\"></ply-tree>",
    "keywords": [
      "tree",
      "nested"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "safe-timer",
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "27b838c65c1249a7b3405b9e10954f7e1221f652fab6bc2a8f61d33833f32740"
  },
  {
    "name": "tri-state-checkbox",
    "tier": "free",
    "category": "component",
    "description": "Free three-state checkbox that cycles **unchecked → checked → indeterminate** on each click.",
    "usage": "<ply-tri-state-checkbox [(ngModel)]=\"status\">Include archived</ply-tri-state-checkbox>",
    "keywords": [
      "tri-state-checkbox",
      "tri",
      "state",
      "checkbox",
      "cva",
      "ngModel",
      "forms"
    ],
    "dependencies": [],
    "registryDependencies": [
      "icon",
      "tw-merge",
      "types"
    ],
    "type": "components:ui",
    "digest": "0ccf03e404850d5db74240ce210d55f1f3dd24a6a0588b8bee2e0486fa7f4eb4"
  },
  {
    "name": "tw-merge",
    "tier": "free",
    "category": "component",
    "description": "Merges Tailwind classes safely, resolving conflicts using tailwind-merge and clsx.",
    "usage": "cn('bg-blue-500 p-1', 'bg-red-500') // => 'p-1 bg-red-500'",
    "keywords": [
      "tw-merge",
      "tw",
      "merge",
      "cn",
      "tailwind",
      "clsx"
    ],
    "dependencies": [
      "clsx",
      "tailwind-merge"
    ],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "05fd9c50460346ebf89dce96f87541ba2e95d755df05b346069f994a4eee2ba7"
  },
  {
    "name": "types",
    "tier": "free",
    "category": "component",
    "description": "Shared TypeScript types for Ply color, size, and form contracts.",
    "usage": "import type { ButtonColor } from './types'",
    "keywords": [
      "types",
      "typescript"
    ],
    "dependencies": [],
    "registryDependencies": [
      "scroll-container"
    ],
    "type": "components:ui",
    "digest": "48b1d3c3db967eb1704c9e5c1f526de154a28cf6e2500333884844b9a096cbab"
  },
  {
    "name": "typography",
    "tier": "free",
    "category": "component",
    "description": "Applies standardized heading typography styles to an element.",
    "usage": "<h1 plyHeadingText>Page Title</h1>",
    "keywords": [
      "typography",
      "plyHeadingText"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "2bd3d2e802b4eeb656011dd4e84587188c9e1e646c7bbe4829a49f635f07c549"
  },
  {
    "name": "virtual-scroll",
    "tier": "pro",
    "category": "component",
    "description": "Fixed-size virtual scroll viewport for large lists.",
    "usage": "<ply-virtual-scroll class=\"block h-96\" [items]=\"users\" [itemSize]=\"56\">",
    "keywords": [
      "virtual-scroll",
      "virtual",
      "scroll",
      "infinite"
    ],
    "dependencies": [
      "@angular/cdk"
    ],
    "registryDependencies": [
      "tw-merge"
    ],
    "type": "components:ui",
    "digest": "af35bc7e4daf5caa98d6df91459caea535b427471da2875d16d7563199f576fd"
  },
  {
    "name": "z-index",
    "tier": "free",
    "category": "component",
    "description": "Centralized z-index scale for fixed-position overlays.",
    "usage": "npx ply-ui-cli add z-index",
    "keywords": [
      "z-index",
      "index"
    ],
    "dependencies": [],
    "registryDependencies": [],
    "type": "components:ui",
    "digest": "f4163a0e114217fcdea1a50121e1df9c79b06875768b365a745e11efc8e1d638"
  }
]