{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "course-curriculum-outline",
  "title": "Course Curriculum Outline",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/course-curriculum-outline/course-curriculum-outline.component.ts",
      "content": "// LMS video-course syllabus: hero header with course metadata, instructor profile,\n// rating, progress bar and actions, collapsible module accordions with lesson\n// durations, type badges and completion checks, plus a sidebar with a verifiable\n// certificate preview, downloadable resources and community access.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport {\n  Award,\n  Check,\n  CheckCircle2,\n  Circle,\n  Clock,\n  Download,\n  ExternalLink,\n  FileCode,\n  FileQuestion,\n  FileText,\n  FlaskConical,\n  GraduationCap,\n  Lock,\n  LucideAngularModule,\n  MessageSquare,\n  PenTool,\n  Play,\n  PlayCircle,\n  ShieldCheck,\n  Star,\n  Users,\n  Video,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport {\n  UiAccordionComponent,\n  UiAccordionContentComponent,\n  UiAccordionItemComponent,\n  UiAccordionTriggerComponent,\n} from '@/ui/accordion/accordion.component'\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  UiCardFooterComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiProgressComponent } from '@/ui/progress/progress.component'\n\nexport interface Lesson {\n  id: string\n  title: string\n  duration: string\n  type: 'Video' | 'Interactive Lab' | 'Quiz'\n  status: 'completed' | 'in-progress' | 'not-started' | 'locked'\n}\n\nexport interface Module {\n  id: string\n  title: string\n  duration: string\n  lessonsCount: string\n  completedCount: number\n  totalCount: number\n  status: 'completed' | 'in-progress' | 'locked'\n  lessons: Lesson[]\n}\n\ninterface CourseResource {\n  id: string\n  title: string\n  meta: string\n  type: 'figma' | 'repo' | 'pdf'\n}\n\nexport const defaultModules: Module[] = [\n  {\n    id: 'module-1',\n    title: 'Module 1: Design Tokens & OKLCH Architecture',\n    duration: '1h 45m',\n    lessonsCount: '4 lessons',\n    completedCount: 4,\n    totalCount: 4,\n    status: 'completed',\n    lessons: [\n      {\n        id: 'm1-l1',\n        title: 'Introduction to OKLCH & Gamut Mapping',\n        duration: '18m',\n        type: 'Video',\n        status: 'completed',\n      },\n      {\n        id: 'm1-l2',\n        title: 'Configuring Semantic Tokens in Tailwind CSS v4',\n        duration: '26m',\n        type: 'Video',\n        status: 'completed',\n      },\n      {\n        id: 'm1-l3',\n        title: 'Lab: Building an Automated Contrast Checker',\n        duration: '35m',\n        type: 'Interactive Lab',\n        status: 'completed',\n      },\n      {\n        id: 'm1-l4',\n        title: 'Quiz: Token Architecture & Dark Mode Strategy',\n        duration: '26m',\n        type: 'Quiz',\n        status: 'completed',\n      },\n    ],\n  },\n  {\n    id: 'module-2',\n    title: 'Module 2: Polymorphic Primitives & Headless Reka UI',\n    duration: '3h 10m',\n    lessonsCount: '6 lessons',\n    completedCount: 3,\n    totalCount: 6,\n    status: 'in-progress',\n    lessons: [\n      {\n        id: 'm2-l1',\n        title: 'Anatomy of Headless Primitives with Reka UI & Radix',\n        duration: '24m',\n        type: 'Video',\n        status: 'completed',\n      },\n      {\n        id: 'm2-l2',\n        title: 'Building Polymorphic Button & Slot Mechanics',\n        duration: '32m',\n        type: 'Video',\n        status: 'completed',\n      },\n      {\n        id: 'm2-l3',\n        title: 'Lab: Compound Component Patterns with Provide/Inject',\n        duration: '40m',\n        type: 'Interactive Lab',\n        status: 'completed',\n      },\n      {\n        id: 'm2-l4',\n        title: 'Accessible Dialog, Popover & Focus Trapping',\n        duration: '36m',\n        type: 'Video',\n        status: 'in-progress',\n      },\n      {\n        id: 'm2-l5',\n        title: 'Virtualization for High-Density Data Grids',\n        duration: '38m',\n        type: 'Video',\n        status: 'not-started',\n      },\n      {\n        id: 'm2-l6',\n        title: 'Quiz: Accessibility Tree & ARIA Roles',\n        duration: '20m',\n        type: 'Quiz',\n        status: 'not-started',\n      },\n    ],\n  },\n  {\n    id: 'module-3',\n    title: 'Module 3: Micro-Interactions & Spring Physics',\n    duration: '4h 50m',\n    lessonsCount: '8 lessons',\n    completedCount: 0,\n    totalCount: 8,\n    status: 'locked',\n    lessons: [\n      {\n        id: 'm3-l1',\n        title: 'Physics-Based Animation Principles with Spring Physics',\n        duration: '28m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm3-l2',\n        title: 'Gesture Interactions & Drag-and-Drop Primitives',\n        duration: '35m',\n        type: 'Interactive Lab',\n        status: 'locked',\n      },\n      {\n        id: 'm3-l3',\n        title: 'Layout Animations and Shared Element Transitions',\n        duration: '42m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm3-l4',\n        title: 'Haptic Feedback & Tactile States in Web Interfaces',\n        duration: '25m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm3-l5',\n        title: 'Optimizing 60fps / 120fps Rendering Pipelines',\n        duration: '45m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm3-l6',\n        title: 'Lab: Crafting a Fluid Floating Command Palette',\n        duration: '50m',\n        type: 'Interactive Lab',\n        status: 'locked',\n      },\n      { id: 'm3-l7', title: 'Sound Design & Audio Micro-Feedback', duration: '25m', type: 'Video', status: 'locked' },\n      {\n        id: 'm3-l8',\n        title: 'Quiz: Motion Reduction & Animation Performance',\n        duration: '20m',\n        type: 'Quiz',\n        status: 'locked',\n      },\n    ],\n  },\n  {\n    id: 'module-4',\n    title: 'Module 4: Monorepo Architecture & CI Distribution',\n    duration: '4h 45m',\n    lessonsCount: '6 lessons',\n    completedCount: 0,\n    totalCount: 6,\n    status: 'locked',\n    lessons: [\n      {\n        id: 'm4-l1',\n        title: 'Turborepo & pnpm Workspaces Setup from Scratch',\n        duration: '35m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm4-l2',\n        title: 'Dual-Framework Export Pipelines (Vue 3 + React 19)',\n        duration: '45m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm4-l3',\n        title: 'Registry Distribution Schema & JSON Manifest Generator',\n        duration: '50m',\n        type: 'Video',\n        status: 'locked',\n      },\n      {\n        id: 'm4-l4',\n        title: 'Lab: Custom CLI Tooling with npx shadcn add',\n        duration: '55m',\n        type: 'Interactive Lab',\n        status: 'locked',\n      },\n      {\n        id: 'm4-l5',\n        title: 'Automated Visual Regression CI with Playwright',\n        duration: '40m',\n        type: 'Interactive Lab',\n        status: 'locked',\n      },\n      {\n        id: 'm4-l6',\n        title: 'Capstone Project: Publishing Your Own Component Registry',\n        duration: '60m',\n        type: 'Interactive Lab',\n        status: 'locked',\n      },\n    ],\n  },\n]\n\nconst resources: CourseResource[] = [\n  { id: 'res-figma', title: 'Figma Design System Kit v4.2', meta: '.fig · 48.2 MB', type: 'figma' },\n  { id: 'res-repo', title: 'Course Starter Monorepo Template', meta: 'GitHub Template · Public', type: 'repo' },\n  { id: 'res-tokens', title: 'OKLCH & Color Tokens Cheatsheet', meta: 'PDF Guide · 2.4 MB', type: 'pdf' },\n  { id: 'res-wcag', title: 'WCAG 2.2 AA Contrast Matrix', meta: 'PDF Reference · 1.8 MB', type: 'pdf' },\n]\n\nexport const totalLessonsCount = 24\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-course-curriculum-outline, [ui-course-curriculum-outline]',\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    UiAccordionComponent,\n    UiAccordionContentComponent,\n    UiAccordionItemComponent,\n    UiAccordionTriggerComponent,\n    UiAvatarComponent,\n    UiAvatarFallbackComponent,\n    UiAvatarImageComponent,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardFooterComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiProgressComponent,\n  ],\n  template: `\n    <div data-slot=\"course-curriculum-outline\" [class]=\"rootClass\">\n      <!-- Course Hero Header -->\n      <div ui-card class=\"border-border bg-card shadow-xs\">\n        <div ui-card-header class=\"space-y-4\">\n          <div class=\"flex flex-wrap items-center justify-between gap-3\">\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <span ui-badge variant=\"secondary\" class=\"font-medium\">Advanced · 14.5 Total Hours</span>\n              <span ui-badge variant=\"outline\" class=\"text-muted-foreground\">Design Engineering</span>\n            </div>\n            <div class=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n              <div class=\"text-warning flex items-center\">\n                <lucide-icon [img]=\"Star\" class=\"size-3.5 fill-current\" />\n                <span class=\"text-foreground ml-1 font-semibold\">4.9</span>\n              </div>\n              <span>·</span>\n              <span class=\"tabular-nums\">(1,840 students)</span>\n            </div>\n          </div>\n\n          <div class=\"space-y-2\">\n            <h2 ui-card-title class=\"text-2xl font-bold tracking-tight sm:text-3xl\">\n              Full-Stack Design Systems with Vue & React\n            </h2>\n            <p ui-card-description class=\"text-sm\">\n              Master enterprise-grade UI components, OKLCH color spaces, headless architecture with Reka UI, fluid\n              spring physics, and monorepo package distribution.\n            </p>\n          </div>\n\n          <div class=\"flex flex-wrap items-center justify-between gap-4 pt-1\">\n            <div class=\"flex items-center gap-3\">\n              <ui-avatar class=\"border-border size-10 border\">\n                <ui-avatar-image\n                  src=\"https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=96&h=96&fit=crop&crop=faces\"\n                  alt=\"Marcus Vance\"\n                />\n                <ui-avatar-fallback>MV</ui-avatar-fallback>\n              </ui-avatar>\n              <div>\n                <p class=\"text-sm leading-none font-medium\">Marcus Vance</p>\n                <p class=\"text-muted-foreground mt-1 text-xs\">Principal Design Engineer</p>\n              </div>\n            </div>\n\n            <div class=\"flex flex-wrap items-center gap-2.5\">\n              @if (!isFullyCompleted()) {\n                <button ui-button class=\"gap-2 shadow-xs\">\n                  <lucide-icon [img]=\"Play\" class=\"size-4 fill-current\" />\n                  Resume Learning\n                </button>\n              } @else {\n                <button ui-button aria-label=\"Download attachment\" class=\"gap-2 shadow-xs\">\n                  <lucide-icon [img]=\"Award\" class=\"size-4\" />\n                  Download Certificate\n                </button>\n              }\n              <button ui-button aria-label=\"Download attachment\" variant=\"outline\" class=\"gap-2\">\n                <lucide-icon [img]=\"Download\" class=\"size-4\" />\n                Download Resources\n              </button>\n            </div>\n          </div>\n        </div>\n\n        <div ui-card-content class=\"pt-0\">\n          <div class=\"border-border/60 bg-muted/40 space-y-2 rounded-lg border p-4\">\n            <div class=\"flex items-center justify-between text-xs\">\n              <span class=\"text-foreground font-medium\">\n                <span class=\"tabular-nums\">{{ completedLessonsCount() }} of {{ totalLessonsCount }}</span> lessons\n                completed\n              </span>\n              <span class=\"text-muted-foreground font-medium tabular-nums\">{{ progressPercent() }}%</span>\n            </div>\n            <div ui-progress [value]=\"progressPercent()\"></div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Main Content & Sidebar Grid -->\n      <div class=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n        <!-- Left Column: Modular Curriculum Accordions -->\n        <div class=\"space-y-4 lg:col-span-2\">\n          <div class=\"flex items-center justify-between px-1\">\n            <div>\n              <h2 class=\"text-lg font-semibold tracking-tight\">Course Curriculum</h2>\n              <p class=\"text-muted-foreground text-xs\">4 modular sections · 24 total lessons & interactive labs</p>\n            </div>\n            <div class=\"text-muted-foreground text-xs tabular-nums\">\n              <span class=\"text-foreground font-medium\">{{ completedLessonsCount() }}/{{ totalLessonsCount }}</span>\n              Completed\n            </div>\n          </div>\n\n          <ui-accordion type=\"multiple\" [defaultValue]=\"openModules\" variant=\"separated\">\n            @for (module of modules(); track module.id) {\n              <ui-accordion-item [value]=\"module.id\">\n                <button ui-accordion-trigger class=\"hover:no-underline\">\n                  <div class=\"flex flex-1 items-center justify-between gap-3 pr-2 text-left\">\n                    <div class=\"flex min-w-0 items-center gap-3\">\n                      @if (module.status === 'completed') {\n                        <span\n                          class=\"border-success/30 bg-success/15 text-success flex size-7 shrink-0 items-center justify-center rounded-full border shadow-xs\"\n                        >\n                          <lucide-icon [img]=\"Check\" class=\"size-3.5\" />\n                        </span>\n                      } @else if (module.status === 'in-progress') {\n                        <span\n                          class=\"border-primary/20 bg-primary/10 text-primary flex size-7 shrink-0 items-center justify-center rounded-full border\"\n                        >\n                          <lucide-icon [img]=\"Play\" class=\"size-3.5 fill-current\" />\n                        </span>\n                      } @else {\n                        <span\n                          class=\"border-border bg-muted text-muted-foreground flex size-7 shrink-0 items-center justify-center rounded-full border\"\n                        >\n                          <lucide-icon [img]=\"Lock\" class=\"size-3.5\" />\n                        </span>\n                      }\n                      <div class=\"min-w-0\">\n                        <p class=\"text-foreground truncate text-sm font-semibold\">{{ module.title }}</p>\n                        <p class=\"text-muted-foreground mt-0.5 text-xs tabular-nums\">\n                          {{ module.lessonsCount }} · {{ module.duration }} ·\n                          @if (module.status === 'completed') {\n                            <span class=\"text-success font-medium\">100% completed</span>\n                          } @else if (module.status === 'in-progress') {\n                            <span class=\"text-foreground font-medium\">\n                              {{ module.completedCount }}/{{ module.totalCount }} completed\n                            </span>\n                          } @else {\n                            <span class=\"text-muted-foreground\">Locked</span>\n                          }\n                        </p>\n                      </div>\n                    </div>\n\n                    <div class=\"hidden shrink-0 items-center gap-2 sm:flex\">\n                      @if (module.status === 'completed') {\n                        <span ui-badge variant=\"success\" class=\"gap-1 text-xs\">\n                          <lucide-icon [img]=\"Check\" class=\"size-3\" /> Completed\n                        </span>\n                      } @else if (module.status === 'in-progress') {\n                        <span ui-badge variant=\"secondary\" class=\"text-xs\">\n                          In Progress ({{ module.completedCount }}/{{ module.totalCount }})\n                        </span>\n                      } @else {\n                        <span ui-badge variant=\"outline\" class=\"text-muted-foreground gap-1 text-xs\">\n                          <lucide-icon [img]=\"Lock\" class=\"size-3\" /> Locked\n                        </span>\n                      }\n                    </div>\n                  </div>\n                </button>\n\n                <ui-accordion-content>\n                  <div class=\"border-border divide-border divide-y border-t\">\n                    @for (lesson of module.lessons; track lesson.id) {\n                      <div\n                        class=\"group hover:bg-muted/40 flex items-center justify-between gap-3 px-2 py-3 transition-colors first:pt-3 last:pb-1 sm:px-3\"\n                      >\n                        <div class=\"flex min-w-0 items-center gap-3\">\n                          <div class=\"flex shrink-0 items-center justify-center\">\n                            @if (lesson.status === 'completed') {\n                              <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-4\" />\n                            } @else if (lesson.status === 'in-progress') {\n                              <lucide-icon [img]=\"PlayCircle\" class=\"text-primary size-4 animate-pulse\" />\n                            } @else if (lesson.status === 'locked') {\n                              <lucide-icon [img]=\"Lock\" class=\"text-muted-foreground/50 size-4\" />\n                            } @else {\n                              <lucide-icon [img]=\"Circle\" class=\"text-muted-foreground/60 size-4\" />\n                            }\n                          </div>\n\n                          <div class=\"min-w-0\">\n                            <p [class]=\"lessonTitleClass(lesson)\">{{ lesson.title }}</p>\n                          </div>\n                        </div>\n\n                        <div class=\"flex shrink-0 items-center gap-2\">\n                          @if (lesson.type === 'Interactive Lab') {\n                            <span ui-badge variant=\"secondary\" class=\"gap-1 text-xs\">\n                              <lucide-icon [img]=\"FlaskConical\" class=\"size-3\" />\n                              <span class=\"hidden sm:inline\">Interactive Lab</span>\n                              <span class=\"sm:hidden\">Lab</span>\n                            </span>\n                          } @else if (lesson.type === 'Quiz') {\n                            <span ui-badge variant=\"outline\" class=\"gap-1 text-xs\">\n                              <lucide-icon [img]=\"FileQuestion\" class=\"size-3\" />\n                              Quiz\n                            </span>\n                          } @else {\n                            <span ui-badge variant=\"outline\" class=\"gap-1 text-xs\">\n                              <lucide-icon [img]=\"Video\" class=\"size-3\" />\n                              Video\n                            </span>\n                          }\n\n                          <span class=\"text-muted-foreground min-w-[32px] text-right font-mono text-xs tabular-nums\">\n                            {{ lesson.duration }}\n                          </span>\n\n                          <div class=\"hidden sm:block\">\n                            @if (lesson.status === 'in-progress') {\n                              <button ui-button size=\"sm\" class=\"h-7 gap-1 px-2.5 text-xs\">\n                                <lucide-icon [img]=\"Play\" class=\"size-3 fill-current\" /> Resume\n                              </button>\n                            } @else if (lesson.status === 'completed') {\n                              <button\n                                ui-button\n                                variant=\"ghost\"\n                                size=\"sm\"\n                                class=\"text-muted-foreground hover:text-foreground h-7 px-2 text-xs\"\n                              >\n                                Review\n                              </button>\n                            } @else if (lesson.status === 'not-started') {\n                              <button ui-button variant=\"outline\" size=\"sm\" class=\"h-7 px-2 text-xs\">Start</button>\n                            } @else {\n                              <span class=\"text-muted-foreground/50 px-2 text-xs\">Locked</span>\n                            }\n                          </div>\n                        </div>\n                      </div>\n                    }\n                  </div>\n                </ui-accordion-content>\n              </ui-accordion-item>\n            }\n          </ui-accordion>\n        </div>\n\n        <!-- Right Column: Certificate & Resources Sidebar -->\n        <div class=\"space-y-6\">\n          <!-- Certificate Card -->\n          <div ui-card>\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center gap-2\">\n                <lucide-icon [img]=\"GraduationCap\" class=\"text-primary size-5\" />\n                <h3 ui-card-title class=\"text-base\">Certificate of Completion</h3>\n              </div>\n              <p ui-card-description class=\"text-xs\">Accredited credential upon 100% course and lab completion.</p>\n            </div>\n\n            <div ui-card-content class=\"space-y-4\">\n              <!-- Cert preview container -->\n              <div\n                class=\"border-border/80 from-muted/50 to-muted/20 relative space-y-3 overflow-hidden rounded-lg border bg-gradient-to-b p-4 text-center\"\n              >\n                <div class=\"relative z-10 space-y-2\">\n                  <div [class]=\"certBadgeClass\">\n                    <lucide-icon [img]=\"Award\" class=\"size-6\" />\n                  </div>\n                  <div>\n                    <p class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                      Verified Credential\n                    </p>\n                    <p class=\"text-foreground mt-0.5 text-sm font-bold\">Full-Stack Design Systems</p>\n                    <p class=\"text-muted-foreground text-xs\">Marcus Vance · UIPKGE Academy</p>\n                  </div>\n                  <div class=\"pt-1\">\n                    <span\n                      class=\"border-border bg-background/80 text-muted-foreground inline-flex items-center gap-1 rounded border px-2 py-0.5 font-mono text-xs\"\n                    >\n                      <lucide-icon [img]=\"ShieldCheck\" class=\"text-primary size-3\" /> CERT-8841-FS\n                    </span>\n                  </div>\n                </div>\n              </div>\n\n              <!-- Progress info -->\n              <div class=\"space-y-1.5\">\n                <div class=\"flex items-center justify-between text-xs\">\n                  <span class=\"text-muted-foreground\">Graduation Status</span>\n                  <span class=\"text-foreground font-medium tabular-nums\">\n                    {{ completedLessonsCount() }}/{{ totalLessonsCount }} Lessons\n                  </span>\n                </div>\n                <div ui-progress [value]=\"progressPercent()\"></div>\n                <p class=\"text-muted-foreground pt-1 text-xs\">\n                  @if (isFullyCompleted()) {\n                    <span class=\"text-success font-medium\">\n                      All requirements satisfied! Your certificate is ready to download and share.\n                    </span>\n                  } @else {\n                    <span>\n                      Complete the remaining {{ totalLessonsCount - completedLessonsCount() }} lessons and labs to\n                      unlock.\n                    </span>\n                  }\n                </p>\n              </div>\n            </div>\n\n            <div ui-card-footer>\n              @if (isFullyCompleted()) {\n                <button ui-button aria-label=\"Download attachment\" class=\"w-full gap-1.5\" size=\"sm\">\n                  <lucide-icon [img]=\"Download\" class=\"size-4\" /> Download PDF Certificate\n                </button>\n              } @else {\n                <button ui-button variant=\"outline\" size=\"sm\" class=\"w-full gap-1.5\" disabled>\n                  <lucide-icon [img]=\"Lock\" class=\"size-4\" /> Locked (Complete Course)\n                </button>\n              }\n            </div>\n          </div>\n\n          <!-- Course Resources Card -->\n          <div ui-card>\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center gap-2\">\n                <lucide-icon [img]=\"FileCode\" class=\"text-primary size-5\" />\n                <h3 ui-card-title class=\"text-base\">Course Resources</h3>\n              </div>\n              <p ui-card-description class=\"text-xs\">Downloadable starter kits, Figma files, and spec guides.</p>\n            </div>\n\n            <div ui-card-content class=\"space-y-2.5\">\n              @for (res of courseResources; track res.id) {\n                <div\n                  class=\"border-border hover:bg-muted/40 flex items-center justify-between gap-3 rounded-md border p-2.5 transition-colors\"\n                >\n                  <div class=\"flex min-w-0 items-center gap-2.5\">\n                    <span\n                      class=\"bg-muted text-muted-foreground flex size-8 shrink-0 items-center justify-center rounded-md\"\n                    >\n                      @if (res.type === 'repo') {\n                        <lucide-icon [img]=\"FileCode\" class=\"size-4\" />\n                      } @else if (res.type === 'figma') {\n                        <lucide-icon [img]=\"PenTool\" class=\"size-4\" />\n                      } @else {\n                        <lucide-icon [img]=\"FileText\" class=\"size-4\" />\n                      }\n                    </span>\n                    <div class=\"min-w-0\">\n                      <p class=\"text-foreground truncate text-xs font-medium\">{{ res.title }}</p>\n                      <p class=\"text-muted-foreground text-xs\">{{ res.meta }}</p>\n                    </div>\n                  </div>\n\n                  <button\n                    ui-button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    class=\"text-muted-foreground hover:text-foreground size-8 shrink-0\"\n                  >\n                    @if (res.type === 'repo') {\n                      <lucide-icon [img]=\"ExternalLink\" class=\"size-4\" />\n                    } @else {\n                      <lucide-icon [img]=\"Download\" class=\"size-4\" />\n                    }\n                    <span class=\"sr-only\">Download {{ res.title }}</span>\n                  </button>\n                </div>\n              }\n            </div>\n          </div>\n\n          <!-- Community & Mentorship Card -->\n          <div ui-card>\n            <div ui-card-header class=\"pb-3\">\n              <div class=\"flex items-center gap-2\">\n                <lucide-icon [img]=\"Users\" class=\"text-primary size-5\" />\n                <h3 ui-card-title class=\"text-base\">Student Community</h3>\n              </div>\n              <p ui-card-description class=\"text-xs\">\n                Connect with peers and get code reviews from design engineering mentors.\n              </p>\n            </div>\n\n            <div ui-card-content class=\"text-muted-foreground space-y-2.5 text-xs\">\n              <div class=\"flex items-center gap-2\">\n                <span class=\"bg-success size-2 rounded-full\"></span>\n                <span><strong class=\"text-foreground\">1,420 students online</strong> in Discord</span>\n              </div>\n              <div class=\"flex items-center gap-2\">\n                <lucide-icon [img]=\"Clock\" class=\"text-muted-foreground size-3.5\" />\n                <span>Weekly live Q&A: <strong class=\"text-foreground\">Thursdays @ 5:00 PM UTC</strong></span>\n              </div>\n            </div>\n\n            <div ui-card-footer>\n              <button ui-button variant=\"outline\" size=\"sm\" class=\"w-full gap-1.5\">\n                <lucide-icon [img]=\"MessageSquare\" class=\"size-4\" /> Join Discord Community\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiCourseCurriculumOutlineComponent {\n  protected readonly Award = Award\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Circle = Circle\n  protected readonly Clock = Clock\n  protected readonly Download = Download\n  protected readonly ExternalLink = ExternalLink\n  protected readonly FileCode = FileCode\n  protected readonly FileQuestion = FileQuestion\n  protected readonly FileText = FileText\n  protected readonly FlaskConical = FlaskConical\n  protected readonly GraduationCap = GraduationCap\n  protected readonly Lock = Lock\n  protected readonly MessageSquare = MessageSquare\n  protected readonly PenTool = PenTool\n  protected readonly Play = Play\n  protected readonly PlayCircle = PlayCircle\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Star = Star\n  protected readonly Users = Users\n  protected readonly Video = Video\n\n  protected readonly openModules = ['module-1', 'module-2']\n  protected readonly courseResources = resources\n  protected readonly totalLessonsCount = totalLessonsCount\n\n  /** Seed completed state for all lessons to preview the verified certificate state. */\n  @Input() set initialComplete(v: boolean) {\n    this.initialCompleteSig.set(!!v)\n  }\n  @Input('class') className?: string\n\n  private readonly initialCompleteSig = signal(false)\n\n  readonly modules = computed<Module[]>(() => {\n    if (!this.initialCompleteSig()) return defaultModules\n    return defaultModules.map((m) => ({\n      ...m,\n      status: 'completed' as const,\n      completedCount: m.totalCount,\n      lessons: m.lessons.map((l) => ({ ...l, status: 'completed' as const })),\n    }))\n  })\n\n  readonly completedLessonsCount = computed(() => (this.initialCompleteSig() ? 24 : 8))\n  readonly progressPercent = computed(() => Math.round((this.completedLessonsCount() / totalLessonsCount) * 100))\n  readonly isFullyCompleted = computed(() => this.completedLessonsCount() === totalLessonsCount)\n\n  get rootClass(): string {\n    return cn('text-foreground w-full space-y-6', this.className)\n  }\n\n  get certBadgeClass(): string {\n    return cn(\n      'mx-auto flex size-12 items-center justify-center rounded-full border shadow-xs',\n      this.isFullyCompleted()\n        ? 'border-success/30 bg-success/15 text-success'\n        : 'border-primary/30 bg-primary/10 text-primary',\n    )\n  }\n\n  lessonTitleClass(lesson: Lesson): string {\n    return cn(\n      'truncate text-sm font-medium transition-colors',\n      lesson.status === 'locked' ? 'text-muted-foreground' : 'text-foreground group-hover:text-primary',\n    )\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/course-curriculum-outline/course-curriculum-outline.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/course-curriculum-outline/index.ts",
      "content": "export {\n  UiCourseCurriculumOutlineComponent,\n  defaultModules,\n  totalLessonsCount,\n  type Lesson,\n  type Module,\n} from './course-curriculum-outline.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/course-curriculum-outline/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/accordion.json",
    "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/progress.json"
  ],
  "description": "LMS and video course syllabus block: hero header with course metadata, instructor profile, rating, progress bar, and action buttons, collapsible modular section accordions with lesson durations, type badges, and completion checks, plus a sidebar with verifiable certificate preview, downloadable course resources, and student community access.",
  "categories": [
    "education",
    "app"
  ]
}