Freelance Work For Hire Contract
blocklegalIndependent contractor Master Services Agreement (MSA) with work-for-hire IP assignment, payment milestones, kill fee clauses, and electronic signature workflow.
Installation
$pnpm dlx uipkge-ng@latest add freelance-work-for-hire-contract$npx uipkge-ng@latest add freelance-work-for-hire-contract$yarn dlx uipkge-ng@latest add freelance-work-for-hire-contract$bunx uipkge-ng@latest add freelance-work-for-hire-contractManifest:
https://uipkge.dev/r/angular/freelance-work-for-hire-contract.jsonInstalls to:src/app/components/blocks/freelance-work-for-hire-contract/Variants
Loading interactive previews…
Loading interactive previews…
Files installed (2)
src/app/components/blocks/freelance-work-for-hire-contract/freelance-work-for-hire-contract.component.ts62.3 kB
// Independent contractor Master Services Agreement (MSA) with work-for-hire IP // assignment, payment milestones, kill fee clauses, and an electronic signature // workflow: two initial checkpoints gate the signature pad, which executes the // agreement. Port of the React block 1:1. import { ChangeDetectionStrategy, Component, DestroyRef, Input, computed, inject, signal } from '@angular/core' import { AlertCircle, BadgeCheck, Calendar, Check, CheckCircle2, Clock, Download, Lock, LucideAngularModule, Pen, PenTool, Printer, RotateCcw, Scale, ShieldAlert, ShieldCheck, } from 'lucide-angular' import { cn } from '@/lib/utils' import { UiAvatarComponent, UiAvatarFallbackComponent } from '@/ui/avatar/avatar.component' 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 { UiSeparatorComponent } from '@/ui/separator/separator.component' import { UiTableBodyComponent, UiTableCellComponent, UiTableComponent, UiTableHeadComponent, UiTableHeaderComponent, UiTableRowComponent, } from '@/ui/table/table.component' export type SignatureFont = 'serif' | 'script' | 'sans' @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-freelance-work-for-hire-contract, [ui-freelance-work-for-hire-contract]', 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, UiAvatarComponent, UiAvatarFallbackComponent, UiBadgeComponent, UiButtonComponent, UiCardComponent, UiCardContentComponent, UiCardDescriptionComponent, UiCardHeaderComponent, UiCardTitleComponent, UiSeparatorComponent, UiTableComponent, UiTableBodyComponent, UiTableCellComponent, UiTableHeadComponent, UiTableHeaderComponent, UiTableRowComponent, ], template: ` <div data-slot="freelance-work-for-hire-contract" [class]="rootClass"> <div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 sm:py-8 lg:px-8"> <!-- Top Agreement Header --> <header class="border-border bg-card mb-6 rounded-xl border p-5 shadow-xs sm:p-6"> <div class="flex flex-col gap-4 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">Contract Ref:</span> <span class="text-foreground font-mono text-xs font-semibold tabular-nums">#MSA-2026-4892</span> <span class="text-muted-foreground text-xs">•</span> <span class="text-muted-foreground text-xs font-medium">Total Value:</span> <span class="text-foreground font-mono text-xs font-bold tabular-nums">$24,000.00 USD</span> <span class="text-muted-foreground text-xs">•</span> @if (isSigned()) { <span ui-badge wrap 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 & Legally Binding</span> </span> } @else if (initial1Completed() && initial2Completed()) { <span ui-badge wrap class="border-warning/30 bg-warning/10 text-warning gap-1.5 text-xs font-medium"> <lucide-icon [img]="PenTool" class="size-3.5" /> <span>Ready for Signature</span> </span> } @else { <span ui-badge wrap 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 Signature • {{ pendingCount() }} Checkpoints Pending </span> </span> } </div> <h1 class="text-foreground text-xl font-bold tracking-tight sm:text-2xl lg:text-3xl"> Independent Contractor Agreement & Work-for-Hire Assignment </h1> <div class="text-muted-foreground flex flex-wrap items-center gap-x-4 gap-y-1 text-xs sm:text-sm"> <span class="flex items-center gap-1.5"> <lucide-icon [img]="Scale" class="text-primary size-3.5" /> <span> Governing Law: <strong>State of Delaware, US</strong> </span> </span> <span class="flex items-center gap-1.5"> <lucide-icon [img]="Calendar" class="text-primary size-3.5" /> <span> Effective Date: <strong>September 01, 2026</strong> </span> </span> <span class="flex items-center gap-1.5"> <lucide-icon [img]="ShieldCheck" class="text-success size-3.5" /> <span>Work-for-Hire (17 U.S.C. § 101)</span> </span> </div> </div> <div class="flex flex-wrap items-center gap-2.5"> <button ui-button variant="outline" size="sm" class="gap-1.5 text-xs shadow-xs" (click)="handlePrint()"> <lucide-icon [img]="Printer" class="size-4" /> <span>Print</span> </button> <button ui-button aria-label="Download attachment" variant="outline" size="sm" class="gap-1.5 text-xs shadow-xs" (click)="handleDownload()" > <lucide-icon [img]="Download" class="size-4" /> <span>{{ downloadSuccess() ? 'Downloading PDF...' : 'Download Draft PDF' }}</span> </button> @if (!isSigned()) { <button ui-button size="sm" class="gap-1.5 text-xs font-semibold shadow-xs" (click)="scrollToSignaturePad()" > <lucide-icon [img]="PenTool" class="size-3.5" /> <span>Sign Contract</span> </button> } @else { <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> </header> <!-- 2-Column Agreement Layout --> <div class="grid grid-cols-1 gap-8 lg:grid-cols-12"> <!-- Left Column: Contract Document Terms --> <main class="space-y-6 lg:col-span-8"> <div class="border-border bg-card rounded-xl border p-6 shadow-xs sm:p-8"> <!-- Document Header Banner --> <div class="border-border border-b pb-6 text-center"> <div class="border-primary/20 bg-primary/5 text-primary inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-semibold" > <lucide-icon [img]="Scale" class="size-3.5" /> <span>MASTER SERVICES AGREEMENT (MSA) • WORK-FOR-HIRE</span> </div> <h2 class="text-foreground mt-3 text-lg font-bold tracking-tight uppercase sm:text-xl"> Independent Contractor Master Services Agreement </h2> <p class="text-muted-foreground mt-1 text-xs"> Proprietary Rights Assignment • Milestone Payment Schedule • Kill Fee Terms </p> </div> <!-- Parties Comparison Matrix --> <div class="my-6"> <div class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <!-- Client Card --> <div class="border-border/80 bg-muted/20 rounded-lg border p-4"> <div class="flex items-center justify-between"> <span class="text-muted-foreground text-xs font-bold tracking-wider uppercase">The Client</span> <span ui-badge wrap variant="outline" class="font-mono text-xs">Principal</span> </div> <div class="mt-2.5 flex items-center gap-3"> <ui-avatar class="border-border size-10 border"> <ui-avatar-fallback class="bg-primary/10 text-primary font-bold">UP</ui-avatar-fallback> </ui-avatar> <div> <p class="text-foreground text-sm font-bold">UIPKGE Technologies Inc.</p> <p class="text-muted-foreground text-xs">Delaware C-Corp • File #6849201</p> </div> </div> <div ui-separator class="my-3"></div> <div class="text-muted-foreground space-y-1 font-mono text-xs"> <p class="flex justify-between"> <span>Address:</span> <span class="text-foreground text-right font-sans"> 548 Market St, Suite 29000, SF, CA 94104 </span> </p> <p class="flex justify-between"> <span>Authorized Signer:</span> <span class="text-foreground font-sans font-semibold">David Chen (CTO)</span> </p> <p class="flex justify-between"> <span>Billing Contact:</span> <span class="text-foreground font-sans">legal@uipkge.dev</span> </p> </div> </div> <!-- Contractor Card --> <div class="border-border/80 bg-muted/20 rounded-lg border p-4"> <div class="flex items-center justify-between"> <span class="text-muted-foreground text-xs font-bold tracking-wider uppercase"> The Contractor </span> <span ui-badge wrap variant="outline" class="font-mono text-xs">Independent Pro</span> </div> <div class="mt-2.5 flex items-center gap-3"> <ui-avatar class="border-border size-10 border"> <ui-avatar-fallback class="bg-primary/10 text-primary font-bold">ER</ui-avatar-fallback> </ui-avatar> <div> <p class="text-foreground text-sm font-bold">Elena Rostova Design LLC</p> <p class="text-muted-foreground text-xs">New York LLC • EIN: XX-XXX4910</p> </div> </div> <div ui-separator class="my-3"></div> <div class="text-muted-foreground space-y-1 font-mono text-xs"> <p class="flex justify-between"> <span>Address:</span> <span class="text-foreground text-right font-sans"> 350 5th Avenue, Suite 4100, NY, NY 10118 </span> </p> <p class="flex justify-between"> <span>Principal Signer:</span> <span class="text-foreground font-sans font-semibold"> Elena Rostova (Design Architect) </span> </p> <p class="flex justify-between"> <span>Direct Contact:</span> <span class="text-foreground font-sans">elena@rostovadesign.io</span> </p> </div> </div> </div> </div> <!-- Scope of Work Executive Summary Box --> <div class="bg-muted/30 border-border mb-8 rounded-lg border p-4 sm:p-5"> <div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between"> <div> <span class="text-muted-foreground text-xs font-semibold tracking-wider uppercase"> Statement of Work (SOW-01) </span> <h3 class="text-foreground text-sm font-bold sm:text-base"> Full-Stack Design System Component Architecture & Documentation </h3> </div> <span ui-badge wrap variant="secondary" class="self-start font-mono text-xs sm:self-auto"> Fixed-Price Milestone </span> </div> <p class="text-muted-foreground mt-2 text-xs leading-relaxed sm:text-sm"> Contractor shall architect, code, test, and document a multi-framework component registry matching enterprise production craft standards, comprising OKLCH design tokens, 50 headless Vue & React UI primitives, 50 composed application blocks, accessibility test suites, and interactive Astro live documentation. </p> <div class="mt-4 grid grid-cols-2 gap-3 sm:grid-cols-4"> <div class="border-border/60 bg-card rounded-md border p-2.5"> <p class="text-muted-foreground text-xs font-medium">Total Consideration</p> <p class="text-foreground mt-0.5 font-mono text-base font-bold tabular-nums sm:text-lg"> $24,000.00 </p> <p class="text-muted-foreground text-xs">100% Milestone-based</p> </div> <div class="border-border/60 bg-card rounded-md border p-2.5"> <p class="text-muted-foreground text-xs font-medium">Payment Terms</p> <p class="text-foreground mt-0.5 text-xs font-bold sm:text-sm">Net 15 Days</p> <p class="text-muted-foreground text-xs">Upon acceptance</p> </div> <div class="border-border/60 bg-card rounded-md border p-2.5"> <p class="text-muted-foreground text-xs font-medium">IP Ownership</p> <p class="text-foreground mt-0.5 text-xs font-bold sm:text-sm">Work-for-Hire</p> <p class="text-muted-foreground text-xs">17 U.S.C. § 101</p> </div> <div class="border-border/60 bg-card rounded-md border p-2.5"> <p class="text-muted-foreground text-xs font-medium">Kill Fee Baseline</p> <p class="text-foreground text-warning text-warning mt-0.5 font-mono text-base font-bold tabular-nums sm:text-lg" > 25.0% </p> <p class="text-muted-foreground text-xs">On uncompleted</p> </div> </div> </div> <!-- Legal Sections Stream --> <div class="text-foreground/90 space-y-8 text-xs leading-relaxed sm:text-sm"> <!-- Section 1: Services & Deliverables Table --> <section id="angular-section-1" class="space-y-4"> <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-bold sm:text-base"> Services, Milestone Deliverables & Acceptance </h3> </div> <p class="text-muted-foreground"> Contractor agrees to perform the services and provide the specific deliverables set forth in the milestone schedule below. Each deliverable shall undergo formal review by Client within seven (7) business days of submission. </p> <!-- Itemized Deliverables Table --> <div class="border-border overflow-hidden rounded-lg border"> <div class="overflow-x-auto"> <table ui-table> <thead ui-table-header class="bg-muted/50"> <tr ui-table-row> <th ui-table-head class="text-xs font-bold">Milestone & Scope</th> <th ui-table-head class="text-xs font-bold">Target Date</th> <th ui-table-head class="text-right text-xs font-bold">Consideration</th> <th ui-table-head class="text-right text-xs font-bold">Status</th> </tr> </thead> <tbody ui-table-body> <tr ui-table-row> <td ui-table-cell class="font-medium"> <div class="space-y-0.5"> <p class="text-foreground font-semibold"> Milestone 1: Architectural Discovery & Token Spec </p> <p class="text-muted-foreground text-xs"> OKLCH token set, Tailwind v4 theme bindings, typography scale, and core utilities. </p> </div> </td> <td ui-table-cell class="text-muted-foreground font-mono text-xs tabular-nums"> Sep 15, 2026 </td> <td ui-table-cell class="text-foreground text-right font-mono font-bold tabular-nums"> $6,000.00 <span class="text-muted-foreground block text-xs font-normal">25% (Deposit)</span> </td> <td ui-table-cell class="text-right"> <span ui-badge wrap class="border-success/30 bg-success/10 text-success text-xs font-medium" > <lucide-icon [img]="Check" class="mr-1 size-3" /> Paid & Settled </span> </td> </tr> <tr ui-table-row> <td ui-table-cell class="font-medium"> <div class="space-y-0.5"> <p class="text-foreground font-semibold"> Milestone 2: Core 50 UI Primitives in Vue & React </p> <p class="text-muted-foreground text-xs"> 50 accessible headless primitives (Reka UI & Radix mirror), CVA variants, and unit test suites. </p> </div> </td> <td ui-table-cell class="text-muted-foreground font-mono text-xs tabular-nums"> Oct 15, 2026 </td> <td ui-table-cell class="text-foreground text-right font-mono font-bold tabular-nums"> $10,000.00 <span class="text-muted-foreground block text-xs font-normal">41.67%</span> </td> <td ui-table-cell class="text-right"> <span ui-badge wrap variant="outline" class="border-info/30 bg-info/10 text-info text-xs font-medium" > <lucide-icon [img]="Clock" class="mr-1 size-3" /> Pending Review </span> </td> </tr> <tr ui-table-row> <td ui-table-cell class="font-medium"> <div class="space-y-0.5"> <p class="text-foreground font-semibold"> Milestone 3: 50 Composed Application Blocks & Docs </p> <p class="text-muted-foreground text-xs"> 50 production application domain blocks, Astro documentation pages, story demos, and manifests. </p> </div> </td> <td ui-table-cell class="text-muted-foreground font-mono text-xs tabular-nums"> Nov 15, 2026 </td> <td ui-table-cell class="text-foreground text-right font-mono font-bold tabular-nums"> $8,000.00 <span class="text-muted-foreground block text-xs font-normal">33.33%</span> </td> <td ui-table-cell class="text-right"> <span ui-badge wrap variant="secondary" class="text-muted-foreground text-xs font-medium"> Scheduled </span> </td> </tr> </tbody> </table> </div> </div> </section> <div ui-separator></div> <!-- Section 2: Intellectual Property Assignment & Work-for-Hire --> <section id="angular-section-2" class="space-y-3"> <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-bold sm:text-base"> Intellectual Property Assignment & Work-for-Hire Doctrine </h3> </div> <div class="text-muted-foreground space-y-2.5"> <p> <strong class="text-foreground">2.1 Work-for-Hire Declaration:</strong> Contractor expressly acknowledges and agrees that all original works of authorship, user interface components, software architecture, codebases, design tokens, documentation, graphic assets, and associated inventions prepared, authored, or contributed by Contractor under this Agreement shall constitute a <strong class="text-foreground">“Work Made for Hire”</strong> as defined under the United States Copyright Act (17 U.S.C. § 101) for the benefit of Client. </p> <p> <strong class="text-foreground">2.2 Absolute Assignment:</strong> To the extent that any Deliverable does not legally qualify as a work made for hire, Contractor hereby irrevocably, unconditionally, and perpetually transfers, assigns, and conveys to Client all worldwide right, title, and interest in and to all Intellectual Property Rights, including patents, copyrights, trade secrets, trademarks, and moral rights, effective immediately upon receipt of full payment for the applicable milestone. </p> <p> <strong class="text-foreground">2.3 Pre-Existing IP & Open-Source Carveout:</strong> Contractor retains sole ownership of pre-existing general toolchains and standard open-source libraries licensed under OSI-approved licenses (MIT/Apache-2.0) incorporated into the Deliverables, granting Client an irrevocable, perpetual, royalty-free, worldwide license to utilize, sub-license, and distribute such pre-existing materials. </p> </div> <!-- Initial Checkpoint Marker 1 --> <div id="angular-initial-marker-ip" [class]="initialMarkerClass(initial1Completed())"> <div class="flex flex-col justify-between gap-3 sm:flex-row sm:items-center"> <div class="space-y-1"> <div class="flex items-center gap-2"> <span class="text-muted-foreground text-xs font-semibold tracking-wider uppercase"> Contractor Initial Checkpoint • Section 2 </span> @if (initial1Completed()) { <span ui-badge wrap class="border-success/40 bg-success/10 text-success text-xs font-medium" > <lucide-icon [img]="Check" class="mr-1 size-3" /> Initialed </span> } @else { <span ui-badge wrap class="border-warning/40 bg-warning/10 text-warning text-xs font-medium" > Action Required </span> } </div> <p class="text-muted-foreground text-xs"> Contractor hereby irrevocably assigns all right, title, and interest in deliverables upon receipt of full payment under 17 U.S.C. § 101. </p> </div> <button type="button" ui-button size="sm" [disabled]="isSigned()" [variant]="initial1Completed() ? 'outline' : 'default'" [class]="initialButtonClass(initial1Completed())" (click)="toggleInitial1()" > @if (initial1Completed()) { <span class="text-sm font-semibold italic">ER</span> <span class="font-mono text-xs tabular-nums">• Elena Rostova [Initialed]</span> } @else { <lucide-icon [img]="Pen" class="size-3.5" /> <span>Click to Initial [ER]</span> } </button> </div> </div> </section> <div ui-separator></div> <!-- Section 3: Compensation & Invoicing --> <section id="angular-section-3" class="space-y-3"> <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-bold sm:text-base"> Compensation, Invoicing & Net 15 Terms </h3> </div> <div class="text-muted-foreground space-y-2.5"> <p> <strong class="text-foreground">3.1 Aggregate Consideration:</strong> In full consideration for the timely and satisfactory completion of the Deliverables, Client shall pay Contractor an aggregate fixed fee of <strong class="text-foreground font-mono tabular-nums">$24,000.00 USD</strong> according to the milestone schedule in Section 1. </p> <p> <strong class="text-foreground">3.2 Invoicing & Net 15 Terms:</strong> Contractor shall submit an electronic invoice upon delivery of each milestone. Client shall remit payment within <strong class="text-foreground">fifteen (15) calendar days (Net 15)</strong> from the date of formal written acceptance via ACH direct deposit or international wire. Overdue undisputed balances shall accrue statutory interest at 1.5% per month. </p> <p> <strong class="text-foreground">3.3 Taxes & Independent Status:</strong> Contractor operates strictly as an independent contractor. Contractor is solely responsible for reporting and remitting all applicable federal, state, local, and self-employment taxes (IRS Form 1099-NEC). No employment benefits, healthcare, retirement, or worker’s compensation coverage are provided. </p> </div> </section> <div ui-separator></div> <!-- Section 4: Termination & Kill Fee --> <section id="angular-section-4" class="space-y-3"> <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-bold sm:text-base"> Termination & 25% Kill Fee Policy </h3> </div> <div class="text-muted-foreground space-y-2.5"> <p> <strong class="text-foreground">4.1 Convenience Termination:</strong> Either party may terminate this Agreement without cause upon providing <strong class="text-foreground">fourteen (14) calendar days</strong> prior written notice to the other party. </p> <p> <strong class="text-foreground">4.2 Kill Fee Entitlement:</strong> In the event Client elects to terminate this Agreement for convenience prior to final completion, Client shall promptly pay Contractor for: (a) all completed and accepted milestones in full, and (b) a <strong class="text-foreground text-warning font-semibold"> Kill Fee of twenty-five percent (25%) </strong> of the total remaining uncompleted milestone compensation to cover reserved contractor capacity and schedule reallocation. </p> <p> <strong class="text-foreground">4.3 Immediate Handover:</strong> Upon termination, Contractor shall immediately deliver to Client all completed and partially completed work product, Git branches, design system source files, and credentials up to the termination effective date. </p> </div> <!-- Initial Checkpoint Marker 2 --> <div id="angular-initial-marker-kill-fee" [class]="initialMarkerClass(initial2Completed())"> <div class="flex flex-col justify-between gap-3 sm:flex-row sm:items-center"> <div class="space-y-1"> <div class="flex items-center gap-2"> <span class="text-muted-foreground text-xs font-semibold tracking-wider uppercase"> Contractor Initial Checkpoint • Section 4 </span> @if (initial2Completed()) { <span ui-badge wrap class="border-success/40 bg-success/10 text-success text-xs font-medium" > <lucide-icon [img]="Check" class="mr-1 size-3" /> Initialed </span> } @else { <span ui-badge wrap class="border-warning/40 bg-warning/10 text-warning text-xs font-medium" > Action Required </span> } </div> <p class="text-muted-foreground text-xs"> Acknowledge the 14-day termination notice requirement and 25% kill fee clause on uncompleted milestones. </p> </div> <button type="button" ui-button size="sm" [disabled]="isSigned()" [variant]="initial2Completed() ? 'outline' : 'default'" [class]="initialButtonClass(initial2Completed())" (click)="toggleInitial2()" > @if (initial2Completed()) { <span class="text-sm font-semibold italic">ER</span> <span class="font-mono text-xs tabular-nums">• Elena Rostova [Initialed]</span> } @else { <lucide-icon [img]="Pen" class="size-3.5" /> <span>Click to Initial [ER]</span> } </button> </div> </div> </section> <div ui-separator></div> <!-- Execution & Signatures Section --> <section class="space-y-4 pt-2"> <div class="flex items-center justify-between"> <h3 class="text-foreground text-sm font-bold sm:text-base">Execution & Legal Signatures</h3> <span class="text-muted-foreground font-mono text-xs">2 of 2 Parties Countersigned</span> </div> <div class="grid grid-cols-1 gap-4 sm:grid-cols-2"> <!-- Client 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-semibold tracking-wider uppercase">Client Execution</p> <span ui-badge wrap 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 & 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">David Chen</p> <p class="text-muted-foreground mt-0.5 font-mono text-xs"> CTO • UIPKGE Technologies Inc. </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"> Aug 20, 2026 • 14:22 EDT </span> </p> <p class="flex justify-between"> <span>Digital Cert:</span> <span class="text-foreground font-semibold">CERT-UIP-2026-991A</span> </p> </div> </div> <!-- Contractor Signature Block --> <div [class]="contractorBlockClass()"> <div class="flex items-center justify-between"> <p class="text-foreground text-xs font-semibold tracking-wider uppercase"> Contractor Execution </p> @if (isSigned()) { <span ui-badge wrap 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 </span> } @else { <span ui-badge wrap class="border-warning/40 bg-warning/10 text-warning font-mono text-xs font-medium" > Pending Signature </span> } </div> <div [class]="contractorPreviewClass()"> @if (isSigned()) { <p [class]="signatureClass()">{{ signerName }}</p> <p class="text-muted-foreground mt-0.5 font-mono text-xs"> Principal • Elena Rostova Design LLC </p> } @else { <p class="text-muted-foreground text-xs italic"> Awaiting contractor electronic execution via sidebar </p> <p class="text-muted-foreground/80 mt-1 text-xs"> Complete both initials above to enable signing </p> } </div> <div class="text-muted-foreground space-y-1 font-mono text-xs"> <p class="flex justify-between"> <span>Date Signed:</span> <span class="text-foreground font-semibold tabular-nums"> {{ isSigned() ? 'Aug 21, 2026 • 11:15 EDT' : 'Pending' }} </span> </p> <p class="flex justify-between"> <span>Audit Hash:</span> <span class="text-foreground font-semibold"> {{ isSigned() ? 'SHA256:4b9a2...e781' : 'Unexecuted' }} </span> </p> </div> </div> </div> </section> </div> </div> </main> <!-- Right Column: Milestone & Payment Schedule + Signature Action Center --> <aside class="space-y-5 lg:sticky lg:top-6 lg:col-span-4 lg:self-start"> <!-- Contractor Signer Profile Card --> <div ui-card class="border-border bg-card shadow-xs"> <div ui-card-header class="p-4 pb-2"> <div class="flex items-center justify-between"> <div class="flex items-center gap-2.5"> <ui-avatar class="border-border size-9 border"> <ui-avatar-fallback class="bg-primary/10 text-primary text-xs font-bold">ER</ui-avatar-fallback> </ui-avatar> <div> <h3 ui-card-title class="text-sm font-semibold">{{ signerName }}</h3> <p ui-card-description class="text-xs">Principal Design Architect</p> </div> </div> <span ui-badge wrap variant="outline" class="border-primary/30 text-primary font-mono text-xs"> Contractor </span> </div> </div> <div ui-card-content class="text-muted-foreground space-y-2 p-4 pt-2 text-xs"> <div class="flex justify-between"> <span class="text-muted-foreground">Entity:</span> <span class="text-foreground font-medium">Elena Rostova Design LLC</span> </div> <div class="flex justify-between"> <span class="text-muted-foreground">Tax Status:</span> <span class="text-foreground font-medium">W-9 On File (EIN Verified)</span> </div> <div class="flex justify-between"> <span class="text-muted-foreground">Disbursement:</span> <span class="text-foreground font-mono tabular-nums">ACH Direct Deposit (••8842)</span> </div> </div> </div> <!-- Milestone & Payout Schedule Card --> <div ui-card class="border-border bg-card shadow-xs"> <div ui-card-header class="p-4 pb-2"> <div class="flex items-center justify-between"> <h3 ui-card-title class="text-sm font-semibold">Payment Milestones</h3> <span class="text-foreground font-mono text-xs font-bold tabular-nums">$24,000.00 USD</span> </div> <p ui-card-description class="text-xs">Milestone-based disbursement on acceptance</p> </div> <div ui-card-content class="space-y-3 p-4 pt-2 text-xs"> <!-- Milestone 1 --> <div class="border-border/70 bg-muted/20 rounded-lg border p-3"> <div class="flex items-center justify-between"> <span class="text-foreground font-semibold">1. Discovery & Token Spec</span> <span ui-badge wrap class="border-success/30 bg-success/10 text-success text-xs font-medium"> Paid $6,000 </span> </div> <div class="text-muted-foreground mt-1.5 flex items-center justify-between"> <span>Target: Sep 15, 2026</span> <span class="font-mono tabular-nums">25% Allocation</span> </div> </div> <!-- Milestone 2 --> <div class="border-border/70 bg-muted/20 rounded-lg border p-3"> <div class="flex items-center justify-between"> <span class="text-foreground font-semibold">2. Core 50 UI Primitives</span> <span ui-badge wrap variant="outline" class="border-info/30 bg-info/10 text-info text-xs font-medium" > Review $10,000 </span> </div> <div class="text-muted-foreground mt-1.5 flex items-center justify-between"> <span>Target: Oct 15, 2026</span> <span class="font-mono tabular-nums">41.67% Allocation</span> </div> </div> <!-- Milestone 3 --> <div class="border-border/70 bg-muted/20 rounded-lg border p-3"> <div class="flex items-center justify-between"> <span class="text-foreground font-semibold">3. 50 Composed Blocks</span> <span ui-badge wrap variant="secondary" class="text-muted-foreground text-xs font-medium"> Due $8,000 </span> </div> <div class="text-muted-foreground mt-1.5 flex items-center justify-between"> <span>Target: Nov 15, 2026</span> <span class="font-mono tabular-nums">33.33% Final</span> </div> </div> <!-- Progress Bar --> <div class="space-y-1.5 pt-1"> <div class="flex justify-between text-xs"> <span class="text-muted-foreground">Payment Progress</span> <span class="text-foreground font-mono font-medium tabular-nums">$6,000 / $24,000 (25%)</span> </div> <div class="bg-muted flex h-2 w-full overflow-hidden rounded-full"> <div class="bg-success h-full w-[25%]" title="Paid (25%)"></div> <div class="bg-info/60 h-full w-[41.67%]" title="In Review (41.67%)"></div> <div class="bg-muted-foreground/20 h-full w-[33.33%]" title="Scheduled (33.33%)"></div> </div> </div> <!-- Kill Fee Calculation Callout --> <div class="border-warning/30 bg-warning/10 rounded-lg border p-3 text-xs"> <div class="flex items-center justify-between"> <div class="text-warning flex items-center gap-1.5 font-semibold"> <lucide-icon [img]="ShieldAlert" class="text-warning size-3.5 shrink-0" /> <span>25% Kill Fee Protection</span> </div> <span class="text-warning text-warning font-mono font-bold tabular-nums">$4,500.00</span> </div> <p class="text-muted-foreground mt-1 text-xs"> Calculated as 25% of uncompleted milestones ($18,000.00) payable upon client convenience termination. </p> </div> </div> </div> <!-- Signature Action Checklist Card --> <div ui-card class="border-border bg-card shadow-xs"> <div ui-card-header class="p-4 pb-2"> <div class="flex items-center justify-between"> <h3 ui-card-title class="text-sm font-semibold">Execution Checklist</h3> <span ui-badge wrap [variant]="completedCount() === 3 ? 'default' : 'secondary'" class="font-mono text-xs tabular-nums" > {{ completedCount() }} / 3 Done </span> </div> <p ui-card-description class="text-xs"> @if (completedCount() === 3) { All mandatory checkpoints finalized } @else { Complete all mandatory checkpoints to finalize contract } </p> </div> <div ui-card-content class="space-y-2.5 p-4 pt-2"> <!-- Item 1: Initial Section 2 IP --> <button type="button" class="border-border/80 hover:bg-muted/40 flex w-full items-center justify-between rounded-lg border p-2.5 text-left text-xs transition-colors" (click)="scrollToInitial1()" > <div class="flex items-center gap-2.5"> <div [class]="checklistDotClass(initial1Completed())"> @if (initial1Completed()) { <lucide-icon [img]="Check" class="size-3" /> } @else { <span>1</span> } </div> <div> <p class="text-foreground font-medium">Initial Section 2 (IP Assignment)</p> <p class="text-muted-foreground text-xs">17 U.S.C. § 101 Work-for-Hire clause</p> </div> </div> <span ui-badge wrap [variant]="initial1Completed() ? 'outline' : 'secondary'" [class]="checklistBadgeClass(initial1Completed())" > {{ initial1Completed() ? 'Done' : 'Review' }} </span> </button> <!-- Item 2: Initial Section 4 Kill Fee --> <button type="button" class="border-border/80 hover:bg-muted/40 flex w-full items-center justify-between rounded-lg border p-2.5 text-left text-xs transition-colors" (click)="scrollToInitial2()" > <div class="flex items-center gap-2.5"> <div [class]="checklistDotClass(initial2Completed())"> @if (initial2Completed()) { <lucide-icon [img]="Check" class="size-3" /> } @else { <span>2</span> } </div> <div> <p class="text-foreground font-medium">Initial Section 4 (25% Kill Fee)</p> <p class="text-muted-foreground text-xs">Termination protocol & compensation</p> </div> </div> <span ui-badge wrap [variant]="initial2Completed() ? 'outline' : 'secondary'" [class]="checklistBadgeClass(initial2Completed())" > {{ initial2Completed() ? 'Done' : 'Review' }} </span> </button> <!-- Item 3: Full MSA Signature --> <div [class]="checklistRowClass()"> <div class="flex items-center gap-2.5"> <div [class]="checklistDoneDotClass(isSigned())"> @if (isSigned()) { <lucide-icon [img]="Check" class="size-3" /> } @else { <span>3</span> } </div> <div> <p class="text-foreground font-medium">Execute Agreement</p> <p class="text-muted-foreground text-xs">Contractor e-signature</p> </div> </div> <span ui-badge wrap [variant]="isSigned() ? 'outline' : 'secondary'" [class]="isSigned() ? 'border-success/30 text-success text-xs' : 'text-muted-foreground text-xs'" > {{ isSigned() ? 'Executed' : 'Pending' }} </span> </div> </div> </div> <!-- Interactive Signature Pad Card --> <div ui-card id="angular-signature-pad" class="border-border bg-card shadow-xs"> <div ui-card-header class="p-4 pb-2"> <h3 ui-card-title class="text-sm font-semibold">Contractor Signature Pad</h3> <p ui-card-description class="text-xs">Adopt signature style & execute contract</p> </div> <div ui-card-content class="space-y-4 p-4 pt-2"> <!-- Style Selector --> <div class="bg-muted/60 grid grid-cols-3 gap-1.5 rounded-lg p-1"> <button type="button" [class]="fontOptionClass('serif')" (click)="signatureFont.set('serif')"> Formal Serif </button> <button type="button" [class]="fontOptionClass('script')" (click)="signatureFont.set('script')"> Script Elegance </button> <button type="button" [class]="fontOptionClass('sans')" (click)="signatureFont.set('sans')"> Modern Sans </button> </div> <!-- Preview Display 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</p> <div class="my-2 flex min-h-[48px] items-center justify-center"> <span [class]="signaturePreviewClass()">{{ signerName }}</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 & U.S. ESIGN 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)="onConsentChange($event)" class="text-primary focus:ring-ring border-border mt-0.5 size-4 rounded" /> <span> I agree to transact electronically and execute this Master Services Agreement (#MSA-2026-4892) as a legally binding instrument. </span> </label> <!-- Main Execution Button --> <div class="space-y-2 pt-2"> @if (!isSigned()) { <button type="button" ui-button class="w-full gap-2 text-sm font-semibold shadow-xs" [disabled]="!canSign()" (click)="signContract()" > <lucide-icon [img]="PenTool" class="size-4" /> <span>Sign & 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>Contract Executed Successfully!</span> </div> <p class="text-muted-foreground text-xs"> Countersigned MSA certificate dispatched to David Chen (CTO) and Elena Rostova. </p> <button ui-button aria-label="Download attachment" size="sm" class="mt-2 w-full gap-1.5 text-xs shadow-xs" (click)="handleDownload()" > <lucide-icon [img]="Download" class="size-3.5" /> <span>Download Executed Contract</span> </button> </div> } @if (!isSigned() && !canSign()) { <p class="text-muted-foreground text-center text-xs"> @if (!initial1Completed() || !initial2Completed()) { Please complete both section initial checkpoints above. } @else { Please check the electronic records consent box. } </p> } </div> </div> </div> <!-- Audit Ledger Mini Card --> <div class="border-border bg-card/60 text-muted-foreground space-y-1.5 rounded-lg border p-3 text-xs"> <div class="text-foreground flex items-center gap-1.5 font-medium"> <lucide-icon [img]="Lock" class="text-primary size-3.5" /> <span>Tamper-Proof Audit Trail Ledger</span> </div> <p class="leading-relaxed"> Every initial checkpoint and signature event is stamped with SHA-256 integrity hash, RFC 3161 timestamp, and recorded in the permanent contract execution audit trail. </p> </div> </aside> </div> </div> </div> `, }) export class UiFreelanceWorkForHireContractComponent { protected readonly AlertCircle = AlertCircle protected readonly BadgeCheck = BadgeCheck protected readonly Calendar = Calendar protected readonly Check = Check protected readonly CheckCircle2 = CheckCircle2 protected readonly Clock = Clock protected readonly Download = Download protected readonly Lock = Lock protected readonly Pen = Pen protected readonly PenTool = PenTool protected readonly Printer = Printer protected readonly RotateCcw = RotateCcw protected readonly Scale = Scale protected readonly ShieldAlert = ShieldAlert protected readonly ShieldCheck = ShieldCheck protected readonly signerName = 'Elena Rostova' @Input() set initialSigned(v: boolean) { this.isSigned.set(!!v) if (v) { this.initial1Completed.set(true) this.initial2Completed.set(true) } } @Input() set initialInitialsCompleted(v: boolean) { if (v) { this.initial1Completed.set(true) this.initial2Completed.set(true) } } @Input('class') className?: string readonly initial1Completed = signal(false) readonly initial2Completed = signal(false) readonly isSigned = signal(false) readonly signatureFont = signal<SignatureFont>('serif') readonly eConsentAgreed = signal(true) readonly downloadSuccess = signal(false) private downloadTimer: ReturnType<typeof setTimeout> | undefined constructor() { inject(DestroyRef).onDestroy(() => clearTimeout(this.downloadTimer)) } readonly completedCount = computed( () => (this.initial1Completed() ? 1 : 0) + (this.initial2Completed() ? 1 : 0) + (this.isSigned() ? 1 : 0), ) readonly pendingCount = computed(() => (this.initial1Completed() ? 0 : 1) + (this.initial2Completed() ? 0 : 1)) readonly canSign = computed( () => this.initial1Completed() && this.initial2Completed() && this.eConsentAgreed() && !this.isSigned(), ) get rootClass(): string { return cn('bg-background text-foreground w-full', this.className) } initialMarkerClass(done: boolean): string { return cn( 'rounded-lg border p-4 transition-colors duration-200', done ? 'border-success/40 bg-success/5' : 'border-warning/50 bg-warning/5 ring-warning/20 dark:bg-warning/10 ring-1', ) } initialButtonClass(done: boolean): string { return cn( 'shrink-0 gap-2 text-xs font-medium shadow-xs', done ? 'border-success/40 text-success hover:bg-success/10 text-success' : 'bg-warning hover:bg-warning/90 bg-warning dark:hover:bg-warning text-white', ) } contractorBlockClass(): 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', ) } contractorPreviewClass(): 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', ) } signatureClass(): string { const font = this.signatureFont() return cn( 'text-success text-xl font-medium tracking-wide', font === 'serif' && 'font-medium tracking-wide italic', font === 'script' && 'font-medium tracking-widest italic', font === 'sans' && 'font-semibold tracking-tight', ) } signaturePreviewClass(): string { const font = this.signatureFont() return cn( 'text-foreground text-2xl select-none', font === 'serif' && 'font-medium tracking-wide italic', font === 'script' && 'font-medium tracking-widest italic', font === 'sans' && 'font-semibold tracking-tight', ) } fontOptionClass(font: SignatureFont): string { return cn( 'rounded-md py-1 text-center text-xs font-medium transition-colors', this.signatureFont() === font ? 'bg-card text-foreground shadow-xs' : 'text-muted-foreground hover:text-foreground', ) } checklistDotClass(done: boolean): string { return cn( 'flex size-5 items-center justify-center rounded-full text-xs font-semibold', done ? 'bg-success bg-success text-white' : 'bg-warning/20 text-warning', ) } checklistDoneDotClass(done: boolean): string { return cn( 'flex size-5 items-center justify-center rounded-full text-xs font-semibold', done ? 'bg-success bg-success text-white' : 'bg-muted text-muted-foreground', ) } checklistBadgeClass(done: boolean): string { return cn('text-xs', done ? 'border-success/30 text-success' : 'text-warning') } checklistRowClass(): string { return cn( 'flex items-center justify-between rounded-lg border p-2.5 text-xs', this.isSigned() ? 'border-success/40 bg-success/5' : 'border-border/80 bg-card', ) } toggleInitial1(): void { if (this.isSigned()) return this.initial1Completed.update((v) => !v) } toggleInitial2(): void { if (this.isSigned()) return this.initial2Completed.update((v) => !v) } signContract(): void { if (!this.canSign()) return this.isSigned.set(true) } resetWorkflow(): void { this.initial1Completed.set(false) this.initial2Completed.set(false) this.isSigned.set(false) this.downloadSuccess.set(false) } handleDownload(): void { this.downloadSuccess.set(true) clearTimeout(this.downloadTimer) this.downloadTimer = setTimeout(() => this.downloadSuccess.set(false), 2500) } handlePrint(): void { if (typeof window !== 'undefined') window.print() } onConsentChange(event: Event): void { this.eConsentAgreed.set((event.target as HTMLInputElement).checked) } scrollToInitial1(): void { const el = document.getElementById('angular-initial-marker-ip') if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }) } scrollToInitial2(): void { const el = document.getElementById('angular-initial-marker-kill-fee') if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }) } scrollToSignaturePad(): void { const el = document.getElementById('angular-signature-pad') if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }) } }src/app/components/blocks/freelance-work-for-hire-contract/index.ts0.1 kB
export { UiFreelanceWorkForHireContractComponent, type SignatureFont, } from './freelance-work-for-hire-contract.component'
Raw manifest:https://uipkge.dev/r/angular/freelance-work-for-hire-contract.json