{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "ad-spend-roi-dashboard",
  "title": "Ad Spend Roi Dashboard",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/ad-spend-roi-dashboard/ad-spend-roi-dashboard.component.ts",
      "content": "// Multi-channel paid acquisition ad spend, blended ROAS, and CAC performance\n// dashboard: KPI cards, channel comparison table with live toggles, and top\n// campaigns. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, signal } from '@angular/core'\nimport {\n  Award,\n  Calendar,\n  Download,\n  LucideAngularModule,\n  Megaphone,\n  Plus,\n  Search,\n  Share2,\n  Target,\n  TrendingDown,\n  TrendingUp,\n  Users,\n  Wallet,\n  Zap,\n  type LucideIconData,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\nimport {\n  UiSelectComponent,\n  UiSelectContentComponent,\n  UiSelectItemComponent,\n  UiSelectTriggerComponent,\n  UiSelectValueComponent,\n} from '@/ui/select/select.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport { UiSwitchComponent } from '@/ui/switch/switch.component'\nimport {\n  UiTableBodyComponent,\n  UiTableCellComponent,\n  UiTableComponent,\n  UiTableHeadComponent,\n  UiTableHeaderComponent,\n  UiTableRowComponent,\n} from '@/ui/table/table.component'\n\nexport type ChannelRoasStatus = 'high' | 'medium' | 'low'\n\nexport interface AdChannelPerformance {\n  id: string\n  name: string\n  campaignCount: number\n  spend: string\n  impressions: string\n  clicks: string\n  ctr: string\n  cpc: string\n  cpa: string\n  roas: string\n  roasStatus: ChannelRoasStatus\n  conversions: number\n  revenue: string\n  active: boolean\n  icon: LucideIconData\n  iconClass: string\n}\n\nexport interface TopCampaign {\n  id: string\n  rank: number\n  name: string\n  channel: string\n  targetNiche: string\n  spend: string\n  revenue: string\n  cpa: string\n  roas: string\n}\n\nconst initialChannels: AdChannelPerformance[] = [\n  {\n    id: 'google-search',\n    name: 'Google Search Ads',\n    campaignCount: 6,\n    spend: '$11,200.00',\n    impressions: '248,500',\n    clicks: '14,910',\n    ctr: '6.00%',\n    cpc: '$0.75',\n    cpa: '$42.10',\n    roas: '4.2x',\n    roasStatus: 'high',\n    conversions: 266,\n    revenue: '$47,040.00',\n    active: true,\n    icon: Search,\n    iconClass: 'bg-info/10 text-info border-info/20',\n  },\n  {\n    id: 'meta-ads',\n    name: 'Meta / Instagram Ads',\n    campaignCount: 8,\n    spend: '$7,650.00',\n    impressions: '420,000',\n    clicks: '8,400',\n    ctr: '2.00%',\n    cpc: '$0.91',\n    cpa: '$49.35',\n    roas: '3.1x',\n    roasStatus: 'high',\n    conversions: 155,\n    revenue: '$23,715.00',\n    active: true,\n    icon: Share2,\n    iconClass: 'bg-chart-1/10 text-chart-1 border-chart-1/20',\n  },\n  {\n    id: 'linkedin-ads',\n    name: 'LinkedIn Sponsored',\n    campaignCount: 3,\n    spend: '$3,800.00',\n    impressions: '54,000',\n    clicks: '1,080',\n    ctr: '2.00%',\n    cpc: '$3.52',\n    cpa: '$64.40',\n    roas: '2.4x',\n    roasStatus: 'medium',\n    conversions: 59,\n    revenue: '$9,120.00',\n    active: true,\n    icon: Megaphone,\n    iconClass: 'bg-info/10 text-info border-info/20',\n  },\n  {\n    id: 'twitter-ads',\n    name: 'Twitter / X Ads',\n    campaignCount: 2,\n    spend: '$2,200.00',\n    impressions: '110,000',\n    clicks: '1,650',\n    ctr: '1.50%',\n    cpc: '$1.33',\n    cpa: '$68.75',\n    roas: '1.8x',\n    roasStatus: 'low',\n    conversions: 32,\n    revenue: '$3,960.00',\n    active: false,\n    icon: Zap,\n    iconClass: 'bg-zinc-500/10 text-zinc-600 text-muted-foreground border-zinc-500/20',\n  },\n]\n\nconst topCampaigns: TopCampaign[] = [\n  {\n    id: 'camp-1',\n    rank: 1,\n    name: 'Q3 Retargeting · High-Intent Abandoned Cart',\n    channel: 'Google Search Ads',\n    targetNiche: 'SaaS Mid-Market Decision Makers',\n    spend: '$4,120.00',\n    revenue: '$22,248.00',\n    cpa: '$34.33',\n    roas: '5.4x',\n  },\n  {\n    id: 'camp-2',\n    rank: 2,\n    name: 'Competitor Keyword Conquesting - Core US',\n    channel: 'Google Search Ads',\n    targetNiche: 'Direct B2B Search Intent',\n    spend: '$6,800.00',\n    revenue: '$31,280.00',\n    cpa: '$38.20',\n    roas: '4.6x',\n  },\n  {\n    id: 'camp-3',\n    rank: 3,\n    name: 'Founder Video Testimonial - Lookalike 1%',\n    channel: 'Meta / Instagram Ads',\n    targetNiche: 'Seed & Series A Tech Founders',\n    spend: '$3,450.00',\n    revenue: '$13,110.00',\n    cpa: '$46.00',\n    roas: '3.8x',\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-ad-spend-roi-dashboard, [ui-ad-spend-roi-dashboard]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiProgressComponent,\n    UiSelectComponent,\n    UiSelectContentComponent,\n    UiSelectItemComponent,\n    UiSelectTriggerComponent,\n    UiSelectValueComponent,\n    UiSeparatorComponent,\n    UiSwitchComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n  ],\n  template: `\n    <div data-slot=\"ad-spend-roi-dashboard\" [class]=\"rootClass\">\n      <!-- Header -->\n      <div class=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n        <div class=\"space-y-1\">\n          <h1 class=\"text-foreground text-2xl font-bold tracking-tight sm:text-3xl\">Paid Acquisition & Ad Spend ROI</h1>\n          <p class=\"text-muted-foreground text-sm\">\n            Multi-channel paid acquisition ad spend, blended ROAS, and CAC performance dashboard.\n          </p>\n        </div>\n        <div class=\"flex flex-wrap items-center gap-2.5\">\n          <ui-select [value]=\"selectedPeriod()\" (valueChange)=\"selectedPeriod.set($event)\">\n            <button ui-select-trigger class=\"w-56 text-xs\" aria-label=\"Select date range\">\n              <lucide-icon [img]=\"Calendar\" class=\"text-muted-foreground mr-1.5 size-3.5\" />\n              <ui-select-value placeholder=\"Select period\" />\n            </button>\n            <ui-select-content>\n              <ui-select-item value=\"this-month\">This Month · Aug 2026</ui-select-item>\n              <ui-select-item value=\"last-month\">Last Month · Jul 2026</ui-select-item>\n              <ui-select-item value=\"last-30\">Last 30 Days</ui-select-item>\n              <ui-select-item value=\"last-90\">Last 90 Days (Q3)</ui-select-item>\n              <ui-select-item value=\"ytd\">Year to Date · 2026</ui-select-item>\n            </ui-select-content>\n          </ui-select>\n          <button ui-button aria-label=\"Download attachment\" variant=\"outline\" size=\"sm\" class=\"gap-1.5 text-xs\">\n            <lucide-icon [img]=\"Download\" class=\"size-3.5\" />\n            <span>Export Campaign CSV</span>\n          </button>\n          <button ui-button size=\"sm\" class=\"gap-1.5 text-xs\">\n            <lucide-icon [img]=\"Plus\" class=\"size-3.5\" />\n            <span>Connect Ad Account</span>\n          </button>\n        </div>\n      </div>\n\n      <!-- 4 Primary Performance KPI Cards -->\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex flex-wrap items-center justify-between gap-2\">\n              <div class=\"flex min-w-0 items-center gap-2\">\n                <div\n                  class=\"border-border bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                  aria-hidden=\"true\"\n                >\n                  <lucide-icon [img]=\"Wallet\" class=\"size-4\" />\n                </div>\n                <h3 ui-card-title class=\"text-muted-foreground text-sm font-medium\">Total Ad Spend</h3>\n              </div>\n              <span ui-badge wrap variant=\"outline\" class=\"text-xs font-normal tabular-nums\">82.8% pacing</span>\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-3\">\n            <div>\n              <div class=\"flex items-baseline gap-1.5\">\n                <span class=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">$24,850.00</span>\n              </div>\n              <p class=\"text-muted-foreground mt-0.5 text-xs tabular-nums\">Monthly budget $30,000.00</p>\n            </div>\n            <div class=\"space-y-1.5\">\n              <ui-progress [value]=\"82.8\" class=\"[&_[data-slot=progress-indicator]]:bg-primary h-1.5\" />\n              <div class=\"text-muted-foreground flex items-center justify-between text-xs tabular-nums\">\n                <span>$5,150.00 headroom</span>\n                <span>10 days left</span>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex flex-wrap items-center justify-between gap-2\">\n              <div class=\"flex min-w-0 items-center gap-2\">\n                <div\n                  class=\"border-success/20 bg-success/10 text-success flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                  aria-hidden=\"true\"\n                >\n                  <lucide-icon [img]=\"TrendingUp\" class=\"size-4\" />\n                </div>\n                <h3 ui-card-title class=\"text-muted-foreground text-sm font-medium\">Attributed Revenue</h3>\n              </div>\n              <span\n                ui-badge\n                wrap\n                variant=\"outline\"\n                class=\"border-success/20 bg-success/10 text-success text-xs font-bold tabular-nums\"\n              >\n                3.39x Blended ROAS\n              </span>\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-3\">\n            <div>\n              <div class=\"flex items-baseline gap-1.5\">\n                <span class=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">$84,200.00</span>\n              </div>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Direct ad touch attribution</p>\n            </div>\n            <div class=\"border-border/60 border-t pt-2 text-xs\">\n              <div class=\"flex items-center justify-between\">\n                <span class=\"text-muted-foreground\">Period growth:</span>\n                <span class=\"text-success font-semibold tabular-nums\">+$18,450.00 (+28.1%)</span>\n              </div>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Target ROAS: 2.80x (exceeded)</p>\n            </div>\n          </div>\n        </div>\n\n        <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex flex-wrap items-center justify-between gap-2\">\n              <div class=\"flex min-w-0 items-center gap-2\">\n                <div\n                  class=\"border-border bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                  aria-hidden=\"true\"\n                >\n                  <lucide-icon [img]=\"Target\" class=\"size-4\" />\n                </div>\n                <h3 ui-card-title class=\"text-muted-foreground text-sm font-medium\">Customer Acquisition Cost</h3>\n              </div>\n              <span\n                ui-badge\n                wrap\n                variant=\"outline\"\n                class=\"border-success/20 bg-success/10 text-success gap-1 text-xs font-medium tabular-nums\"\n              >\n                <lucide-icon [img]=\"TrendingDown\" class=\"size-3\" />\n                <span>-$6.20 vs last month</span>\n              </span>\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-3\">\n            <div>\n              <div class=\"flex items-baseline gap-1.5\">\n                <span class=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">$48.50</span>\n                <span class=\"text-muted-foreground text-xs\">/ customer</span>\n              </div>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Blended across all 4 channels</p>\n            </div>\n            <div class=\"border-border/60 border-t pt-2 text-xs\">\n              <div class=\"flex items-center justify-between\">\n                <span class=\"text-muted-foreground\">Target CAC ceiling:</span>\n                <span class=\"text-foreground font-semibold tabular-nums\">$55.00 max</span>\n              </div>\n              <p class=\"text-success mt-0.5 text-xs font-medium\">11.8% below budget cap</p>\n            </div>\n          </div>\n        </div>\n\n        <div ui-card class=\"flex flex-col justify-between shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex flex-wrap items-center justify-between gap-2\">\n              <div class=\"flex min-w-0 items-center gap-2\">\n                <div\n                  class=\"border-border bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                  aria-hidden=\"true\"\n                >\n                  <lucide-icon [img]=\"Users\" class=\"size-4\" />\n                </div>\n                <h3 ui-card-title class=\"text-muted-foreground text-sm font-medium\">Total Conversions</h3>\n              </div>\n              <span ui-badge wrap variant=\"outline\" class=\"text-xs font-normal tabular-nums\">+64 vs Jul</span>\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-3\">\n            <div>\n              <div class=\"flex items-baseline gap-1.5\">\n                <span class=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">512</span>\n                <span class=\"text-foreground text-sm font-semibold\">Paid Customers</span>\n              </div>\n              <p class=\"text-muted-foreground mt-0.5 text-xs tabular-nums\">Avg order value $164.45</p>\n            </div>\n            <div class=\"border-border/60 border-t pt-2 text-xs\">\n              <div class=\"flex items-center justify-between\">\n                <span class=\"text-muted-foreground\">Blended Conversion Rate:</span>\n                <span class=\"text-foreground font-semibold tabular-nums\">14.2%</span>\n              </div>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Organic lift multiplier: 1.18x</p>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Channel Performance Comparison Table -->\n      <div ui-card class=\"shadow-xs\">\n        <div ui-card-header>\n          <div class=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n            <div>\n              <h3 ui-card-title>Channel Performance Comparison</h3>\n              <p ui-card-description>\n                Unit economics, click-through rates, acquisition volumes, and return on ad spend across channels.\n              </p>\n            </div>\n            <span ui-badge wrap variant=\"outline\" class=\"w-fit text-xs font-normal tabular-nums\">\n              4 channels active\n            </span>\n          </div>\n        </div>\n        <div ui-card-content class=\"p-0 sm:p-6 sm:pt-0\">\n          <div class=\"overflow-x-auto\">\n            <table ui-table>\n              <thead ui-table-header>\n                <tr ui-table-row>\n                  <th ui-table-head class=\"min-w-[200px]\">Channel & Campaigns</th>\n                  <th ui-table-head class=\"text-right\">Spend</th>\n                  <th ui-table-head class=\"text-right\">Impressions & Clicks (CTR)</th>\n                  <th ui-table-head class=\"text-right\">CPC & CPA</th>\n                  <th ui-table-head class=\"text-right\">ROAS</th>\n                  <th ui-table-head class=\"text-right\">Conversions & Rev</th>\n                  <th ui-table-head class=\"text-right\">Status</th>\n                </tr>\n              </thead>\n              <tbody ui-table-body>\n                @for (channel of channels(); track channel.id) {\n                  <tr ui-table-row class=\"hover:bg-muted/50\">\n                    <td ui-table-cell>\n                      <div class=\"flex items-center gap-3\">\n                        <div [class]=\"channelIconClass(channel)\" aria-hidden=\"true\">\n                          <lucide-icon [img]=\"channel.icon\" class=\"size-4\" />\n                        </div>\n                        <div>\n                          <div class=\"text-foreground text-sm font-semibold\">{{ channel.name }}</div>\n                          <div class=\"text-muted-foreground text-xs tabular-nums\">\n                            {{ channel.campaignCount }} active campaigns\n                          </div>\n                        </div>\n                      </div>\n                    </td>\n                    <td ui-table-cell class=\"text-right\">\n                      <div class=\"text-foreground text-sm font-semibold tabular-nums\">{{ channel.spend }}</div>\n                      <div class=\"text-muted-foreground text-xs tabular-nums\">{{ spendShare(channel) }}% of total</div>\n                    </td>\n                    <td ui-table-cell class=\"text-right\">\n                      <div class=\"text-foreground text-xs font-medium tabular-nums\">{{ channel.impressions }} imp</div>\n                      <div class=\"text-muted-foreground text-xs tabular-nums\">\n                        {{ channel.clicks }} clicks ({{ channel.ctr }})\n                      </div>\n                    </td>\n                    <td ui-table-cell class=\"text-right\">\n                      <div class=\"text-foreground text-xs font-semibold tabular-nums\">{{ channel.cpc }} CPC</div>\n                      <div class=\"text-muted-foreground text-xs tabular-nums\">{{ channel.cpa }} CPA</div>\n                    </td>\n                    <td ui-table-cell class=\"text-right\">\n                      <span ui-badge variant=\"outline\" [class]=\"roasBadgeClass(channel)\">\n                        {{ channel.roas }} ROAS\n                      </span>\n                    </td>\n                    <td ui-table-cell class=\"text-right\">\n                      <div class=\"text-foreground text-xs font-bold tabular-nums\">{{ channel.revenue }}</div>\n                      <div class=\"text-muted-foreground text-xs tabular-nums\">\n                        {{ channel.conversions }} conversions\n                      </div>\n                    </td>\n                    <td ui-table-cell class=\"text-right\">\n                      <div class=\"flex items-center justify-end gap-2\">\n                        <span class=\"text-muted-foreground text-xs font-medium\">\n                          {{ channel.active ? 'Active' : 'Paused' }}\n                        </span>\n                        <button\n                          ui-switch\n                          [checked]=\"channel.active\"\n                          [attr.aria-label]=\"'Toggle status for ' + channel.name\"\n                          (checkedChange)=\"handleToggleChannel(channel.id, $event)\"\n                        ></button>\n                      </div>\n                    </td>\n                  </tr>\n                }\n              </tbody>\n            </table>\n          </div>\n        </div>\n      </div>\n\n      <!-- Bottom Section: Top Performing Campaigns & Budget Allocation -->\n      <div class=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n        <div ui-card class=\"shadow-xs\">\n          <div ui-card-header>\n            <div class=\"flex items-center justify-between\">\n              <h3 ui-card-title>Top Performing Campaigns</h3>\n              <span ui-badge wrap variant=\"outline\" class=\"gap-1 text-xs\">\n                <lucide-icon [img]=\"Award\" class=\"text-warning size-3\" />\n                <span>Highest ROAS</span>\n              </span>\n            </div>\n            <p ui-card-description>Ad creatives and targeting sets driving highest attribution revenue and ROAS.</p>\n          </div>\n          <div ui-card-content class=\"space-y-4\">\n            @for (campaign of topCampaigns; track campaign.id) {\n              <div\n                class=\"border-border bg-muted/30 hover:bg-muted/60 flex flex-col gap-3 rounded-lg border p-4 transition-colors\"\n              >\n                <div class=\"flex items-start justify-between gap-2\">\n                  <div class=\"flex items-start gap-2.5\">\n                    <span\n                      ui-badge\n                      wrap\n                      [variant]=\"campaign.rank === 1 ? 'default' : 'secondary'\"\n                      class=\"flex size-6 shrink-0 items-center justify-center rounded-full p-0 text-xs font-bold tabular-nums\"\n                    >\n                      #{{ campaign.rank }}\n                    </span>\n                    <div class=\"space-y-0.5\">\n                      <h4 class=\"text-foreground text-sm font-semibold\">{{ campaign.name }}</h4>\n                      <div class=\"flex flex-wrap items-center gap-1.5\">\n                        <span ui-badge wrap variant=\"outline\" class=\"text-xs font-normal\">{{ campaign.channel }}</span>\n                        <span class=\"text-muted-foreground text-xs\">{{ campaign.targetNiche }}</span>\n                      </div>\n                    </div>\n                  </div>\n                  <span\n                    ui-badge\n                    wrap\n                    variant=\"outline\"\n                    class=\"border-success/20 bg-success/10 text-success shrink-0 text-xs font-bold tabular-nums\"\n                  >\n                    {{ campaign.roas }} ROAS\n                  </span>\n                </div>\n\n                <div class=\"border-border/60 grid grid-cols-1 gap-2 border-t pt-2 text-xs sm:grid-cols-3\">\n                  <div>\n                    <span class=\"text-muted-foreground\">Spend:</span>\n                    <p class=\"text-foreground font-semibold tabular-nums\">{{ campaign.spend }}</p>\n                  </div>\n                  <div>\n                    <span class=\"text-muted-foreground\">Attributed Rev:</span>\n                    <p class=\"text-success font-semibold tabular-nums\">{{ campaign.revenue }}</p>\n                  </div>\n                  <div class=\"sm:text-right\">\n                    <span class=\"text-muted-foreground\">Unit CPA:</span>\n                    <p class=\"text-foreground font-semibold tabular-nums\">{{ campaign.cpa }}</p>\n                  </div>\n                </div>\n              </div>\n            }\n          </div>\n        </div>\n\n        <div ui-card class=\"shadow-xs\">\n          <div ui-card-header>\n            <div class=\"flex items-center justify-between\">\n              <h3 ui-card-title>Budget Allocation & Guardrails</h3>\n              <span ui-badge wrap variant=\"outline\" class=\"text-xs font-normal\">Automated Pacing</span>\n            </div>\n            <p ui-card-description>\n              Live capital distribution by ad channel with automated spend-shift recommendations.\n            </p>\n          </div>\n          <div ui-card-content class=\"space-y-4\">\n            <div\n              class=\"border-border bg-muted/40 flex flex-wrap items-baseline justify-between gap-x-2 gap-y-0.5 rounded-lg border p-4\"\n            >\n              <div>\n                <p class=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Total Deployed Spend</p>\n                <p class=\"text-foreground text-3xl font-bold tracking-tight tabular-nums\">$24,850.00</p>\n              </div>\n              <div class=\"text-right\">\n                <span class=\"text-muted-foreground text-xs\">\n                  Budget Cap: <strong class=\"text-foreground font-semibold tabular-nums\">$30,000.00</strong>\n                </span>\n                <p class=\"text-success text-xs font-semibold tabular-nums\">$5,150.00 (17.2%) remaining</p>\n              </div>\n            </div>\n\n            <div class=\"space-y-3 text-xs\">\n              <div class=\"space-y-1\">\n                <div class=\"flex items-center justify-between\">\n                  <span class=\"text-foreground font-medium\">Google Search Ads (45.1%)</span>\n                  <span class=\"text-foreground font-semibold tabular-nums\">$11,200.00 / 4.2x ROAS</span>\n                </div>\n                <ui-progress [value]=\"45.1\" class=\"[&_[data-slot=progress-indicator]]:bg-info h-1.5\" />\n              </div>\n\n              <div class=\"space-y-1\">\n                <div class=\"flex items-center justify-between\">\n                  <span class=\"text-foreground font-medium\">Meta / Instagram Ads (30.8%)</span>\n                  <span class=\"text-foreground font-semibold tabular-nums\">$7,650.00 / 3.1x ROAS</span>\n                </div>\n                <ui-progress [value]=\"30.8\" class=\"[&_[data-slot=progress-indicator]]:bg-chart-1 h-1.5\" />\n              </div>\n\n              <div class=\"space-y-1\">\n                <div class=\"flex items-center justify-between\">\n                  <span class=\"text-foreground font-medium\">LinkedIn Sponsored (15.3%)</span>\n                  <span class=\"text-foreground font-semibold tabular-nums\">$3,800.00 / 2.4x ROAS</span>\n                </div>\n                <ui-progress [value]=\"15.3\" class=\"[&_[data-slot=progress-indicator]]:bg-info h-1.5\" />\n              </div>\n\n              <div class=\"space-y-1\">\n                <div class=\"flex items-center justify-between\">\n                  <span class=\"text-foreground font-medium\">Twitter / X Ads (8.8%)</span>\n                  <span class=\"text-muted-foreground font-semibold tabular-nums\">$2,200.00 / 1.8x ROAS</span>\n                </div>\n                <ui-progress [value]=\"8.8\" class=\"h-1.5 [&_[data-slot=progress-indicator]]:bg-zinc-500\" />\n              </div>\n            </div>\n\n            <ui-separator />\n\n            <div class=\"border-border/80 bg-muted/20 flex items-start gap-3 rounded-lg border p-3\">\n              <lucide-icon [img]=\"TrendingUp\" class=\"text-primary mt-0.5 size-4 shrink-0\" />\n              <div class=\"space-y-1\">\n                <h5 class=\"text-foreground text-xs font-semibold\">Growth Optimization Insight</h5>\n                <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                  Google Search & Meta campaigns are outperforming blended ROAS target (+0.59x). Pausing Twitter / X Ads\n                  saves $73.30/day to reallocate into the highest-converting Q3 Retargeting set.\n                </p>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiAdSpendRoiDashboardComponent {\n  protected readonly Award = Award\n  protected readonly Calendar = Calendar\n  protected readonly Download = Download\n  protected readonly Plus = Plus\n  protected readonly Target = Target\n  protected readonly TrendingDown = TrendingDown\n  protected readonly TrendingUp = TrendingUp\n  protected readonly Users = Users\n  protected readonly Wallet = Wallet\n\n  protected readonly topCampaigns = topCampaigns\n\n  @Input() set initialPeriod(v: string | undefined) {\n    this.selectedPeriod.set(v ?? 'this-month')\n  }\n  @Input('class') className?: string\n\n  readonly selectedPeriod = signal('this-month')\n  readonly channels = signal<AdChannelPerformance[]>(initialChannels.map((c) => ({ ...c })))\n\n  get rootClass(): string {\n    return cn('mx-auto w-full max-w-6xl space-y-6', this.className)\n  }\n\n  channelIconClass(channel: AdChannelPerformance): string {\n    return cn('flex size-8 shrink-0 items-center justify-center rounded-lg border shadow-xs', channel.iconClass)\n  }\n\n  spendShare(channel: AdChannelPerformance): string {\n    const spendNum = parseFloat(channel.spend.replace(/[$,]/g, ''))\n    return ((spendNum / 24850) * 100).toFixed(1)\n  }\n\n  roasBadgeClass(channel: AdChannelPerformance): string {\n    return cn(\n      'text-xs font-bold tabular-nums',\n      channel.roasStatus === 'high' && 'border-success/20 bg-success/10 text-success',\n      channel.roasStatus === 'medium' && 'border-info/20 bg-info/10 text-info',\n      channel.roasStatus === 'low' && 'border-warning/20 bg-warning/10 text-warning',\n    )\n  }\n\n  handleToggleChannel(id: string, active: boolean): void {\n    this.channels.update((prev) => prev.map((ch) => (ch.id === id ? { ...ch, active } : ch)))\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/ad-spend-roi-dashboard/ad-spend-roi-dashboard.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/ad-spend-roi-dashboard/index.ts",
      "content": "export {\n  UiAdSpendRoiDashboardComponent,\n  type AdChannelPerformance,\n  type ChannelRoasStatus,\n  type TopCampaign,\n} from './ad-spend-roi-dashboard.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/ad-spend-roi-dashboard/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/progress.json",
    "https://uipkge.dev/r/angular/select.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/switch.json",
    "https://uipkge.dev/r/angular/table.json"
  ],
  "description": "Multi-channel paid acquisition ad spend, blended ROAS, and CAC performance dashboard: 4 primary KPI cards (total spend, revenue with blended ROAS, CAC, conversions), channel performance comparison table with live toggle switches, and top 3 performing campaign breakdown.",
  "categories": [
    "marketing",
    "dashboard",
    "analytics"
  ]
}