diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 00000000..5fdb242c
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,686 @@
+# GitHub Copilot Instructions for ng-in-viewport
+
+**Angular Development Guidelines**
+_Ignore current project patterns - use only latest Angular v20+ standards and best practices_
+
+## Project Overview
+
+This is an Angular library for viewport detection using modern Angular v20+ patterns. The repository contains:
+
+- **Core library**: `projects/ng-in-viewport` - Signal-based viewport detection with Intersection Observer
+- **Demo application**: `projects/demo` - Documentation and interactive examples
+- **Example application**: `projects/example` - Real-world usage scenarios and performance testing
+- **Test suites**: Comprehensive unit and E2E testing with modern Angular testing patterns
+
+## Environment Setup
+
+### Node.js Requirements
+
+- **Required**: Node.js >=22.0.0 (LTS)
+- **Required**: npm >=10.0.0
+- **Package Manager**: Prefer `npm` with exact versions for consistency
+
+### Dependency Installation
+
+For restricted environments, use network workarounds:
+
+```bash
+CYPRESS_INSTALL_BINARY=0 npm ci
+```
+
+**Execution time**: ~15 seconds
+**Timeout**: Use 60+ seconds minimum, NEVER CANCEL
+
+## Build Pipeline
+
+### Complete Build Validation
+
+```bash
+npm run format && npm run lint && npm run build:lib && npm run test:lib
+```
+
+**Execution time**: ~45 seconds
+**Timeout**: Use 120+ seconds minimum, NEVER CANCEL
+
+### Individual Commands
+
+```bash
+# Code Quality
+npm run format # Check formatting (5s)
+npm run format:write # Fix formatting (5s)
+npm run lint # Lint all projects (15s)
+
+# Library Build
+npm run build:lib # Production build (20s)
+npm run watch:lib # Development watch mode
+
+# Testing
+npm run test:lib # Unit tests with coverage (15s)
+npm run e2e:run # E2E tests headless (60s+)
+
+# Development Servers
+npm run serve:demo # Demo app - localhost:4200
+npm run serve:example # Example app - localhost:4300
+```
+
+## Angular v20+ Development Standards
+
+### Core Principles
+
+**Signal-First Architecture**: Use signals as the primary state management pattern. Observables are reserved for streams and HTTP operations only.
+
+**Component Design**: All components MUST be standalone with OnPush change detection and signal-based APIs.
+
+**Template Syntax**: Exclusive use of modern control flow (`@if`, `@for`, `@switch`) and direct binding patterns.
+
+### TypeScript Configuration
+
+```typescript
+// Use strict TypeScript with latest features
+{
+ "compilerOptions": {
+ "strict": true,
+ "exactOptionalPropertyTypes": true,
+ "noUncheckedIndexedAccess": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ }
+}
+```
+
+**Type Standards**:
+
+- NEVER use `any` - use `unknown` for uncertain types
+- Use `satisfies` operator for type checking with inference
+- Prefer `readonly` for all data that shouldn't be mutated
+- Use template literal types for string constants
+
+### Component Architecture
+
+```typescript
+import {
+ ChangeDetectionStrategy,
+ Component,
+ computed,
+ effect,
+ inject,
+ input,
+ output,
+ signal,
+ ElementRef,
+} from '@angular/core';
+
+@Component({
+ selector: 'viewport-element',
+ standalone: true,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ template: `
+ @if (isInViewport()) {
+
+ Content is visible ({{ visibilityRatio() }}%)
+
+ } @else {
+ Content is hidden
+ }
+ `,
+ host: {
+ '[attr.data-viewport-state]': 'viewportState()',
+ '[class.in-viewport]': 'isInViewport()',
+ },
+})
+export class ViewportElementComponent {
+ // Signal inputs - primary pattern for v20+
+ readonly threshold = input(0.5);
+ readonly rootMargin = input('0px');
+ readonly trackVisibility = input(true);
+
+ // Signal outputs - modern event handling
+ readonly visibilityChange = output<{
+ isVisible: boolean;
+ entry: IntersectionObserverEntry;
+ }>();
+
+ // Dependency injection with inject()
+ private readonly elementRef = inject(ElementRef);
+ private readonly viewportService = inject(ViewportService);
+
+ // Internal signals
+ protected readonly isInViewport = signal(false);
+ protected readonly visibilityRatio = signal(0);
+ private readonly lastEntry = signal(null);
+
+ // Computed values - derived state
+ protected readonly opacity = computed(
+ () => this.visibilityRatio() * 0.8 + 0.2
+ );
+
+ protected readonly viewportState = computed(() =>
+ this.isInViewport() ? 'visible' : 'hidden'
+ );
+
+ constructor() {
+ // Effects for side effects and reactions
+ effect(() => {
+ if (this.trackVisibility()) {
+ this.setupViewportObserver();
+ }
+ });
+
+ effect(() => {
+ // Emit events when visibility changes
+ const entry = this.lastEntry();
+ if (entry) {
+ this.visibilityChange.emit({
+ isVisible: this.isInViewport(),
+ entry,
+ });
+ }
+ });
+ }
+
+ private setupViewportObserver(): void {
+ // Implementation with Intersection Observer
+ this.viewportService.observe(this.elementRef.nativeElement, {
+ threshold: this.threshold(),
+ rootMargin: this.rootMargin(),
+ callback: (entry) => {
+ this.isInViewport.set(entry.isIntersecting);
+ this.visibilityRatio.set(entry.intersectionRatio * 100);
+ this.lastEntry.set(entry);
+ },
+ });
+ }
+}
+```
+
+### Service Design Patterns
+
+```typescript
+import { Injectable, inject, signal, computed } from '@angular/core';
+import { DOCUMENT } from '@angular/common';
+import { isPlatformBrowser } from '@angular/common';
+import { PLATFORM_ID } from '@angular/core';
+
+interface ViewportConfig {
+ threshold: number | number[];
+ rootMargin: string;
+ callback: (entry: IntersectionObserverEntry) => void;
+}
+
+interface ViewportGlobalConfig {
+ rootMargin: string;
+ threshold: number[];
+}
+
+@Injectable({ providedIn: 'root' })
+export class ViewportService {
+ private readonly document = inject(DOCUMENT);
+ private readonly platformId = inject(PLATFORM_ID);
+
+ // Signal-based state management
+ private readonly _elements = signal