diff --git a/src/components/LoginScreen.tsx b/src/components/LoginScreen.tsx
index 6da42a7..ad78ef9 100644
--- a/src/components/LoginScreen.tsx
+++ b/src/components/LoginScreen.tsx
@@ -1,30 +1,112 @@
-import React, { useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
import { useAuth } from '../lib/auth';
+/**
+ * Knoten des dekorativen Netzwerks. Jeder Knoten driftet auf einer eigenen
+ * Lissajous-Bahn, damit sich das Muster nie exakt wiederholt.
+ */
+const NETWORK_NODES = [
+ { x: 80, y: 300, r: 9, ax: 10, ay: 7, sx: 0.055, sy: 0.041, px: 0.0, py: 1.9 },
+ { x: 150, y: 210, r: 13, ax: 8, ay: 11, sx: 0.037, sy: 0.049, px: 1.2, py: 0.4 },
+ { x: 240, y: 250, r: 10, ax: 12, ay: 8, sx: 0.045, sy: 0.033, px: 2.7, py: 3.3 },
+ { x: 310, y: 150, r: 12, ax: 9, ay: 12, sx: 0.031, sy: 0.052, px: 4.1, py: 1.1 },
+ { x: 250, y: 80, r: 7, ax: 13, ay: 9, sx: 0.048, sy: 0.036, px: 5.4, py: 2.6 },
+ { x: 160, y: 340, r: 6, ax: 11, ay: 10, sx: 0.042, sy: 0.057, px: 0.8, py: 4.8 },
+ { x: 360, y: 240, r: 8, ax: 7, ay: 13, sx: 0.058, sy: 0.029, px: 3.5, py: 0.2 },
+];
+
+/** Verbindungen zwischen den Knoten (Indizes in NETWORK_NODES). */
+const NETWORK_EDGES: Array<[number, number]> = [
+ [0, 1],
+ [1, 2],
+ [2, 3],
+ [3, 4],
+ [4, 1],
+ [0, 5],
+ [5, 2],
+ [3, 6],
+ [6, 2],
+];
+
/** Dekoratives Netzwerk-Muster - greift das Knoten-Motiv des perinco Logos auf. */
-const NetworkPattern: React.FC = () => (
-
-);
+const NetworkPattern: React.FC = () => {
+ const circleRefs = useRef>([]);
+ const lineRefs = useRef>([]);
+
+ useEffect(() => {
+ const reduced = window.matchMedia('(prefers-reduced-motion: reduce)');
+ if (reduced.matches) return;
+
+ let frame = 0;
+ const start = performance.now();
+
+ const tick = (now: number) => {
+ const t = (now - start) / 1000;
+ const positions = NETWORK_NODES.map((node) => ({
+ x: node.x + Math.sin(t * node.sx * Math.PI * 2 + node.px) * node.ax,
+ y: node.y + Math.cos(t * node.sy * Math.PI * 2 + node.py) * node.ay,
+ }));
+
+ positions.forEach((pos, index) => {
+ const circle = circleRefs.current[index];
+ if (!circle) return;
+ circle.setAttribute('cx', pos.x.toFixed(2));
+ circle.setAttribute('cy', pos.y.toFixed(2));
+ });
+
+ NETWORK_EDGES.forEach(([from, to], index) => {
+ const line = lineRefs.current[index];
+ if (!line) return;
+ line.setAttribute('x1', positions[from].x.toFixed(2));
+ line.setAttribute('y1', positions[from].y.toFixed(2));
+ line.setAttribute('x2', positions[to].x.toFixed(2));
+ line.setAttribute('y2', positions[to].y.toFixed(2));
+ });
+
+ frame = requestAnimationFrame(tick);
+ };
+
+ frame = requestAnimationFrame(tick);
+ return () => cancelAnimationFrame(frame);
+ }, []);
+
+ return (
+
+ );
+};
export const LoginScreen: React.FC = () => {
const { login } = useAuth();