Menu

Change language

GitHub repo

Nda Agreement Generator

blocklegal

Interactive Non-Disclosure Agreement (NDA) generator and contract customizer with bilateral/unilateral modes, customizable legal covenants, real-time contract parchment preview, and e-signature execution workflow.

Installation

$npx uipkge-ng@latest add nda-agreement-generator
Manifest:https://uipkge.dev/r/angular/nda-agreement-generator.jsonInstalls to:src/app/components/blocks/nda-agreement-generator/

Variants

Loading interactive previews…

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

JurisdictionInfo
interface JurisdictionInfo {
  name: string
  statute: string
  venue: string
  tag: string
}

Files installed (2)

  • src/app/components/blocks/nda-agreement-generator/nda-agreement-generator.component.ts59.6 kB
    // Interactive Non-Disclosure Agreement (NDA) generator and contract customizer with
    // bilateral/unilateral modes, customizable legal covenants, a live parchment preview,
    // and an e-signature execution workflow. Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'
    import {
      AlertCircle,
      BadgeCheck,
      Check,
      CheckCircle2,
      Download,
      FileCheck,
      Gavel,
      Lock,
      LucideAngularModule,
      PenTool,
      Printer,
      RotateCcw,
      Scale,
      ShieldCheck,
      Users,
    } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiButtonComponent } from '@/ui/button/button.component'
    import {
      UiCardComponent,
      UiCardContentComponent,
      UiCardDescriptionComponent,
      UiCardHeaderComponent,
      UiCardTitleComponent,
    } from '@/ui/card/card.component'
    import { UiInputComponent } from '@/ui/input/input.component'
    import {
      UiSelectComponent,
      UiSelectContentComponent,
      UiSelectItemComponent,
      UiSelectTriggerComponent,
      UiSelectValueComponent,
    } from '@/ui/select/select.component'
    import { UiSeparatorComponent } from '@/ui/separator/separator.component'
    import { UiSwitchComponent } from '@/ui/switch/switch.component'
    
    export type AgreementType = 'mutual' | 'unilateral'
    export type TermOption = '2 Years' | '3 Years' | '5 Years' | 'Perpetual for Trade Secrets'
    export type JurisdictionOption = 'delaware' | 'california' | 'newyork' | 'england' | 'singapore'
    export type SignatureFont = 'serif' | 'script' | 'sans'
    
    interface JurisdictionInfo {
      name: string
      statute: string
      venue: string
      tag: string
    }
    
    const jurisdictionMap: Record<JurisdictionOption, JurisdictionInfo> = {
      delaware: {
        name: 'State of Delaware, United States',
        statute: 'General Corporation Law of Delaware (DGCL) & Court of Chancery',
        venue: 'Wilmington, Delaware, USA',
        tag: 'US-DE',
      },
      california: {
        name: 'State of California, United States',
        statute: 'California Uniform Trade Secrets Act (Cal. Civ. Code § 3426)',
        venue: 'San Francisco, California, USA',
        tag: 'US-CA',
      },
      newyork: {
        name: 'State of New York, United States',
        statute: 'New York Commercial Division Jurisprudence & General Obligations Law',
        venue: 'New York, New York, USA',
        tag: 'US-NY',
      },
      england: {
        name: 'England & Wales, United Kingdom',
        statute: 'Laws of England and Wales & High Court of Justice (Commercial Court)',
        venue: 'London, United Kingdom',
        tag: 'UK-EW',
      },
      singapore: {
        name: 'Republic of Singapore (SIAC)',
        statute: 'International Arbitration Act & Singapore International Arbitration Centre',
        venue: 'Singapore (SIAC Rules)',
        tag: 'SG-SIAC',
      },
    }
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-nda-agreement-generator, [ui-nda-agreement-generator]',
      standalone: true,
      // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.
      host: { '[attr.class]': '"contents"' },
      imports: [
        LucideAngularModule,
        UiBadgeComponent,
        UiButtonComponent,
        UiCardComponent,
        UiCardContentComponent,
        UiCardDescriptionComponent,
        UiCardHeaderComponent,
        UiCardTitleComponent,
        UiInputComponent,
        UiSelectComponent,
        UiSelectContentComponent,
        UiSelectItemComponent,
        UiSelectTriggerComponent,
        UiSelectValueComponent,
        UiSeparatorComponent,
        UiSwitchComponent,
      ],
      template: `
        <div data-slot="nda-agreement-generator" [class]="rootClass">
          <div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 sm:py-8 lg:px-8">
            <!-- Main Header Bar -->
            <header class="border-border bg-card mb-6 rounded-xl border p-5 shadow-xs sm:p-6">
              <div class="flex flex-col gap-5 lg:flex-row lg:items-center lg:justify-between">
                <div class="space-y-1.5">
                  <div class="flex flex-wrap items-center gap-2">
                    <span class="text-muted-foreground text-xs font-medium">Instrument:</span>
                    <span class="text-foreground font-mono text-xs font-semibold tabular-nums">#NDA-2026-88F</span>
                    <span class="text-muted-foreground text-xs">&bull;</span>
                    <span ui-badge variant="outline" class="border-primary/30 text-primary font-mono text-xs">
                      {{ agreementType() === 'mutual' ? 'Mutual / Bilateral' : 'Unilateral' }}
                    </span>
                    <span class="text-muted-foreground text-xs">&bull;</span>
                    @if (isSigned()) {
                      <span ui-badge class="border-success/30 bg-success/10 text-success gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="BadgeCheck" class="size-3.5" />
                        <span>Fully Executed &amp; Legally Binding</span>
                      </span>
                    } @else {
                      <span ui-badge class="border-warning/30 bg-warning/10 text-warning gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="AlertCircle" class="size-3.5" />
                        <span>Ready for E-Signature</span>
                      </span>
                    }
                  </div>
                  <h1 class="text-foreground text-xl font-bold tracking-tight sm:text-2xl lg:text-3xl">
                    Non-Disclosure Agreement (NDA) Generator
                  </h1>
                  <p class="text-muted-foreground flex flex-wrap items-center gap-2 text-xs sm:text-sm">
                    <lucide-icon [img]="Scale" class="size-4 shrink-0" />
                    <span>Governing Jurisdiction: {{ currentJurisdiction().name }} &bull; Effective Aug 21, 2026</span>
                  </p>
                </div>
    
                <!-- Action Buttons -->
                <div class="flex flex-wrap items-center gap-2.5">
                  <button ui-button variant="outline" size="sm" class="gap-1.5 text-xs" (click)="handlePrint()">
                    <lucide-icon [img]="Printer" class="size-4" />
                    <span>Print</span>
                  </button>
                  <button ui-button variant="outline" size="sm" class="gap-1.5 text-xs" (click)="handleSaveDraft()">
                    <lucide-icon [img]="FileCheck" class="size-4" />
                    <span>{{ draftSavedStatus() ? 'Draft Saved ✓' : 'Save Draft' }}</span>
                  </button>
                  <button
                    ui-button
                    aria-label="Download attachment"
                    size="sm"
                    class="gap-1.5 text-xs font-semibold shadow-xs"
                    [variant]="isSigned() ? 'default' : 'outline'"
                    (click)="handleExportPdf()"
                  >
                    <lucide-icon [img]="Download" class="size-4" />
                    <span>
                      {{ downloadStatus() ? 'Exporting PDF...' : isSigned() ? 'Export Signed PDF' : 'Download Draft PDF' }}
                    </span>
                  </button>
                  @if (isSigned()) {
                    <button
                      ui-button
                      variant="outline"
                      size="sm"
                      class="border-muted-foreground/30 gap-1.5 text-xs"
                      (click)="resetWorkflow()"
                    >
                      <lucide-icon [img]="RotateCcw" class="size-3.5" />
                      <span>Reset Demo</span>
                    </button>
                  }
                </div>
              </div>
    
              <ui-separator class="my-4" />
    
              <!-- Quick Parameter Switches in Header -->
              <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
                <!-- Agreement Type Toggle -->
                <div class="bg-muted/40 border-border rounded-lg border p-3">
                  <label class="text-muted-foreground block text-xs font-medium">Agreement Type</label>
                  <div class="bg-muted/60 mt-2 grid grid-cols-2 gap-1 rounded-md p-0.5">
                    <button type="button" [class]="agreementTypeClass('mutual')" (click)="agreementType.set('mutual')">
                      Mutual (Bilateral)
                    </button>
                    <button
                      type="button"
                      [class]="agreementTypeClass('unilateral')"
                      (click)="agreementType.set('unilateral')"
                    >
                      Unilateral
                    </button>
                  </div>
                </div>
    
                <!-- Jurisdiction Selector -->
                <div class="bg-muted/40 border-border rounded-lg border p-3">
                  <label class="text-muted-foreground block text-xs font-medium">Governing Jurisdiction</label>
                  <div class="mt-2">
                    <ui-select [value]="jurisdiction()" (valueChange)="setJurisdiction($event)">
                      <button ui-select-trigger size="sm" class="bg-card h-8 text-xs font-medium">
                        <ui-select-value placeholder="Select jurisdiction" />
                      </button>
                      <ui-select-content>
                        <ui-select-item value="delaware">Delaware, USA</ui-select-item>
                        <ui-select-item value="california">California, USA</ui-select-item>
                        <ui-select-item value="newyork">New York, USA</ui-select-item>
                        <ui-select-item value="england">England &amp; Wales, UK</ui-select-item>
                        <ui-select-item value="singapore">Singapore (SIAC)</ui-select-item>
                      </ui-select-content>
                    </ui-select>
                  </div>
                </div>
    
                <!-- Term of Protection -->
                <div class="bg-muted/40 border-border rounded-lg border p-3">
                  <label class="text-muted-foreground block text-xs font-medium">Protection Term</label>
                  <div class="mt-2">
                    <ui-select [value]="confidentialityTerm()" (valueChange)="setTerm($event)">
                      <button ui-select-trigger size="sm" class="bg-card h-8 text-xs font-medium">
                        <ui-select-value placeholder="Select term" />
                      </button>
                      <ui-select-content>
                        <ui-select-item value="2 Years">2 Years</ui-select-item>
                        <ui-select-item value="3 Years">3 Years (Standard)</ui-select-item>
                        <ui-select-item value="5 Years">5 Years</ui-select-item>
                        <ui-select-item value="Perpetual for Trade Secrets">Perpetual (Trade Secrets)</ui-select-item>
                      </ui-select-content>
                    </ui-select>
                  </div>
                </div>
    
                <!-- Active Protective Clauses Summary -->
                <div class="bg-muted/40 border-border rounded-lg border p-3">
                  <label class="text-muted-foreground block text-xs font-medium">Active Protective Covenants</label>
                  <div class="mt-2 flex items-center justify-between">
                    <span class="text-foreground text-xs font-semibold"
                      >{{ activeClausesCount() }} of 4 Clauses Active</span
                    >
                    <span ui-badge variant="secondary" class="font-mono text-xs tabular-nums">
                      {{ coveragePct() }}% Coverage
                    </span>
                  </div>
                </div>
              </div>
            </header>
    
            <!-- 2-Column Document Builder & Live Parchment Canvas -->
            <div class="grid grid-cols-1 gap-8 lg:grid-cols-12">
              <!-- Left Column: Builder, Clauses, Parties Form (40%) -->
              <aside class="space-y-6 lg:col-span-5">
                <!-- Contracting Parties Card -->
                <div ui-card class="border-border bg-card shadow-xs">
                  <div ui-card-header class="p-4 pb-2 sm:p-5 sm:pb-3">
                    <div class="flex items-center justify-between">
                      <div class="flex items-center gap-2">
                        <div
                          class="bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md font-bold"
                        >
                          <lucide-icon [img]="Users" class="size-4" />
                        </div>
                        <div>
                          <h3 ui-card-title class="text-sm font-semibold">Contracting Parties</h3>
                          <p ui-card-description class="text-xs">Entities bound under this confidentiality covenants</p>
                        </div>
                      </div>
                      <span ui-badge variant="outline" class="font-mono text-xs">2 Legal Entities</span>
                    </div>
                  </div>
                  <div ui-card-content class="space-y-4 p-4 pt-2 sm:p-5 sm:pt-2">
                    <!-- Disclosing Party -->
                    <div class="border-border/80 bg-muted/20 space-y-2.5 rounded-lg border p-3.5">
                      <div class="flex items-center justify-between">
                        <span class="text-foreground text-xs font-medium">Party A &bull; Disclosing Entity</span>
                        <span ui-badge variant="secondary" class="text-xs">Original Licensor</span>
                      </div>
                      <div>
                        <label class="text-muted-foreground block text-xs font-medium">Company Legal Name</label>
                        <ui-input
                          [value]="disclosingCompany()"
                          (valueChange)="disclosingCompany.set($event)"
                          size="small"
                          class="mt-1"
                          placeholder="e.g. UIPKGE Technologies Inc."
                        />
                      </div>
                      <div class="grid grid-cols-2 gap-2">
                        <div>
                          <label class="text-muted-foreground block text-xs font-medium">Authorized Signatory</label>
                          <ui-input
                            [value]="disclosingSignatory()"
                            (valueChange)="disclosingSignatory.set($event)"
                            size="small"
                            class="mt-1"
                            placeholder="e.g. Sarah Jenkins"
                          />
                        </div>
                        <div>
                          <label class="text-muted-foreground block text-xs font-medium">Corporate Title</label>
                          <ui-input
                            [value]="disclosingTitle()"
                            (valueChange)="disclosingTitle.set($event)"
                            size="small"
                            class="mt-1"
                            placeholder="e.g. VP of Architecture"
                          />
                        </div>
                      </div>
                    </div>
    
                    <!-- Receiving Party -->
                    <div class="border-border/80 bg-muted/20 space-y-2.5 rounded-lg border p-3.5">
                      <div class="flex items-center justify-between">
                        <span class="text-foreground text-xs font-medium">Party B &bull; Receiving Entity</span>
                        <span ui-badge variant="secondary" class="text-xs">Counterparty</span>
                      </div>
                      <div>
                        <label class="text-muted-foreground block text-xs font-medium">Recipient Company Name</label>
                        <ui-input
                          [value]="receivingCompany()"
                          (valueChange)="receivingCompany.set($event)"
                          size="small"
                          class="mt-1"
                          placeholder="e.g. Vertex Solutions Corp."
                        />
                      </div>
                      <div class="grid grid-cols-2 gap-2">
                        <div>
                          <label class="text-muted-foreground block text-xs font-medium">Recipient Signatory</label>
                          <ui-input
                            [value]="receivingSignatory()"
                            (valueChange)="receivingSignatory.set($event)"
                            size="small"
                            class="mt-1"
                            placeholder="e.g. Marcus Vance"
                          />
                        </div>
                        <div>
                          <label class="text-muted-foreground block text-xs font-medium">Corporate Title</label>
                          <ui-input
                            [value]="receivingTitle()"
                            (valueChange)="receivingTitle.set($event)"
                            size="small"
                            class="mt-1"
                            placeholder="e.g. Chief Technology Officer"
                          />
                        </div>
                      </div>
                    </div>
    
                    <!-- Purpose Statement -->
                    <div>
                      <label class="text-foreground block text-xs font-semibold">Authorized Purpose of Disclosure</label>
                      <p class="text-muted-foreground mt-0.5 text-xs">
                        Defines the strict commercial boundary for information exchange
                      </p>
                      <ui-input
                        [value]="purposeOfDisclosure()"
                        (valueChange)="purposeOfDisclosure.set($event)"
                        size="middle"
                        class="mt-1.5 font-mono text-xs"
                        placeholder="e.g. Evaluation of architectural partnership..."
                      />
                    </div>
                  </div>
                </div>
    
                <!-- Standard Clauses Customizer -->
                <div ui-card class="border-border bg-card shadow-xs">
                  <div ui-card-header class="p-4 pb-2 sm:p-5 sm:pb-3">
                    <div class="flex items-center justify-between">
                      <div class="flex items-center gap-2">
                        <div
                          class="bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md font-bold"
                        >
                          <lucide-icon [img]="Gavel" class="size-4" />
                        </div>
                        <div>
                          <h3 ui-card-title class="text-sm font-bold">Standard Legal Covenants</h3>
                          <p ui-card-description class="text-xs">Toggle and enforce protective clauses in real time</p>
                        </div>
                      </div>
                      <span ui-badge variant="outline" class="font-mono text-xs">Custom Covenants</span>
                    </div>
                  </div>
                  <div ui-card-content class="space-y-3.5 p-4 pt-2 sm:p-5 sm:pt-2">
                    <!-- Clause 1: Non-Solicitation -->
                    <div
                      class="border-border/80 bg-card hover:bg-muted/20 flex items-start justify-between gap-3 rounded-lg border p-3 transition-colors"
                    >
                      <div class="min-w-0 space-y-1">
                        <div class="flex flex-wrap items-center gap-2">
                          <p class="text-foreground text-xs font-semibold">1. Non-Solicitation of Employees</p>
                          <span ui-badge variant="secondary" class="text-xs">12 Months</span>
                        </div>
                        <p class="text-muted-foreground text-xs leading-relaxed">
                          Restricts either party from directly soliciting, recruiting, or hiring key technical personnel and
                          architects.
                        </p>
                      </div>
                      <ui-switch
                        [checked]="clauseNonSolicit()"
                        (checkedChange)="clauseNonSolicit.set($event)"
                        aria-label="Toggle Non-Solicitation Clause"
                      />
                    </div>
    
                    <!-- Clause 2: Injunctive Relief -->
                    <div
                      class="border-border/80 bg-card hover:bg-muted/20 flex items-start justify-between gap-3 rounded-lg border p-3 transition-colors"
                    >
                      <div class="min-w-0 space-y-1">
                        <div class="flex flex-wrap items-center gap-2">
                          <p class="text-foreground text-xs font-semibold">2. Injunctive &amp; Equitable Relief</p>
                          <span ui-badge variant="secondary" class="text-xs">No Bond Required</span>
                        </div>
                        <p class="text-muted-foreground text-xs leading-relaxed">
                          Stipulates that breach causes irreparable harm, entitling Disclosing Party to emergency
                          restraining orders without posting a bond.
                        </p>
                      </div>
                      <ui-switch
                        [checked]="clauseInjunctiveRelief()"
                        (checkedChange)="clauseInjunctiveRelief.set($event)"
                        aria-label="Toggle Injunctive Relief Clause"
                      />
                    </div>
    
                    <!-- Clause 3: Return of Materials -->
                    <div
                      class="border-border/80 bg-card hover:bg-muted/20 flex items-start justify-between gap-3 rounded-lg border p-3 transition-colors"
                    >
                      <div class="min-w-0 space-y-1">
                        <div class="flex flex-wrap items-center gap-2">
                          <p class="text-foreground text-xs font-semibold">3. Return &amp; Certified Destruction</p>
                          <span ui-badge variant="secondary" class="text-xs">14 Calendar Days</span>
                        </div>
                        <p class="text-muted-foreground text-xs leading-relaxed">
                          Mandates formal return or certified cryptographic shredding of all confidential technical assets
                          within 14 days of request.
                        </p>
                      </div>
                      <ui-switch
                        [checked]="clauseReturnMaterials()"
                        (checkedChange)="clauseReturnMaterials.set($event)"
                        aria-label="Toggle Return of Materials Clause"
                      />
                    </div>
    
                    <!-- Clause 4: Permitted Disclosures -->
                    <div
                      class="border-border/80 bg-card hover:bg-muted/20 flex items-start justify-between gap-3 rounded-lg border p-3 transition-colors"
                    >
                      <div class="min-w-0 space-y-1">
                        <div class="flex flex-wrap items-center gap-2">
                          <p class="text-foreground text-xs font-semibold">4. Permitted Compelled Disclosures</p>
                          <span ui-badge variant="secondary" class="text-xs">Subpoena Carve-Out</span>
                        </div>
                        <p class="text-muted-foreground text-xs leading-relaxed">
                          Carves out court order / statutory subpoena compliance with mandatory prompt written notification
                          to the other party.
                        </p>
                      </div>
                      <ui-switch
                        [checked]="clausePermittedDisclosures()"
                        (checkedChange)="clausePermittedDisclosures.set($event)"
                        aria-label="Toggle Permitted Disclosures Clause"
                      />
                    </div>
                  </div>
                </div>
    
                <!-- E-Signature Pad Execution Card -->
                <div ui-card class="border-border bg-card shadow-xs">
                  <div ui-card-header class="p-4 pb-2 sm:p-5 sm:pb-3">
                    <div class="flex items-center justify-between">
                      <div class="flex items-center gap-2">
                        <div
                          class="bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md font-bold"
                        >
                          <lucide-icon [img]="PenTool" class="size-4" />
                        </div>
                        <div>
                          <h3 ui-card-title class="text-sm font-bold">Electronic Signature Pad</h3>
                          <p ui-card-description class="text-xs">Adopt official digital signature style for execution</p>
                        </div>
                      </div>
                      <span ui-badge [variant]="isSigned() ? 'default' : 'outline'" class="font-mono text-xs">
                        {{ isSigned() ? 'Executed' : 'Signer 2/2' }}
                      </span>
                    </div>
                  </div>
                  <div ui-card-content class="space-y-4 p-4 pt-2 sm:p-5 sm:pt-2">
                    <!-- Signer Name Input -->
                    <div>
                      <label class="text-foreground block text-xs font-medium">Recipient Signatory Full Name</label>
                      <ui-input
                        [value]="signerName()"
                        (valueChange)="signerName.set($event)"
                        [disabled]="isSigned()"
                        size="middle"
                        class="mt-1"
                        placeholder="e.g. Marcus Vance"
                      />
                    </div>
    
                    <!-- Signature Style Picker -->
                    <div>
                      <label class="text-muted-foreground block text-xs font-medium">Adopted Typography Style</label>
                      <div class="bg-muted/60 mt-1.5 grid grid-cols-3 gap-1 rounded-lg p-1">
                        <button
                          type="button"
                          [disabled]="isSigned()"
                          [class]="signatureFontClass('serif')"
                          (click)="signatureFont.set('serif')"
                        >
                          Formal Serif
                        </button>
                        <button
                          type="button"
                          [disabled]="isSigned()"
                          [class]="signatureFontClass('script')"
                          (click)="signatureFont.set('script')"
                        >
                          Script Elegance
                        </button>
                        <button
                          type="button"
                          [disabled]="isSigned()"
                          [class]="signatureFontClass('sans')"
                          (click)="signatureFont.set('sans')"
                        >
                          Modern Sans
                        </button>
                      </div>
                    </div>
    
                    <!-- Visual Preview Box -->
                    <div class="border-border bg-muted/20 relative rounded-lg border p-4 text-center">
                      <p class="text-muted-foreground text-xs font-medium">Adopted Signature Preview</p>
                      <div class="my-3 flex min-h-[52px] items-center justify-center">
                        <span [class]="signaturePreviewClass()">{{ signerName() || 'Marcus Vance' }}</span>
                      </div>
                      <div class="text-muted-foreground flex items-center justify-center gap-1.5 font-mono text-xs">
                        <lucide-icon [img]="ShieldCheck" class="text-success size-3.5" />
                        <span>256-Bit eIDAS / ESIGN Act Compliant</span>
                      </div>
                    </div>
    
                    <!-- Consent Checkbox -->
                    <label class="text-muted-foreground flex cursor-pointer items-start gap-2.5 text-xs">
                      <input
                        type="checkbox"
                        [checked]="eConsentAgreed()"
                        [disabled]="isSigned()"
                        (change)="eConsentAgreed.set($any($event.target).checked)"
                        class="text-primary focus:ring-ring border-border mt-0.5 size-4 rounded"
                      />
                      <span class="leading-relaxed">
                        I agree to execute this Non-Disclosure Agreement electronically and confirm my electronic signature
                        legally binds <strong>{{ receivingCompany() }}</strong> under the U.S. ESIGN Act and
                        {{ currentJurisdiction().name }}.
                      </span>
                    </label>
    
                    <!-- Main Execution Action Button -->
                    <div class="space-y-2 pt-1">
                      @if (!isSigned()) {
                        <button
                          ui-button
                          type="button"
                          class="w-full gap-2 text-sm font-semibold shadow-xs"
                          [disabled]="!canSign()"
                          (click)="signAgreement()"
                        >
                          <lucide-icon [img]="PenTool" class="size-4" />
                          <span>Sign &amp; Execute Agreement</span>
                        </button>
                      } @else {
                        <div class="border-success/30 bg-success/10 space-y-2 rounded-lg border p-3.5 text-center">
                          <div class="text-success flex items-center justify-center gap-1.5 text-xs font-semibold">
                            <lucide-icon [img]="CheckCircle2" class="size-4" />
                            <span>Agreement Digitally Executed!</span>
                          </div>
                          <p class="text-muted-foreground text-xs">
                            Both parties have countersigned this NDA. Cryptographic SHA-256 certificate has been logged in
                            the audit trail.
                          </p>
                          <button
                            ui-button
                            aria-label="Download attachment"
                            size="sm"
                            class="mt-2 w-full gap-1.5 text-xs"
                            (click)="handleExportPdf()"
                          >
                            <lucide-icon [img]="Download" class="size-3.5" />
                            <span>Export Countersigned PDF</span>
                          </button>
                        </div>
                      }
    
                      @if (!isSigned() && !canSign()) {
                        <p class="text-muted-foreground text-center text-xs">
                          {{
                            !eConsentAgreed()
                              ? 'Please check the legal electronic consent box to proceed.'
                              : 'Please provide a valid signatory name.'
                          }}
                        </p>
                      }
                    </div>
                  </div>
                </div>
    
                <!-- Audit Log Miniature Card -->
                <div
                  class="border-border bg-card/60 text-muted-foreground space-y-1.5 rounded-lg border p-3.5 text-xs shadow-xs"
                >
                  <div class="text-foreground flex items-center gap-1.5 font-semibold">
                    <lucide-icon [img]="Lock" class="text-primary size-3.5" />
                    <span>Immutable Legal Audit Ledger</span>
                  </div>
                  <p class="leading-relaxed">
                    Every clause configuration and signature execution generates a tamper-evident SHA-256 cryptographic
                    digest with RFC 3161 trusted timestamping.
                  </p>
                </div>
              </aside>
    
              <!-- Right Column: Live Document Parchment Canvas (60%) -->
              <main class="space-y-6 lg:col-span-7">
                <div class="border-border bg-card rounded-xl border p-6 shadow-xs sm:p-8 lg:p-10">
                  <!-- Document Title Bar -->
                  <div class="border-border border-b pb-6 text-center">
                    <span ui-badge variant="outline" class="font-mono text-xs tracking-widest uppercase">
                      Official Legal Instrument &bull; {{ currentJurisdiction().tag }}
                    </span>
                    <h2 class="text-foreground mt-3 text-lg font-semibold tracking-tight sm:text-xl lg:text-2xl">
                      {{
                        agreementType() === 'mutual'
                          ? 'Mutual Non-Disclosure Agreement'
                          : 'Unilateral Non-Disclosure Agreement'
                      }}
                    </h2>
                    <p class="text-muted-foreground mt-1.5 font-mono text-xs">
                      Governing Law: {{ currentJurisdiction().name }} &bull; Ref: #NDA-2026-88F
                    </p>
                  </div>
    
                  <!-- Agreement Key Terms Summary Box -->
                  <div class="my-6">
                    <div class="bg-muted/40 border-border rounded-lg border p-4 sm:p-5">
                      <div class="mb-3 flex items-center justify-between">
                        <h3 class="text-foreground text-xs font-semibold">Contract Terms &amp; Scope Summary</h3>
                        <span ui-badge variant="secondary" class="font-mono text-xs">
                          {{ agreementType() === 'mutual' ? 'Bilateral Protection' : 'Unilateral Protection' }}
                        </span>
                      </div>
                      <div class="grid grid-cols-2 gap-3 sm:grid-cols-4">
                        <div class="border-border/60 bg-card rounded-md border p-3">
                          <p class="text-muted-foreground text-xs font-medium">Disclosing Party</p>
                          <p class="text-foreground mt-1 truncate text-xs font-bold">{{ disclosingCompany() }}</p>
                          <p class="text-muted-foreground mt-0.5 truncate text-xs">{{ disclosingSignatory() }}</p>
                        </div>
                        <div class="border-border/60 bg-card rounded-md border p-3">
                          <p class="text-muted-foreground text-xs font-medium">Receiving Party</p>
                          <p class="text-foreground mt-1 truncate text-xs font-bold">{{ receivingCompany() }}</p>
                          <p class="text-muted-foreground mt-0.5 truncate text-xs">{{ receivingSignatory() }}</p>
                        </div>
                        <div class="border-border/60 bg-card rounded-md border p-3">
                          <p class="text-muted-foreground text-xs font-medium">Protection Term</p>
                          <p class="text-foreground mt-1 text-xs font-bold">{{ confidentialityTerm() }}</p>
                          <p class="text-muted-foreground mt-0.5 font-mono text-xs">From Effective Date</p>
                        </div>
                        <div class="border-border/60 bg-card rounded-md border p-3">
                          <p class="text-muted-foreground text-xs font-medium">Exclusive Venue</p>
                          <p class="text-foreground mt-1 truncate text-xs font-bold">{{ venueCity() }}</p>
                          <p class="text-muted-foreground mt-0.5 font-mono text-xs">{{ currentJurisdiction().tag }}</p>
                        </div>
                      </div>
                    </div>
                  </div>
    
                  <!-- Legal Sections Content -->
                  <div class="text-foreground/90 space-y-7 text-xs leading-relaxed sm:text-sm">
                    <!-- Preamble & Recitals -->
                    <section class="space-y-3">
                      <p class="text-muted-foreground leading-relaxed">
                        This Non-Disclosure Agreement (this &ldquo;Agreement&rdquo;), effective as of the
                        <strong class="text-foreground">21st day of August, 2026</strong> (&ldquo;Effective Date&rdquo;), is
                        entered into by and between:
                      </p>
                      <div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
                        <div class="border-border bg-muted/20 rounded-lg border p-3.5">
                          <p class="text-foreground text-xs font-medium">Disclosing Party (&ldquo;Party A&rdquo;)</p>
                          <p class="text-foreground mt-1 font-bold">{{ disclosingCompany() }}</p>
                          <p class="text-muted-foreground text-xs">
                            {{ disclosingSignatory() }} &bull; {{ disclosingTitle() }}
                          </p>
                          <p class="text-muted-foreground font-mono text-xs">{{ disclosingEmail() }}</p>
                        </div>
                        <div class="border-border bg-muted/20 rounded-lg border p-3.5">
                          <p class="text-foreground text-xs font-medium">Receiving Party (&ldquo;Party B&rdquo;)</p>
                          <p class="text-foreground mt-1 font-bold">{{ receivingCompany() }}</p>
                          <p class="text-muted-foreground text-xs">
                            {{ receivingSignatory() }} &bull; {{ receivingTitle() }}
                          </p>
                          <p class="text-muted-foreground font-mono text-xs">{{ receivingEmail() }}</p>
                        </div>
                      </div>
                      <p class="text-muted-foreground italic">
                        <strong>RECITALS:</strong> WHEREAS, Disclosing Party possesses certain non-public proprietary
                        technology, software architectures, and business data, and Receiving Party desires to receive such
                        information strictly for the purpose of
                        <strong class="text-foreground not-italic">&ldquo;{{ purposeOfDisclosure() }}&rdquo;</strong> (the
                        &ldquo;Authorized Purpose&rdquo;).
                        @if (agreementType() === 'mutual') {
                          Each party may act as both a Disclosing Party and a Receiving Party under this Agreement.
                        }
                      </p>
                    </section>
    
                    <ui-separator />
    
                    <!-- Section 1: Definition of Confidential Information -->
                    <section class="space-y-2.5">
                      <div class="flex items-center gap-2">
                        <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">01</span>
                        <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                          Definition of Confidential Information
                        </h3>
                      </div>
                      <p class="text-muted-foreground">
                        &ldquo;Confidential Information&rdquo; refers to all non-public, proprietary, or confidential
                        technical and business data disclosed by Disclosing Party to Receiving Party, whether orally,
                        electronically, in writing, or by inspection of tangible objects, including but not limited to:
                        source code, software algorithms, API specifications, component registries, cryptographic tokens,
                        database schemas, product roadmaps, financial forecasts, customer records, and trade secrets.
                      </p>
                    </section>
    
                    <ui-separator />
    
                    <!-- Section 2: Non-Disclosure & Duty of Care -->
                    <section class="space-y-2.5">
                      <div class="flex items-center gap-2">
                        <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">02</span>
                        <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                          Obligations of Non-Disclosure &amp; Standard of Care
                        </h3>
                      </div>
                      <p class="text-muted-foreground">
                        Receiving Party agrees to maintain the strict confidentiality of all Confidential Information with
                        at least the same degree of care that it uses to protect its own confidential assets of similar
                        nature, but in no event less than a reasonable degree of care. Receiving Party shall:
                      </p>
                      <ul class="text-muted-foreground list-disc space-y-1.5 pl-4">
                        <li>
                          Use Confidential Information solely and exclusively for the Authorized Purpose defined herein.
                        </li>
                        <li>
                          Restrict disclosure strictly to its authorized officers, directors, employees, and legal counsel
                          who have a clear need-to-know and are bound by confidentiality covenants no less stringent than
                          this Agreement.
                        </li>
                        <li>
                          Refrain from reverse engineering, decompiling, or disassembling any software or architectural
                          artifacts provided.
                        </li>
                      </ul>
                    </section>
    
                    <ui-separator />
    
                    <!-- Section 3: Exclusions from Confidentiality -->
                    <section class="space-y-2.5">
                      <div class="flex items-center gap-2">
                        <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">03</span>
                        <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                          Exclusions from Confidential Treatment
                        </h3>
                      </div>
                      <p class="text-muted-foreground">
                        Confidential Information does not encompass information that: (a) is or becomes publicly available
                        through no act or omission of Receiving Party; (b) was rightfully in Receiving Party&rsquo;s
                        possession prior to disclosure without restriction; (c) is independently developed by Receiving
                        Party without reference to or reliance upon Disclosing Party&rsquo;s Confidential Information; or
                        (d) is lawfully obtained from a third party free of any confidentiality obligations.
                      </p>
                    </section>
    
                    <ui-separator />
    
                    <!-- Section 4: Term & Expiration -->
                    <section class="space-y-2.5">
                      <div class="flex items-center gap-2">
                        <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">04</span>
                        <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                          Term of Confidentiality Obligations
                        </h3>
                      </div>
                      <p class="text-muted-foreground">
                        The obligations of confidentiality and non-use established under this Agreement shall commence on
                        the Effective Date and continue in full force and effect for a period of
                        <strong class="text-foreground">{{ termText() }}</strong
                        >.
                      </p>
                    </section>
    
                    <!-- Dynamic Section: Non-Solicitation -->
                    @if (clauseNonSolicit()) {
                      <ui-separator />
                      <section class="space-y-2.5">
                        <div class="flex items-center gap-2">
                          <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">05</span>
                          <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                            Non-Solicitation of Technical Personnel
                          </h3>
                        </div>
                        <p class="text-muted-foreground">
                          During the term of this Agreement and for a period of
                          <strong class="text-foreground">twelve (12) calendar months</strong> immediately following its
                          expiration or termination, neither party shall directly or indirectly solicit, recruit, or entice
                          any software engineer, systems architect, or executive officer of the other party involved in this
                          collaboration to terminate their employment relationship.
                        </p>
                      </section>
                    }
    
                    <!-- Dynamic Section: Injunctive Relief -->
                    @if (clauseInjunctiveRelief()) {
                      <ui-separator />
                      <section class="space-y-2.5">
                        <div class="flex items-center gap-2">
                          <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">
                            {{ clauseNonSolicit() ? '06' : '05' }}
                          </span>
                          <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                            Injunctive &amp; Equitable Remedies
                          </h3>
                        </div>
                        <p class="text-muted-foreground">
                          The parties acknowledge that unauthorized disclosure or use of Confidential Information will cause
                          irreparable injury for which monetary damages alone would be inadequate. Consequently, Disclosing
                          Party shall be entitled to seek immediate injunctive relief, specific performance, and other
                          equitable remedies in any court of competent jurisdiction without the requirement of posting a
                          bond or proving monetary damages.
                        </p>
                      </section>
                    }
    
                    <!-- Dynamic Section: Return & Certified Destruction -->
                    @if (clauseReturnMaterials()) {
                      <ui-separator />
                      <section class="space-y-2.5">
                        <div class="flex items-center gap-2">
                          <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">
                            {{ returnMaterialsNumber() }}
                          </span>
                          <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                            Return &amp; Certified Destruction of Materials
                          </h3>
                        </div>
                        <p class="text-muted-foreground">
                          Upon written request by Disclosing Party or upon termination of discussions, Receiving Party shall
                          within <strong class="text-foreground">fourteen (14) calendar days</strong>: (a) return all
                          tangible materials containing Confidential Information; and (b) permanently erase and
                          cryptographically shred all digital records, backups, and derivative works, providing a formal
                          officer Certificate of Destruction.
                        </p>
                      </section>
                    }
    
                    <!-- Dynamic Section: Permitted Compelled Disclosures -->
                    @if (clausePermittedDisclosures()) {
                      <ui-separator />
                      <section class="space-y-2.5">
                        <div class="flex items-center gap-2">
                          <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">
                            {{ permittedDisclosuresNumber() }}
                          </span>
                          <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                            Permitted Compelled Disclosures &amp; Subpoenas
                          </h3>
                        </div>
                        <p class="text-muted-foreground">
                          Receiving Party may disclose Confidential Information pursuant to a valid judicial order or
                          statutory subpoena; provided that Receiving Party delivers prompt written notice (within 48 hours)
                          to Disclosing Party prior to disclosure, enabling Disclosing Party an opportunity to seek an
                          appropriate protective order.
                        </p>
                      </section>
                    }
    
                    <ui-separator />
    
                    <!-- Governing Law Section -->
                    <section class="space-y-2.5">
                      <div class="flex items-center gap-2">
                        <span class="bg-primary/10 text-primary rounded px-2 py-0.5 font-mono text-xs font-bold">
                          {{ activeClausesCount() + 5 }}
                        </span>
                        <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                          Governing Law &amp; Dispute Jurisdiction
                        </h3>
                      </div>
                      <p class="text-muted-foreground">
                        This Agreement shall be governed by, construed, and enforced in accordance with the substantive laws
                        of <strong class="text-foreground">{{ currentJurisdiction().name }}</strong> ({{
                          currentJurisdiction().statute
                        }}). The parties consent to the exclusive jurisdiction and venue of the courts situated in
                        <strong class="text-foreground">{{ currentJurisdiction().venue }}</strong
                        >.
                      </p>
                    </section>
    
                    <ui-separator />
    
                    <!-- Dual Signature Execution Block -->
                    <section class="space-y-4 pt-2">
                      <div class="flex items-center justify-between">
                        <h3 class="text-foreground text-sm font-semibold tracking-tight sm:text-base">
                          In Witness Whereof &bull; Execution Signatures
                        </h3>
                        <span class="text-muted-foreground font-mono text-xs">2 of 2 Parties Bound</span>
                      </div>
    
                      <div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
                        <!-- Disclosing Party Signature Block -->
                        <div class="border-border bg-muted/20 rounded-lg border p-4">
                          <div class="flex items-center justify-between">
                            <p class="text-foreground text-xs font-medium">Disclosing Party Signature</p>
                            <span
                              ui-badge
                              variant="outline"
                              class="border-success/40 bg-success/10 text-success font-mono text-xs"
                            >
                              <lucide-icon [img]="Check" class="mr-1 size-3" /> Signed &amp; Verified
                            </span>
                          </div>
                          <div class="border-border/60 bg-card my-3 rounded-md border p-3 text-center">
                            <p class="text-success text-success text-xl font-medium tracking-wide italic">
                              {{ disclosingSignatory() }}
                            </p>
                            <p class="text-muted-foreground mt-0.5 font-mono text-xs">
                              {{ disclosingTitle() }} &bull; {{ disclosingCompany() }}
                            </p>
                          </div>
                          <div class="text-muted-foreground space-y-1 font-mono text-xs">
                            <p class="flex justify-between">
                              <span>Date Countersigned:</span>
                              <span class="text-foreground font-semibold tabular-nums">Aug 21, 2026 &bull; 09:30 EDT</span>
                            </p>
                            <p class="flex justify-between">
                              <span>Certificate ID:</span>
                              <span class="text-foreground font-semibold">DS-CERT-UIPKGE-9941</span>
                            </p>
                          </div>
                        </div>
    
                        <!-- Receiving Party Signature Block -->
                        <div [class]="receivingBlockClass()">
                          <div class="flex items-center justify-between">
                            <p class="text-foreground text-xs font-medium">Receiving Party Signature</p>
                            @if (isSigned()) {
                              <span
                                ui-badge
                                class="border-success/40 bg-success/10 text-success font-mono text-xs font-medium"
                              >
                                <lucide-icon [img]="Check" class="mr-1 size-3" /> Signed &amp; Bound
                              </span>
                            } @else {
                              <span
                                ui-badge
                                class="border-warning/40 bg-warning/10 text-warning font-mono text-xs font-medium"
                              >
                                Awaiting Signature
                              </span>
                            }
                          </div>
    
                          <div [class]="receivingInnerClass()">
                            @if (isSigned()) {
                              <p [class]="executedSignatureClass()">{{ signerName() || receivingSignatory() }}</p>
                              <p class="text-muted-foreground mt-0.5 font-mono text-xs">
                                {{ receivingTitle() }} &bull; {{ receivingCompany() }}
                              </p>
                            } @else {
                              <p class="text-muted-foreground text-xs italic">
                                Awaiting signature execution via left panel
                              </p>
                              <p class="text-muted-foreground/80 mt-1 text-xs">
                                Click &ldquo;Sign &amp; Execute Agreement&rdquo; to bind {{ receivingCompany() }}
                              </p>
                            }
                          </div>
    
                          <div class="text-muted-foreground space-y-1 font-mono text-xs">
                            <p class="flex justify-between">
                              <span>Date Executed:</span>
                              <span class="text-foreground font-semibold tabular-nums">
                                {{ isSigned() ? 'Aug 21, 2026 • 11:20 EDT' : 'Pending' }}
                              </span>
                            </p>
                            <p class="flex justify-between">
                              <span>Digital Audit Hash:</span>
                              <span class="text-foreground font-semibold">
                                {{ isSigned() ? 'SHA256:d91c7a...77a1' : 'Unsigned' }}
                              </span>
                            </p>
                          </div>
                        </div>
                      </div>
                    </section>
    
                    <!-- Parchment Footer Seal -->
                    <div
                      class="border-border/60 bg-muted/20 flex flex-col items-center justify-between gap-2 rounded-lg border p-3 text-xs sm:flex-row"
                    >
                      <div class="text-muted-foreground flex items-center gap-2 font-mono text-xs">
                        <lucide-icon [img]="ShieldCheck" class="text-success size-4" />
                        <span>256-Bit Cryptographic Ledger Seal &bull; RFC 3161 Authenticated</span>
                      </div>
                      <span class="text-muted-foreground font-mono text-xs">
                        Doc ID: #NDA-2026-88F-{{ currentJurisdiction().tag }}
                      </span>
                    </div>
                  </div>
                </div>
              </main>
            </div>
          </div>
        </div>
      `,
    })
    export class UiNdaAgreementGeneratorComponent {
      protected readonly AlertCircle = AlertCircle
      protected readonly BadgeCheck = BadgeCheck
      protected readonly Check = Check
      protected readonly CheckCircle2 = CheckCircle2
      protected readonly Download = Download
      protected readonly FileCheck = FileCheck
      protected readonly Gavel = Gavel
      protected readonly Lock = Lock
      protected readonly PenTool = PenTool
      protected readonly Printer = Printer
      protected readonly RotateCcw = RotateCcw
      protected readonly Scale = Scale
      protected readonly ShieldCheck = ShieldCheck
      protected readonly Users = Users
    
      @Input() set initialSigned(v: boolean) {
        this.isSigned.set(!!v)
      }
      @Input() set initialAgreementType(v: AgreementType) {
        this.agreementType.set(v ?? 'mutual')
      }
      @Input() set initialTerm(v: TermOption) {
        this.confidentialityTerm.set(v ?? '3 Years')
      }
      @Input() set initialJurisdiction(v: JurisdictionOption) {
        this.jurisdiction.set(v ?? 'delaware')
      }
      @Input('class') className?: string
    
      // Generator State
      readonly agreementType = signal<AgreementType>('mutual')
      readonly jurisdiction = signal<JurisdictionOption>('delaware')
      readonly confidentialityTerm = signal<TermOption>('3 Years')
    
      // Parties State
      readonly disclosingCompany = signal('UIPKGE Technologies Inc.')
      readonly disclosingSignatory = signal('Sarah Jenkins')
      readonly disclosingTitle = signal('VP of Architecture & Ecosystem')
      readonly disclosingEmail = signal('s.jenkins@uipkge.dev')
    
      readonly receivingCompany = signal('Vertex Solutions Corp.')
      readonly receivingSignatory = signal('Marcus Vance')
      readonly receivingTitle = signal('Chief Technology Officer')
      readonly receivingEmail = signal('marcus.vance@vertexsolutions.io')
    
      readonly purposeOfDisclosure = signal(
        'Evaluation of potential architectural partnership, proprietary registry protocols, and API integration.',
      )
    
      // Protective Clauses Toggles
      readonly clauseNonSolicit = signal(true)
      readonly clauseInjunctiveRelief = signal(true)
      readonly clauseReturnMaterials = signal(true)
      readonly clausePermittedDisclosures = signal(true)
    
      // Signature State
      readonly isSigned = signal(false)
      readonly signatureFont = signal<SignatureFont>('serif')
      readonly signerName = signal('Marcus Vance')
      readonly eConsentAgreed = signal(true)
      readonly downloadStatus = signal(false)
      readonly draftSavedStatus = signal(false)
    
      readonly currentJurisdiction = computed(() => jurisdictionMap[this.jurisdiction()])
    
      readonly termText = computed(() => {
        switch (this.confidentialityTerm()) {
          case '2 Years':
            return 'two (2) years from the Effective Date'
          case '3 Years':
            return 'three (3) years from the Effective Date'
          case '5 Years':
            return 'five (5) years from the Effective Date'
          case 'Perpetual for Trade Secrets':
            return 'five (5) years for general Confidential Information, and perpetually for all source code, cryptographic primitives, and core trade secrets'
          default:
            return 'three (3) years from the Effective Date'
        }
      })
    
      readonly activeClausesCount = computed(
        () =>
          (this.clauseNonSolicit() ? 1 : 0) +
          (this.clauseInjunctiveRelief() ? 1 : 0) +
          (this.clauseReturnMaterials() ? 1 : 0) +
          (this.clausePermittedDisclosures() ? 1 : 0),
      )
    
      readonly coveragePct = computed(() => Math.round((this.activeClausesCount() / 4) * 100))
    
      readonly canSign = computed(() => this.eConsentAgreed() && this.signerName().trim().length > 0 && !this.isSigned())
    
      /** React's `{(clauseNonSolicit ? 1 : 0) + (clauseInjunctiveRelief ? 1 : 0) + 5}` section number. */
      readonly returnMaterialsNumber = computed(
        () => (this.clauseNonSolicit() ? 1 : 0) + (this.clauseInjunctiveRelief() ? 1 : 0) + 5,
      )
    
      /** React's `{(clauseNonSolicit ? 1 : 0) + (clauseInjunctiveRelief ? 1 : 0) + (clauseReturnMaterials ? 1 : 0) + 5}`. */
      readonly permittedDisclosuresNumber = computed(
        () =>
          (this.clauseNonSolicit() ? 1 : 0) +
          (this.clauseInjunctiveRelief() ? 1 : 0) +
          (this.clauseReturnMaterials() ? 1 : 0) +
          5,
      )
    
      readonly venueCity = computed(() => this.currentJurisdiction().venue.split(',')[0])
    
      get rootClass(): string {
        return cn('bg-background text-foreground w-full', this.className)
      }
    
      agreementTypeClass(type: AgreementType): string {
        return cn(
          'rounded px-2.5 py-1 text-xs font-medium transition-colors',
          this.agreementType() === type
            ? 'bg-card text-foreground shadow-xs'
            : 'text-muted-foreground hover:text-foreground',
        )
      }
    
      signatureFontClass(font: SignatureFont): string {
        return cn(
          'rounded-md py-1.5 text-center text-xs font-medium transition-colors',
          this.signatureFont() === font
            ? 'bg-card text-foreground shadow-xs'
            : 'text-muted-foreground hover:text-foreground',
          this.isSigned() && 'cursor-not-allowed opacity-60',
        )
      }
    
      signaturePreviewClass(): string {
        return cn(
          'text-foreground text-2xl transition-colors select-none',
          this.signatureFont() === 'serif' && 'font-medium tracking-wide italic',
          this.signatureFont() === 'script' && 'font-medium tracking-widest italic',
          this.signatureFont() === 'sans' && 'font-semibold tracking-tight',
        )
      }
    
      executedSignatureClass(): string {
        return cn(
          'text-success text-xl font-medium tracking-wide',
          this.signatureFont() === 'serif' && 'font-medium tracking-wide italic',
          this.signatureFont() === 'script' && 'font-medium tracking-widest italic',
          this.signatureFont() === 'sans' && 'font-semibold tracking-tight',
        )
      }
    
      receivingBlockClass(): string {
        return cn(
          'rounded-lg border p-4 transition-colors duration-200',
          this.isSigned() ? 'border-success/40 bg-success/5' : 'border-border bg-muted/10 border-dashed',
        )
      }
    
      receivingInnerClass(): string {
        return cn(
          'my-3 rounded-md border p-3 text-center transition-colors',
          this.isSigned() ? 'bg-card border-success/40' : 'border-muted-foreground/30 bg-muted/20 border-dashed',
        )
      }
    
      setJurisdiction(value: string): void {
        this.jurisdiction.set(value as JurisdictionOption)
      }
    
      setTerm(value: string): void {
        this.confidentialityTerm.set(value as TermOption)
      }
    
      signAgreement(): void {
        if (!this.canSign()) return
        this.isSigned.set(true)
      }
    
      resetWorkflow(): void {
        this.isSigned.set(false)
        this.downloadStatus.set(false)
        this.draftSavedStatus.set(false)
      }
    
      handleSaveDraft(): void {
        this.draftSavedStatus.set(true)
        setTimeout(() => this.draftSavedStatus.set(false), 2200)
      }
    
      handleExportPdf(): void {
        this.downloadStatus.set(true)
        setTimeout(() => this.downloadStatus.set(false), 2500)
      }
    
      handlePrint(): void {
        if (typeof window !== 'undefined') window.print()
      }
    }
    
  • src/app/components/blocks/nda-agreement-generator/index.ts0.2 kB

Raw manifest:https://uipkge.dev/r/angular/nda-agreement-generator.json