{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "daily-standup-summary",
  "title": "Daily Standup Summary",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/daily-standup-summary/daily-standup-summary.component.ts",
      "content": "// Slack and Geekbot style async engineering daily standup summary with squad pulse cards,\n// critical blocker alert callout, structured yesterday/today/blockers submission entries,\n// reaction counts, and thread actions. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport {\n  AlertTriangle,\n  ArrowRight,\n  Bot,\n  Calendar,\n  Check,\n  CheckCircle2,\n  Clock,\n  Copy,\n  Flame,\n  Handshake,\n  LucideAngularModule,\n  MessageSquare,\n  Rocket,\n  Send,\n  ShieldAlert,\n  ShieldCheck,\n  Smile,\n  Target,\n  Users,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiAvatarComponent, UiAvatarFallbackComponent, UiAvatarImageComponent } from '@/ui/avatar/avatar.component'\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 { UiSeparatorComponent } from '@/ui/separator/separator.component'\n\nexport type StandupStatus = 'on-track' | 'blocked' | 'needs-review'\n\nexport interface StandupReaction {\n  emoji: string\n  count: number\n  active?: boolean\n}\n\nexport interface StandupMember {\n  id: string\n  name: string\n  role: string\n  avatar: string\n  fallback: string\n  submittedAt: string\n  timezone: string\n  status: StandupStatus\n  statusLabel: string\n  yesterday: string[]\n  today: string[]\n  blockers?: string | null\n  blockerSeverity?: 'critical' | 'moderate' | 'low'\n  reactions: StandupReaction[]\n  threadCount?: number\n}\n\nexport interface BlockerAlert {\n  id: string\n  title: string\n  description: string\n  authorName: string\n  authorRole: string\n  reportedAt: string\n  ticketId?: string\n  scope: string\n  assignedSquad: string\n}\n\nexport interface StandupPulseMetrics {\n  submissionsCount: number\n  totalMembers: number\n  pendingMemberName?: string\n  activeBlockersCount: number\n  blockersHighlight?: string\n  goalsOnTrackCount: number\n  totalGoals: number\n  sprintName?: string\n  deploymentsPlannedCount: number\n  deploymentsHighlight?: string\n}\n\nconst defaultPulseMetrics: StandupPulseMetrics = {\n  submissionsCount: 5,\n  totalMembers: 6,\n  pendingMemberName: 'Alex Rivera (PTO / Vacation)',\n  activeBlockersCount: 1,\n  blockersHighlight: 'AWS IAM KMS staging rotation',\n  goalsOnTrackCount: 8,\n  totalGoals: 10,\n  sprintName: 'Sprint 42 · 3 days left',\n  deploymentsPlannedCount: 3,\n  deploymentsHighlight: '2 staging · 1 production (v2.4.0)',\n}\n\nconst defaultBlockerAlert: BlockerAlert = {\n  id: 'blk-aws-kms-01',\n  title: 'Blocked on AWS IAM permission grant for KMS rotation in staging',\n  description:\n    'Unable to complete cryptographic secret rotation automated test suite for the v2.4 staging cluster. Ticket SEC-9104 is currently pending approval from the Security Operations squad.',\n  authorName: 'Marcus Vance',\n  authorRole: 'DevOps & Cloud Architect',\n  reportedAt: '42m ago',\n  ticketId: 'SEC-9104',\n  scope: 'Staging Pipeline',\n  assignedSquad: '#sec-ops-triage',\n}\n\nconst defaultMembers: StandupMember[] = [\n  {\n    id: 'mem-1',\n    name: 'Elena Rostova',\n    role: 'Principal Engineer',\n    avatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150&auto=format&fit=crop&q=80',\n    fallback: 'ER',\n    submittedAt: '09:15 AM',\n    timezone: 'UTC+2 · Berlin',\n    status: 'on-track',\n    statusLabel: 'On Track',\n    yesterday: [\n      'Merged RFC #142 for headless multi-token theme engine architecture',\n      'Reviewed and approved 6 PRs across core UI primitive components',\n      'Mentored frontend team on Reka UI polymorphic asChild slot bindings',\n    ],\n    today: [\n      'Finalizing async tree-shaking benchmarking suite for monorepo components (#PERF-892)',\n      'Kicking off Design Tokens v4 migration RFC discussion thread with design systems team',\n      'Pairing with Sarah on virtualized combobox keyboard focus trap resolution',\n    ],\n    blockers: null,\n    reactions: [\n      { emoji: '👍', count: 4, active: true },\n      { emoji: '🚀', count: 2, active: false },\n      { emoji: '👀', count: 3, active: false },\n      { emoji: '🧠', count: 1, active: false },\n    ],\n    threadCount: 3,\n  },\n  {\n    id: 'mem-2',\n    name: 'Marcus Vance',\n    role: 'DevOps & Cloud Architect',\n    avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&auto=format&fit=crop&q=80',\n    fallback: 'MV',\n    submittedAt: '09:28 AM',\n    timezone: 'UTC-5 · New York',\n    status: 'blocked',\n    statusLabel: 'Blocked',\n    blockerSeverity: 'critical',\n    yesterday: [\n      'Provisioned ephemeral preview environments for automated PR test runners',\n      'Automated Cloudflare Pages edge cache invalidation hooks in GitHub Actions',\n    ],\n    today: [\n      'Rolling out canary release v2.4.0 to EU cluster once KMS permissions clear (#OPS-419)',\n      'Setting up Prometheus edge exporter for SSR latency and cache hit ratios',\n    ],\n    blockers:\n      'Blocked on AWS IAM permission grant for KMS rotation in staging. Escalated to Security Ops in #sec-ops-triage (Ticket SEC-9104).',\n    reactions: [\n      { emoji: '🚨', count: 3, active: true },\n      { emoji: '💬', count: 4, active: false },\n      { emoji: '🤝', count: 2, active: false },\n      { emoji: '🙏', count: 1, active: false },\n    ],\n    threadCount: 4,\n  },\n  {\n    id: 'mem-3',\n    name: 'David Chen',\n    role: 'Full-Stack Engineer',\n    avatar: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=150&auto=format&fit=crop&q=80',\n    fallback: 'DC',\n    submittedAt: '09:42 AM',\n    timezone: 'UTC-7 · San Francisco',\n    status: 'on-track',\n    statusLabel: 'On Track',\n    yesterday: [\n      'Implemented Nitro rate-limiting telemetry parser and token bucket middleware',\n      'Wrote 34 unit tests for zero-allocation token stringifier algorithm',\n    ],\n    today: [\n      'Implementing HMAC-SHA256 webhook signature validation generator (#CORE-331)',\n      'Writing OpenAPI 3.1 documentation with interactive curl playground snippets',\n    ],\n    blockers: null,\n    reactions: [\n      { emoji: '🔥', count: 5, active: false },\n      { emoji: '👍', count: 3, active: true },\n      { emoji: '⚡', count: 2, active: false },\n    ],\n    threadCount: 1,\n  },\n  {\n    id: 'mem-4',\n    name: 'Sarah Jenkins',\n    role: 'Frontend Specialist',\n    avatar: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=150&auto=format&fit=crop&q=80',\n    fallback: 'SJ',\n    submittedAt: '09:55 AM',\n    timezone: 'UTC+1 · London',\n    status: 'needs-review',\n    statusLabel: 'Needs Review',\n    yesterday: [\n      'Completed accessible combobox keyboard navigation and roving tabindex support',\n      'Audited dark mode OKLCH contrast ratios on table headers and badges',\n    ],\n    today: [\n      'Benchmarking spring physics motion transition framerates on mobile viewports (#UI-204)',\n      'Crafting comprehensive story demos for Daily Standup Summary block',\n    ],\n    blockers: 'Awaiting PR review on PR #884 (Reka roving focus patch) from Elena or David to merge.',\n    reactions: [\n      { emoji: '✨', count: 6, active: true },\n      { emoji: '👍', count: 4, active: false },\n      { emoji: '🚀', count: 1, active: false },\n    ],\n    threadCount: 2,\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-daily-standup-summary, [ui-daily-standup-summary]',\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    UiAvatarComponent,\n    UiAvatarFallbackComponent,\n    UiAvatarImageComponent,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiSeparatorComponent,\n  ],\n  template: `\n    <div data-slot=\"daily-standup-summary\" [class]=\"rootClass\">\n      <!-- Header Section -->\n      <header\n        class=\"bg-card border-border flex flex-col gap-4 rounded-xl border p-5 shadow-xs sm:p-6 lg:flex-row lg:items-center lg:justify-between\"\n      >\n        <div class=\"space-y-1.5\">\n          <div class=\"flex flex-wrap items-center gap-2.5\">\n            <div class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg\">\n              <lucide-icon [img]=\"Bot\" class=\"size-4.5\" aria-hidden=\"true\" />\n            </div>\n            <h1 class=\"text-xl font-bold tracking-tight sm:text-2xl\">Daily Engineering Standup</h1>\n            <span ui-badge variant=\"secondary\" class=\"border-info/20 bg-info/10 text-info text-xs font-medium\">\n              <span class=\"bg-info mr-1.5 inline-block size-1.5 animate-pulse rounded-full\"></span>\n              Synced with #eng-standups\n            </span>\n          </div>\n          <div class=\"text-muted-foreground flex flex-wrap items-center gap-2 text-xs sm:text-sm\">\n            <span class=\"text-foreground flex items-center gap-1 font-medium\">\n              <lucide-icon [img]=\"Calendar\" class=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n              {{ date }}\n            </span>\n            <span class=\"flex items-center gap-1\">\n              <lucide-icon [img]=\"Users\" class=\"size-3.5\" aria-hidden=\"true\" />\n              {{ teamName }} · {{ metrics().totalMembers }} Members\n            </span>\n          </div>\n        </div>\n\n        <div class=\"flex flex-wrap items-center gap-2.5\">\n          <button ui-button variant=\"outline\" size=\"sm\" class=\"h-9 gap-1.5 text-xs font-medium\" (click)=\"copySummary()\">\n            @if (copiedSummary()) {\n              <lucide-icon [img]=\"Check\" class=\"text-success size-3.5\" aria-hidden=\"true\" />\n            } @else {\n              <lucide-icon [img]=\"Copy\" class=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n            }\n            {{ copiedSummary() ? 'Summary Copied' : 'Copy Summary' }}\n          </button>\n          <button\n            ui-button\n            [variant]=\"standupSubmitted() ? 'outline' : 'default'\"\n            size=\"sm\"\n            class=\"h-9 gap-1.5 text-xs font-semibold transition\"\n            (click)=\"standupSubmitted.set(!standupSubmitted())\"\n          >\n            @if (standupSubmitted()) {\n              <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-4\" aria-hidden=\"true\" />\n            } @else {\n              <lucide-icon [img]=\"Send\" class=\"size-4\" aria-hidden=\"true\" />\n            }\n            {{ standupSubmitted() ? 'Standup Submitted' : 'Submit My Standup' }}\n          </button>\n        </div>\n      </header>\n\n      <!-- 4 Squad Pulse Summary Cards -->\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        <div ui-card class=\"border-border shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex items-center justify-between\">\n              <p ui-card-description class=\"text-xs font-medium\">Total Submissions</p>\n              <div class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                <lucide-icon [img]=\"CheckCircle2\" class=\"size-3.5\" aria-hidden=\"true\" />\n              </div>\n            </div>\n            <h3 ui-card-title class=\"mt-1 flex items-baseline gap-2 text-xl font-bold tabular-nums\">\n              {{ metrics().submissionsCount }} / {{ metrics().totalMembers }}\n              <span\n                ui-badge\n                variant=\"secondary\"\n                class=\"border-success/20 bg-success/10 text-success text-success text-xs font-semibold tabular-nums\"\n              >\n                {{ submitPct() }}% In\n              </span>\n            </h3>\n          </div>\n          <div ui-card-content class=\"pt-0\">\n            <div class=\"bg-muted mb-2 h-1.5 w-full overflow-hidden rounded-full\">\n              <div class=\"bg-success h-full transition-[width] duration-500\" [style.width.%]=\"submitPct()\"></div>\n            </div>\n            @if (metrics().pendingMemberName) {\n              <p class=\"text-muted-foreground truncate text-xs\">Pending: {{ metrics().pendingMemberName }}</p>\n            }\n          </div>\n        </div>\n\n        <div ui-card [class]=\"blockerCardClass\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex items-center justify-between\">\n              <p ui-card-description class=\"text-xs font-medium\">Active Blockers</p>\n              <div [class]=\"blockerIconClass\">\n                <lucide-icon [img]=\"AlertTriangle\" class=\"size-3.5\" aria-hidden=\"true\" />\n              </div>\n            </div>\n            <h3 ui-card-title class=\"mt-1 flex items-baseline gap-2 text-xl font-bold tabular-nums\">\n              {{ metrics().activeBlockersCount }}\n              {{ metrics().activeBlockersCount === 1 ? 'Critical' : 'Active' }}\n              @if (metrics().activeBlockersCount > 0) {\n                <span ui-badge variant=\"destructive\" class=\"text-xs font-semibold\">\n                  <span class=\"mr-1 inline-block size-1.5 rounded-full bg-white\"></span>\n                  Action Req.\n                </span>\n              } @else {\n                <span\n                  ui-badge\n                  variant=\"secondary\"\n                  class=\"border-success/20 bg-success/10 text-success text-xs font-semibold\"\n                >\n                  Clear\n                </span>\n              }\n            </h3>\n          </div>\n          <div ui-card-content class=\"pt-0\">\n            <p class=\"text-muted-foreground truncate text-xs\">\n              {{ metrics().blockersHighlight || 'All squad paths currently unblocked' }}\n            </p>\n          </div>\n        </div>\n\n        <div ui-card class=\"border-border shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex items-center justify-between\">\n              <p ui-card-description class=\"text-xs font-medium\">Sprint Goals On Track</p>\n              <div class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                <lucide-icon [img]=\"Target\" class=\"size-3.5\" aria-hidden=\"true\" />\n              </div>\n            </div>\n            <h3 ui-card-title class=\"mt-1 flex items-baseline gap-2 text-xl font-bold tabular-nums\">\n              {{ metrics().goalsOnTrackCount }} / {{ metrics().totalGoals }}\n              <span\n                ui-badge\n                variant=\"secondary\"\n                class=\"bg-primary/10 text-primary border-primary/20 text-xs font-semibold tabular-nums\"\n              >\n                {{ goalsPct() }}% Velocity\n              </span>\n            </h3>\n          </div>\n          <div ui-card-content class=\"pt-0\">\n            <p class=\"text-muted-foreground truncate text-xs\">\n              {{ metrics().sprintName || 'Sprint on schedule' }}\n            </p>\n          </div>\n        </div>\n\n        <div ui-card class=\"border-border shadow-xs\">\n          <div ui-card-header class=\"pb-2\">\n            <div class=\"flex items-center justify-between\">\n              <p ui-card-description class=\"text-xs font-medium\">Planned Deployments</p>\n              <div class=\"bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md\">\n                <lucide-icon [img]=\"Rocket\" class=\"size-3.5\" aria-hidden=\"true\" />\n              </div>\n            </div>\n            <h3 ui-card-title class=\"mt-1 flex items-baseline gap-2 text-xl font-bold tabular-nums\">\n              {{ metrics().deploymentsPlannedCount }} Releases\n              <span ui-badge variant=\"outline\" class=\"text-xs font-semibold\"> Today </span>\n            </h3>\n          </div>\n          <div ui-card-content class=\"pt-0\">\n            <p class=\"text-muted-foreground truncate text-xs\">\n              {{ metrics().deploymentsHighlight || 'Targeting staging & edge production' }}\n            </p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Active Blockers Alert Card (Highlighted Banner) -->\n      @if (alert(); as blocker) {\n        <div\n          class=\"border-destructive/30 bg-destructive/5 dark:bg-destructive/10 relative overflow-hidden rounded-xl border p-5 shadow-xs\"\n        >\n          <div class=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n            <div class=\"flex items-start gap-3.5\">\n              <div\n                class=\"bg-destructive/15 text-destructive mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-lg\"\n              >\n                <lucide-icon [img]=\"ShieldAlert\" class=\"size-5\" aria-hidden=\"true\" />\n              </div>\n              <div class=\"space-y-1.5\">\n                <div class=\"flex flex-wrap items-center gap-2\">\n                  <span ui-badge variant=\"destructive\" class=\"text-xs font-semibold\">\n                    <span class=\"mr-1.5 inline-block size-1.5 animate-pulse rounded-full bg-white\"></span>\n                    Critical Blocker\n                  </span>\n                  <span ui-badge variant=\"outline\" class=\"font-mono text-xs\">\n                    {{ blocker.ticketId }}\n                  </span>\n                  <span class=\"text-muted-foreground text-xs\">\n                    Reported by <strong class=\"text-foreground font-medium\">{{ blocker.authorName }}</strong> ({{\n                      blocker.authorRole\n                    }}) · {{ blocker.reportedAt }}\n                  </span>\n                </div>\n                <h2 class=\"text-foreground text-base leading-snug font-semibold\">\n                  {{ blocker.title }}\n                </h2>\n                <p class=\"text-muted-foreground text-xs sm:text-sm\">\n                  {{ blocker.description }}\n                </p>\n                <div class=\"flex flex-wrap items-center gap-3 pt-1 text-xs\">\n                  <span class=\"text-muted-foreground\"\n                    >Scope: <span class=\"text-foreground font-medium\">{{ blocker.scope }}</span></span\n                  >\n                  <span class=\"text-muted-foreground\"\n                    >Assigned: <span class=\"text-primary font-medium\">{{ blocker.assignedSquad }}</span></span\n                  >\n                </div>\n              </div>\n            </div>\n\n            <div class=\"flex shrink-0 flex-wrap items-center gap-2 md:flex-col md:items-end\">\n              <button\n                ui-button\n                size=\"sm\"\n                [variant]=\"escalatedBlocker() ? 'outline' : 'destructive'\"\n                class=\"h-8 text-xs font-semibold\"\n                (click)=\"escalatedBlocker.set(!escalatedBlocker())\"\n              >\n                @if (escalatedBlocker()) {\n                  <lucide-icon [img]=\"Check\" class=\"text-success mr-1 size-3.5\" />\n                } @else {\n                  <lucide-icon [img]=\"Flame\" class=\"mr-1 size-3.5\" />\n                }\n                {{ escalatedBlocker() ? 'Escalated to SecOps' : 'Escalate Blocker' }}\n              </button>\n              <button ui-button variant=\"outline\" size=\"sm\" class=\"h-8 text-xs font-medium\">\n                <lucide-icon [img]=\"MessageSquare\" class=\"text-muted-foreground mr-1 size-3.5\" />\n                Open Thread (4)\n              </button>\n            </div>\n          </div>\n        </div>\n      }\n\n      <!-- Standup Submissions Section -->\n      <div class=\"space-y-4\">\n        <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n          <div class=\"flex items-center gap-2\">\n            <h2 class=\"text-base font-semibold tracking-tight\">Standup Submissions</h2>\n            <span ui-badge variant=\"secondary\" class=\"font-mono text-xs tabular-nums\">\n              {{ filteredMembers().length }}\n            </span>\n          </div>\n\n          <div class=\"bg-muted border-border flex items-center gap-1 rounded-lg border p-1 text-xs\">\n            <button type=\"button\" [class]=\"filterPillClass('all')\" (click)=\"activeFilter.set('all')\">\n              All ({{ countAll() }})\n            </button>\n            <button type=\"button\" [class]=\"filterPillClass('blocked')\" (click)=\"activeFilter.set('blocked')\">\n              Blocked ({{ countBlocked() }})\n            </button>\n            <button type=\"button\" [class]=\"filterPillClass('needs-review')\" (click)=\"activeFilter.set('needs-review')\">\n              Needs Review ({{ countNeedsReview() }})\n            </button>\n            <button type=\"button\" [class]=\"filterPillClass('on-track')\" (click)=\"activeFilter.set('on-track')\">\n              On Track ({{ countOnTrack() }})\n            </button>\n          </div>\n        </div>\n\n        <div class=\"space-y-4\">\n          @for (member of filteredMembers(); track member.id; let mIdx = $index) {\n            <div ui-card [class]=\"memberCardClass(member.status)\">\n              <div ui-card-header class=\"pb-4\">\n                <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n                  <div class=\"flex items-center gap-3.5\">\n                    <ui-avatar class=\"size-10 border\">\n                      <ui-avatar-image [src]=\"member.avatar\" [alt]=\"member.name\" />\n                      <ui-avatar-fallback class=\"bg-primary/10 text-primary text-xs font-semibold\">{{\n                        member.fallback\n                      }}</ui-avatar-fallback>\n                    </ui-avatar>\n                    <div>\n                      <div class=\"flex flex-wrap items-center gap-2\">\n                        <h3 class=\"text-sm font-semibold tracking-tight\">{{ member.name }}</h3>\n                        <span\n                          ui-badge\n                          [variant]=\"member.status === 'blocked' ? 'destructive' : 'secondary'\"\n                          [class]=\"statusBadgeClass(member.status)\"\n                        >\n                          {{ member.statusLabel }}\n                        </span>\n                      </div>\n                      <p class=\"text-muted-foreground text-xs\">\n                        {{ member.role }} · <span class=\"text-muted-foreground/80\">{{ member.timezone }}</span>\n                      </p>\n                    </div>\n                  </div>\n\n                  <div class=\"flex items-center gap-2 self-start text-xs sm:self-auto\">\n                    <span class=\"text-muted-foreground flex items-center gap-1 tabular-nums\">\n                      <lucide-icon [img]=\"Clock\" class=\"text-muted-foreground size-3\" aria-hidden=\"true\" />\n                      {{ member.submittedAt }}\n                    </span>\n                  </div>\n                </div>\n              </div>\n\n              <div ui-card-content class=\"space-y-4 pt-0\">\n                <ui-separator />\n\n                <div class=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n                  <div class=\"bg-muted/30 border-border/60 space-y-2 rounded-lg border p-3.5\">\n                    <h4\n                      class=\"text-muted-foreground flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\"\n                    >\n                      <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3.5 shrink-0\" aria-hidden=\"true\" />\n                      Yesterday's Output\n                    </h4>\n                    <ul class=\"space-y-1.5 text-xs leading-relaxed\">\n                      @for (item of member.yesterday; track item) {\n                        <li class=\"flex items-start gap-1.5\">\n                          <span class=\"text-success mt-0.5 font-bold\">✓</span>\n                          <span class=\"text-foreground/90\">{{ item }}</span>\n                        </li>\n                      }\n                    </ul>\n                  </div>\n\n                  <div class=\"bg-muted/30 border-border/60 space-y-2 rounded-lg border p-3.5\">\n                    <h4\n                      class=\"text-muted-foreground flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\"\n                    >\n                      <lucide-icon [img]=\"ArrowRight\" class=\"text-primary size-3.5 shrink-0\" aria-hidden=\"true\" />\n                      Today's Focus\n                    </h4>\n                    <ul class=\"space-y-1.5 text-xs leading-relaxed\">\n                      @for (item of member.today; track item) {\n                        <li class=\"flex items-start gap-1.5\">\n                          <span class=\"text-primary mt-0.5 font-bold\">→</span>\n                          <span class=\"text-foreground/90\">{{ item }}</span>\n                        </li>\n                      }\n                    </ul>\n                  </div>\n\n                  <div [class]=\"blockerBoxClass(member)\">\n                    <h4\n                      class=\"text-muted-foreground flex items-center gap-1.5 text-xs font-semibold tracking-wider uppercase\"\n                    >\n                      @if (member.blockers) {\n                        <lucide-icon\n                          [img]=\"AlertTriangle\"\n                          [class]=\"\n                            member.status === 'blocked'\n                              ? 'text-destructive size-3.5 shrink-0'\n                              : 'text-warning size-3.5 shrink-0'\n                          \"\n                          aria-hidden=\"true\"\n                        />\n                      } @else {\n                        <lucide-icon [img]=\"ShieldCheck\" class=\"text-success size-3.5 shrink-0\" aria-hidden=\"true\" />\n                      }\n                      Blockers & Risks\n                    </h4>\n\n                    @if (member.blockers) {\n                      <div class=\"text-xs leading-relaxed\">\n                        <p\n                          [class]=\"\n                            member.status === 'blocked' ? 'text-destructive font-medium' : 'text-warning font-medium'\n                          \"\n                        >\n                          {{ member.blockers }}\n                        </p>\n                      </div>\n                    } @else {\n                      <div class=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                        <span class=\"text-success font-medium\">No blockers</span>\n                        <span>— Clear path to sprint goals</span>\n                      </div>\n                    }\n                  </div>\n                </div>\n\n                <div class=\"border-border/60 flex flex-wrap items-center justify-between gap-3 border-t pt-3\">\n                  <div class=\"flex flex-wrap items-center gap-1.5\">\n                    @for (reaction of member.reactions; track reaction.emoji; let rIdx = $index) {\n                      <button\n                        type=\"button\"\n                        [class]=\"reactionPillClass(reaction.active ?? false)\"\n                        (click)=\"toggleReaction(memberIndexOf(member.id), rIdx)\"\n                      >\n                        <span>{{ reaction.emoji }}</span>\n                        <span class=\"font-semibold tabular-nums\">{{ reaction.count }}</span>\n                      </button>\n                    }\n                    <button\n                      type=\"button\"\n                      class=\"focus-visible:ring-ring text-muted-foreground hover:text-foreground hover:bg-muted flex size-7 items-center justify-center rounded-full border border-dashed transition focus-visible:ring-2 focus-visible:outline-none\"\n                      title=\"Add reaction\"\n                      aria-label=\"Add reaction\"\n                      (click)=\"toggleReaction(memberIndexOf(member.id), 0)\"\n                    >\n                      <lucide-icon [img]=\"Smile\" class=\"size-3.5\" aria-hidden=\"true\" />\n                    </button>\n                  </div>\n\n                  <div class=\"flex flex-wrap items-center gap-2\">\n                    <button\n                      ui-button\n                      variant=\"ghost\"\n                      size=\"sm\"\n                      class=\"text-muted-foreground hover:text-foreground h-8 gap-1.5 text-xs\"\n                    >\n                      <lucide-icon [img]=\"Handshake\" class=\"size-3.5\" aria-hidden=\"true\" />\n                      Offer Help\n                    </button>\n                    <button ui-button variant=\"outline\" size=\"sm\" class=\"h-8 gap-1.5 text-xs font-medium\">\n                      <lucide-icon [img]=\"MessageSquare\" class=\"text-muted-foreground size-3.5\" aria-hidden=\"true\" />\n                      <span>Reply in Thread</span>\n                      @if (member.threadCount) {\n                        <span\n                          class=\"bg-muted text-foreground py-0.2 ml-0.5 rounded px-1.5 font-mono text-xs font-bold tabular-nums\"\n                        >\n                          {{ member.threadCount }}\n                        </span>\n                      }\n                    </button>\n                  </div>\n                </div>\n              </div>\n            </div>\n          }\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiDailyStandupSummaryComponent {\n  protected readonly AlertTriangle = AlertTriangle\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Bot = Bot\n  protected readonly Calendar = Calendar\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Clock = Clock\n  protected readonly Copy = Copy\n  protected readonly Flame = Flame\n  protected readonly Handshake = Handshake\n  protected readonly MessageSquare = MessageSquare\n  protected readonly Rocket = Rocket\n  protected readonly Send = Send\n  protected readonly ShieldAlert = ShieldAlert\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Smile = Smile\n  protected readonly Target = Target\n  protected readonly Users = Users\n\n  @Input() teamName = 'Core Registry Squad'\n  @Input() date = 'Today · Friday, Aug 21, 2026'\n  @Input() set pulseMetrics(v: StandupPulseMetrics | undefined) {\n    if (v) this.pulseMetricsInput.set(v)\n  }\n  @Input() set blockerAlert(v: BlockerAlert | null | undefined) {\n    // `undefined` (absent input) keeps the default; explicit `null` hides the banner.\n    if (v !== undefined) this.blockerAlertInput.set(v)\n  }\n  @Input() set members(v: StandupMember[] | undefined) {\n    if (v) this.localMembers.set(v.map((m) => ({ ...m, reactions: m.reactions.map((r) => ({ ...r })) })))\n  }\n  @Input() set initialFilter(v: 'all' | StandupStatus) {\n    if (v) this.activeFilter.set(v)\n  }\n  @Input('class') className?: string\n\n  private readonly pulseMetricsInput = signal<StandupPulseMetrics | null>(null)\n  private readonly blockerAlertInput = signal<BlockerAlert | null | undefined>(undefined)\n  readonly localMembers = signal<StandupMember[]>(\n    defaultMembers.map((m) => ({ ...m, reactions: m.reactions.map((r) => ({ ...r })) })),\n  )\n\n  readonly activeFilter = signal<'all' | StandupStatus>('all')\n  readonly standupSubmitted = signal(false)\n  readonly copiedSummary = signal(false)\n  readonly escalatedBlocker = signal(false)\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  readonly metrics = computed(() => this.pulseMetricsInput() ?? defaultPulseMetrics)\n  readonly alert = computed(() =>\n    this.blockerAlertInput() !== undefined ? this.blockerAlertInput() : defaultBlockerAlert,\n  )\n\n  readonly filteredMembers = computed(() => {\n    const f = this.activeFilter()\n    if (f === 'all') return this.localMembers()\n    return this.localMembers().filter((m) => m.status === f)\n  })\n\n  readonly countAll = computed(() => this.localMembers().length)\n  readonly countBlocked = computed(() => this.localMembers().filter((m) => m.status === 'blocked').length)\n  readonly countNeedsReview = computed(() => this.localMembers().filter((m) => m.status === 'needs-review').length)\n  readonly countOnTrack = computed(() => this.localMembers().filter((m) => m.status === 'on-track').length)\n\n  readonly submitPct = computed(() => {\n    const m = this.metrics()\n    return Math.round((m.submissionsCount / m.totalMembers) * 100)\n  })\n  readonly goalsPct = computed(() => {\n    const m = this.metrics()\n    return Math.round((m.goalsOnTrackCount / m.totalGoals) * 100)\n  })\n\n  get rootClass(): string {\n    return cn('bg-background text-foreground w-full space-y-6', this.className)\n  }\n\n  get blockerCardClass(): string {\n    return cn(\n      'border-border shadow-xs',\n      this.metrics().activeBlockersCount > 0 && 'border-destructive/40 bg-destructive/5',\n    )\n  }\n\n  get blockerIconClass(): string {\n    // [class] replaces static classes: the base must live here (matches React's cn(base, active)).\n    return cn(\n      'flex size-7 items-center justify-center rounded-md',\n      this.metrics().activeBlockersCount > 0 ? 'bg-destructive/10 text-destructive' : 'bg-success/10 text-success',\n    )\n  }\n\n  filterPillClass(f: 'all' | StandupStatus): string {\n    const active = this.activeFilter() === f\n    const base =\n      'focus-visible:ring-ring min-h-6 rounded-md px-2.5 py-1 font-medium transition focus-visible:ring-2 focus-visible:outline-none'\n    if (!active) {\n      return cn(\n        base,\n        f === 'blocked'\n          ? 'text-muted-foreground hover:text-destructive'\n          : 'text-muted-foreground hover:text-foreground',\n      )\n    }\n    if (f === 'blocked') return cn(base, 'bg-background text-destructive font-semibold shadow-xs')\n    if (f === 'needs-review') return cn(base, 'bg-background text-warning text-warning font-semibold shadow-xs')\n    if (f === 'on-track') return cn(base, 'bg-background text-success text-success font-semibold shadow-xs')\n    return cn(base, 'bg-background text-foreground font-semibold shadow-xs')\n  }\n\n  memberCardClass(status: StandupStatus): string {\n    return cn(\n      'border-border hover:border-border/80 shadow-xs transition',\n      status === 'blocked' && 'border-destructive/30',\n      status === 'needs-review' && 'border-warning/30',\n    )\n  }\n\n  statusBadgeClass(status: StandupStatus): string {\n    return cn(\n      'text-xs font-medium',\n      status === 'on-track' && 'border-success/20 bg-success/10 text-success',\n      status === 'needs-review' && 'border-warning/20 bg-warning/10 text-warning',\n    )\n  }\n\n  blockerBoxClass(member: StandupMember): string {\n    return cn(\n      'space-y-2 rounded-lg border p-3.5',\n      member.blockers\n        ? member.status === 'blocked'\n          ? 'border-destructive/30 bg-destructive/5 dark:bg-destructive/10'\n          : 'border-warning/30 bg-warning/5'\n        : 'border-border/60 bg-muted/30',\n    )\n  }\n\n  reactionPillClass(active: boolean): string {\n    return cn(\n      'focus-visible:ring-ring flex min-h-6 items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium transition focus-visible:ring-2 focus-visible:outline-none',\n      active\n        ? 'bg-primary/10 border-primary/40 text-primary'\n        : 'bg-muted/40 border-border text-muted-foreground hover:bg-muted hover:text-foreground',\n    )\n  }\n\n  memberIndexOf(id: string): number {\n    return this.localMembers().findIndex((m) => m.id === id)\n  }\n\n  toggleReaction(memberIndex: number, reactionIndex: number): void {\n    this.localMembers.update((prev) => {\n      const next = [...prev]\n      const member = next[memberIndex]\n      if (!member) return prev\n      const reactions = [...member.reactions]\n      const r = reactions[reactionIndex]\n      if (!r) return prev\n      reactions[reactionIndex] = r.active\n        ? { ...r, count: r.count - 1, active: false }\n        : { ...r, count: r.count + 1, active: true }\n      next[memberIndex] = { ...member, reactions }\n      return next\n    })\n  }\n\n  async copySummary(): Promise<void> {\n    try {\n      const m = this.metrics()\n      const text = `${this.teamName} Standup Summary — ${this.date}\\n\\nSubmissions: ${m.submissionsCount}/${m.totalMembers} (${Math.round((m.submissionsCount / m.totalMembers) * 100)}%)\\nActive Blockers: ${m.activeBlockersCount}\\nGoals on Track: ${m.goalsOnTrackCount}/${m.totalGoals}\\nPlanned Releases: ${m.deploymentsPlannedCount}`\n      await navigator.clipboard.writeText(text)\n      this.copiedSummary.set(true)\n      clearTimeout(this.copyTimer)\n      this.copyTimer = setTimeout(() => this.copiedSummary.set(false), 2000)\n    } catch {\n      // Clipboard unavailable in some contexts.\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/daily-standup-summary/daily-standup-summary.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/daily-standup-summary/index.ts",
      "content": "export {\n  UiDailyStandupSummaryComponent,\n  type StandupStatus,\n  type StandupReaction,\n  type StandupMember,\n  type BlockerAlert,\n  type StandupPulseMetrics,\n} from './daily-standup-summary.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/daily-standup-summary/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/avatar.json",
    "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/separator.json"
  ],
  "description": "Slack and Geekbot style async engineering daily standup summary with squad pulse cards, critical blocker alert callout, structured yesterday/today/blockers submission entries, reaction counts, and thread actions.",
  "categories": [
    "productivity",
    "collaboration",
    "dashboard",
    "app"
  ]
}