PageSourceSearch

https://web4pros.com/

html web4pros.com collected 2026-10-09 22:45:36 UTC 73,356 bytes, 944 lines download raw bytes

1<!DOCTYPE html>
2<html lang="de">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<link rel="icon" href="./favicon.svg?v=607dc0f1" type="image/svg+xml">
7<title>Webdesign, das Marken voranbringt — Web4Pros</title>
8<meta name="description" content="Webdesign, Entwicklung und Strategie für digitale Auftritte mit Substanz. Web4Pros Business Solutions, Tahiche / Lanzarote.">
9<meta property="og:type" content="website">
10<meta property="og:title" content="Webdesign, das Marken voranbringt — Web4Pros">
11<meta property="og:description" content="Webdesign, Entwicklung und Strategie für digitale Auftritte mit Substanz. Web4Pros Business Solutions, Tahiche / Lanzarote.">
12<meta property="og:locale" content="de_DE">
13<meta name="twitter:card" content="summary_large_image">
14<link rel="canonical" href="https://web4pros.com/">
15<link rel="alternate" hreflang="de" href="https://web4pros.com/">
16<link rel="alternate" hreflang="es" href="https://web4pros.com/es/">
17<link rel="alternate" hreflang="en" href="https://web4pros.com/en/">
18<link rel="alternate" hreflang="x-default" href="https://web4pros.com/">
19<link rel="preload" href="./fonts/anton-400-latin.woff2" as="font" type="font/woff2" crossorigin>
20<link rel="preload" href="./fonts/ibm-plex-sans-400-latin.woff2" as="font" type="font/woff2" crossorigin>
21<link rel="stylesheet" href="./fonts.css?v=185a0c6c">
22<style>
23  *, *::before, *::after { box-sizing: border-box; }
24  html { scroll-behavior: smooth; }
25  body { margin:0; background:#08090A; color:#E9E8E4; font-family:'IBM Plex Sans',system-ui,sans-serif; -webkit-font-smoothing:antialiased; overflow-x:hidden; }
26  ::selection { background:#E8380C; color:#fff; }
27  a { color:var(--ac,#E8380C); text-decoration:none; }
28  a:hover { color:#FF5A2E; }
29  [data-hide-sb]::-webkit-scrollbar { display:none; }
30  @keyframes w4pLine { from { transform:translateY(108%); } to { transform:translateY(0); } }
31  @keyframes w4pFade { from { opacity:0; transform:translateY(18px); } to { opacity:1; transform:translateY(0); } }
32  @keyframes w4pMarquee { from { transform:translateX(0); } to { transform:translateX(-50%); } }
33  @keyframes w4pPulse { 0%,100% { opacity:1; transform:scale(1); } 50% { opacity:.35; transform:scale(.72); } }
34  @keyframes w4pDrift { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-14px); } }
35  @keyframes w4pCurPulseW { 0% { box-shadow:0 0 0 0 rgba(255,255,255,.5); } 70% { box-shadow:0 0 0 14px rgba(255,255,255,0); } 100% { box-shadow:0 0 0 0 rgba(255,255,255,0); } }
36  @keyframes w4pCurPulse { 0% { box-shadow:0 0 0 0 rgba(232,56,12,.5); } 70% { box-shadow:0 0 0 14px rgba(232,56,12,0); } 100% { box-shadow:0 0 0 0 rgba(232,56,12,0); } }
37  body[data-cursor="on"], body[data-cursor="on"] * { cursor: none !important; }
38  @keyframes w4pSpin { to { transform:rotate(360deg); } }
39  @keyframes w4pHalo { 0% { box-shadow:0 0 0 0 rgba(232,56,12,.5); } 70% { box-shadow:0 0 0 26px rgba(232,56,12,0); } 100% { box-shadow:0 0 0 0 rgba(232,56,12,0); } }
40  @keyframes w4pCueArrow { 0%,100% { transform:translateY(-4px); opacity:.8; } 50% { transform:translateY(5px); opacity:1; } }
41  @keyframes w4pCueLine { 0%,100% { transform:scaleY(.35); opacity:.45; } 50% { transform:scaleY(1); opacity:1; } }
42</style>
43<script src="./image-slot.js?v=532f5942"></script>
43
44<style>
45  /* Der Akzent muss auf dunklem Grund hell genug sein (Leuchtdichte >= 0,187)
46     und als Knopfhintergrund unter weisser Schrift dunkel genug (<= 0,183).
47     Diese Fenster ueberschneiden sich nicht — ein einziger Farbwert kann
48     beides nicht leisten. Jede Flaeche sagt deshalb ueber data-grund, welchen
49     Ton sie braucht; alles darin folgt, weil es ueber var(--ac) geht.
50     Gemessen gegen die jeweilige Flaeche: hell 4,51 · beige 4,51 · dunkel 4,75. */
51  [data-grund="hell"]   { --ac: #CE320B; }
52  [data-grund="beige"]  { --ac: #B42B09; }
53  [data-grund="dunkel"] { --ac: #E8380C; }
54  [data-lang] { position:relative; flex:0 0 auto; }
55  [data-lang-knopf] { display:flex; align-items:center; gap:8px; background:transparent;
56    border:1px solid rgba(255,255,255,.22); color:#E9E8E4;
57    font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.08em;
58    padding:9px 14px; cursor:pointer; transition:border-color .25s, color .25s; }
59  [data-lang-knopf]:hover, [data-lang][data-offen="1"] [data-lang-knopf] {
60    border-color:rgba(255,255,255,.6); color:#fff; }
61  [data-lang-pfeil] { opacity:.55; font-size:9px; transition:transform .25s; }
62  [data-lang][data-offen="1"] [data-lang-pfeil] { transform:rotate(180deg); }
63  [data-lang-liste] { position:absolute; top:calc(100% + 8px); right:0; min-width:162px;
64    display:none; flex-direction:column; background:#0E0F11;
65    border:1px solid rgba(255,255,255,.18); padding:4px; z-index:210; }
66  [data-lang][data-offen="1"] [data-lang-liste] { display:flex; }
67  [data-lang-liste] a { display:flex; align-items:center; justify-content:space-between;
68    gap:18px; padding:9px 12px; color:#E9E8E4; font-size:14px;
69    transition:background .2s, color .2s; }
70  [data-lang-liste] a:hover { background:rgba(255,255,255,.07); color:#fff; }
71  [data-lang-liste] a[aria-current] { color:var(--ac,#E8380C); }
72  [data-lang-kuerzel] { font-family:'IBM Plex Mono',monospace; font-size:11px;
73    letter-spacing:.12em; opacity:.5; }
74  [data-lang-menue] { display:flex; gap:20px; margin-top:30px;
75    font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.22em; }
76  [data-lang-menue] a { color:rgba(233,232,228,.5); transition:color .25s; }
77  [data-lang-menue] a:hover { color:#FFFFFF; }
78  [data-lang-menue] a[aria-current] { color:var(--ac,#E8380C); }
79</style>
80<style>
81  @media (max-width: 759px) {
82    [data-el="navlinks"] { display:none !important; }
83    [data-el="delang"]   { display:none !important; }
84    [data-el="burger"]   { display:flex !important; }
85    [data-dcref="stageRef"] { height:100svh !important; }
86    [data-el="sticky"]   { height:100svh !important; }
87    [data-el="img"]      { right:-34% !important; top:50% !important; width:168% !important; opacity:.32 !important; }
88    [data-el="text"]     { padding-top:92px !important; padding-bottom:96px !important; }
89    [data-el="layers"]   { display:none !important; }
90    [data-el="notes"]    { display:none !important; }
91    [data-el="glow"]     { opacity:.5 !important; }
92  }
93</style>
94</head>
95<body style="margin:0">
96<div data-dcref="rootRef" style="background:#08090A; --ac:#E8380C; --ac-tief:#CE320B; --ac2:#1652F0;" data-grund="dunkel">
97
98  <div data-el="curRing" style="position:fixed; left:0; top:0; width:36px; height:36px; margin:-18px 0 0 -18px; border:1px solid rgba(232,56,12,.55); border-radius:50%; pointer-events:none; z-index:9998; opacity:0; will-change:transform; transition:opacity .3s ease, border-color .3s ease;"></div>
99  <div data-el="cur" style="position:fixed; left:0; top:0; width:22px; height:22px; margin:-11px 0 0 -11px; border-radius:50%; background:var(--ac,#E8380C); pointer-events:none; z-index:9999; opacity:0; will-change:transform; transition:opacity .3s ease, background .3s ease;"></div>
100
101  <header data-el="nav" style="position:fixed; top:0; left:0; right:0; z-index:200; display:flex; align-items:center; justify-content:space-between; gap:32px; padding:16px clamp(18px,4vw,56px); transition:background .45s ease, padding .45s ease, border-color .45s ease; border-bottom:1px solid rgba(255,255,255,0);">
102    <a href="#top" style="display:flex; flex-direction:column; gap:3px; flex:0 0 auto; color:#fff;">
103      <span style="font-family:'Anton',sans-serif; font-size:clamp(28px,2.8vw,40px); line-height:.86; letter-spacing:.005em; color:#FFFFFF;">Web<span style="color:var(--ac,#E8380C);">4</span>Pros</span>
104      <span style="font-family:'IBM Plex Mono',monospace; font-size:clamp(8px,.72vw,10px); letter-spacing:.44em; color:rgba(233,232,228,.5);">BUSINESS SOLUTIONS</span>
105    </a>
106    <nav data-el="navlinks" style="display: flex; align-items: center; gap: 0; font-size: 14px; letter-spacing: .02em; text-transform: uppercase">
107      <a href="./leistungen.html" data-on-mouseenter="navEnter" data-on-mouseleave="navLeave" style="position:relative; color:#E9E8E4; padding:6px 26px 9px;" style-hover="color:#FFFFFF;">Leistungen<span data-ul="1" style="position:absolute; left:26px; right:26px; bottom:0; height:2px; background:var(--ac,#E8380C); transform:scaleX(0); transform-origin:left center; transition:transform .4s cubic-bezier(.16,1,.3,1);"></span></a>
108      <span style="width:1px; height:16px; background:rgba(255,255,255,.22);"></span>
109      <a href="./projekte.html" data-on-mouseenter="navEnter" data-on-mouseleave="navLeave" style="position:relative; color:#E9E8E4; padding:6px 26px 9px;" style-hover="color:#FFFFFF;">Projekte<span data-ul="1" style="position:absolute; left:26px; right:26px; bottom:0; height:2px; background:var(--ac,#E8380C); transform:scaleX(0); transform-origin:left center; transition:transform .4s cubic-bezier(.16,1,.3,1);"></span></a>
110      <span style="width:1px; height:16px; background:rgba(255,255,255,.22);"></span>
111      <a href="./agentur.html" data-on-mouseenter="navEnter" data-on-mouseleave="navLeave" style="position:relative; color:#E9E8E4; padding:6px 26px 9px;" style-hover="color:#FFFFFF;">Agentur<span data-ul="1" style="position:absolute; left:26px; right:26px; bottom:0; height:2px; background:var(--ac,#E8380C); transform:scaleX(0); transform-origin:left center; transition:transform .4s cubic-bezier(.16,1,.3,1);"></span></a>
112      <span style="width:1px; height:16px; background:rgba(255,255,255,.22);"></span>
113      <a href="./kontakt.html" data-on-mouseenter="navEnter" data-on-mouseleave="navLeave" style="position:relative; color:#E9E8E4; padding:6px 26px 9px;" style-hover="color:#FFFFFF;">Kontakt<span data-ul="1" style="position:absolute; left:26px; right:26px; bottom:0; height:2px; background:var(--ac,#E8380C); transform:scaleX(0); transform-origin:left center; transition:transform .4s cubic-bezier(.16,1,.3,1);"></span></a>
114    </nav>
115    <div data-el="delang" data-lang data-offen="0" style="display:flex;"><button type="button" data-lang-knopf aria-haspopup="true" aria-expanded="false" aria-label="Sprache waehlen">DE <span data-lang-pfeil>&#9662;</span></button><div data-lang-liste><a href="index.html" hreflang="de" lang="de" aria-current="true"><span>Deutsch</span><span data-lang-kuerzel>DE</span></a><a href="es/index.html" hreflang="es" lang="es"><span>Español</span><span data-lang-kuerzel>ES</span></a><a href="en/index.html" hreflang="en" lang="en"><span>English</span><span data-lang-kuerzel>EN</span></a></div></div>
116    <button data-el="burger" data-on-click="toggleMenu" style="display:none; align-items:center; gap:10px; background:transparent; border:1px solid rgba(255,255,255,.24); color:#E9E8E4; font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.16em; padding:11px 16px; cursor:pointer;">MENÜ</button>
117    <div data-el="topbar" style="position:absolute; left:0; bottom:-1px; height:2px; width:0%; background:var(--ac,#E8380C); pointer-events:none;"></div>
118  </header>
119
120  <div data-el="menu" style="position:fixed; inset:0; z-index:190; background:#08090A; display:none; flex-direction:column; justify-content:center; gap:4px; padding:0 clamp(18px,6vw,56px);" data-grund="dunkel">
121    <a href="./leistungen.html" data-on-click="closeMenu" style="font-family:'Anton',sans-serif; font-size:clamp(34px,10vw,58px); line-height:1.1; text-transform:uppercase; color:#FFFFFF; padding:14px 0; border-bottom:1px solid rgba(255,255,255,.12);">Leistungen</a>
122    <a href="./projekte.html" data-on-click="closeMenu" style="font-family:'Anton',sans-serif; font-size:clamp(34px,10vw,58px); line-height:1.1; text-transform:uppercase; color:#FFFFFF; padding:14px 0; border-bottom:1px solid rgba(255,255,255,.12);">Projekte</a>
123    <a href="./agentur.html" data-on-click="closeMenu" style="font-family:'Anton',sans-serif; font-size:clamp(34px,10vw,58px); line-height:1.1; text-transform:uppercase; color:#FFFFFF; padding:14px 0; border-bottom:1px solid rgba(255,255,255,.12);">Agentur</a>
124    <a href="./kontakt.html" data-on-click="closeMenu" style="font-family:'Anton',sans-serif; font-size:clamp(34px,10vw,58px); line-height:1.1; text-transform:uppercase; color:var(--ac,#E8380C); padding:14px 0; border-bottom:1px solid rgba(255,255,255,.12);">Kontakt</a>
125    <div data-lang-menue><a href="index.html" hreflang="de" lang="de" aria-current="true">DE</a><a href="es/index.html" hreflang="es" lang="es">ES</a><a href="en/index.html" hreflang="en" lang="en">EN</a></div>
126  </div>
127
128  <main>
129  <section id="top" data-screen-label="Hero" data-dcref="stageRef" style="position:relative; height:230vh; background:#08090A;" data-grund="dunkel">
130    <div data-el="sticky" style="position:sticky; top:0; height:100vh; overflow:hidden; display:flex; align-items:center;">
131
132      <div data-el="grid" style="position:absolute; inset:-10%; background-image:linear-gradient(rgba(255,255,255,.085) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.085) 1px, transparent 1px); background-size:88px 88px; -webkit-mask-image:radial-gradient(150% 120% at 50% 48%, #000 62%, transparent 96%); mask-image:radial-gradient(150% 120% at 50% 48%, #000 62%, transparent 96%); will-change:transform;"></div>
133
134      <div data-el="glow" style="position:absolute; right:12%; top:50%; width:52vw; height:52vw; transform:translateY(-50%); background:radial-gradient(circle, rgba(232,56,12,.20) 0%, rgba(232,56,12,0) 62%); pointer-events:none;"></div>
135
136      <div data-el="img" style="position:absolute; right:-3%; top:50%; width:min(66vw,1400px); transform:translateY(-50%); will-change:transform; pointer-events:none;">
137        <img decoding="async" src="uploads/Header-BG-Web4Pros-test2.webp?v=6b64a204" alt="" style="width:100%; display:block;">
138      </div>
139
140      <div data-el="layers" style="position:absolute; inset:0; pointer-events:none;">
141        <div data-depth="-70,-40" style="position:absolute; right:24%; top:16%; width:clamp(180px,20vw,320px); height:clamp(140px,15vw,240px); border:1px solid rgba(255,255,255,.16);"></div>
142        <div data-depth="90,60" style="position:absolute; right:8%; bottom:14%; width:clamp(160px,18vw,280px); height:clamp(120px,13vw,200px); border:1px solid rgba(22,82,240,.5);"></div>
143        <div data-depth="-120,20" style="position:absolute; right:44%; top:30%; width:clamp(120px,12vw,180px); height:1px; background:linear-gradient(90deg, transparent, rgba(255,255,255,.45));"></div>
144        <div data-depth="60,-80" style="position:absolute; right:14%; top:10%; width:44px; height:44px; background:var(--ac2,#1652F0); display:flex; align-items:center; justify-content:center; color:#fff; font-size:20px; font-weight:400; line-height:1;">+</div>
145        <div data-depth="-40,90" style="position:absolute; right:34%; bottom:20%; font-family:'IBM Plex Mono',monospace; font-size:11px; line-height:1.7; color:rgba(255,255,255,.35); letter-spacing:.18em;" aria-hidden="true">01001<br>10101<br>01101</div>
146        <div data-depth="110,-30" style="position:absolute; right:6%; top:26%; width:1px; height:clamp(120px,18vh,200px); background:linear-gradient(180deg, var(--ac,#E8380C), transparent);"></div>
147      </div>
148
149      <div data-el="notes" style="position:absolute; right:clamp(24px,28vw,660px); top:50%; transform:translateY(-50%); z-index:4; display:flex; flex-direction:column; gap:clamp(16px,2.6vh,30px); align-items:flex-end; pointer-events:none;">
150        <div data-note="1" style="display:flex; align-items:center; gap:14px; opacity:0; transform:translateX(90px); transition:opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);">
151          <span style="font-family:'IBM Plex Mono',monospace; font-size:clamp(13px,1.05vw,17px); letter-spacing:.14em; color:#F2F1EE; white-space:nowrap;">01 — STRATEGIE</span>
152          <span style="width:clamp(28px,5vw,72px); height:1px; background:rgba(255,255,255,.35);"></span>
153          <span style="width:9px; height:9px; border:1px solid var(--ac,#E8380C);"></span>
154        </div>
155        <div data-note="2" style="display:flex; align-items:center; gap:14px; opacity:0; transform:translateX(90px); transition:opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);">
156          <span style="font-family:'IBM Plex Mono',monospace; font-size:clamp(13px,1.05vw,17px); letter-spacing:.14em; color:#F2F1EE; white-space:nowrap;">02 — DESIGN</span>
157          <span style="width:clamp(28px,5vw,72px); height:1px; background:rgba(255,255,255,.35);"></span>
158          <span style="width:9px; height:9px; border:1px solid var(--ac,#E8380C);"></span>
159        </div>
160        <div data-note="3" style="display:flex; align-items:center; gap:14px; opacity:0; transform:translateX(90px); transition:opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);">
161          <span style="font-family:'IBM Plex Mono',monospace; font-size:clamp(13px,1.05vw,17px); letter-spacing:.14em; color:#F2F1EE; white-space:nowrap;">03 — ENTWICKLUNG</span>
162          <span style="width:clamp(28px,5vw,72px); height:1px; background:rgba(255,255,255,.35);"></span>
163          <span style="width:9px; height:9px; border:1px solid var(--ac,#E8380C);"></span>
164        </div>
165        <div data-note="4" style="display:flex; align-items:center; gap:14px; opacity:0; transform:translateX(90px); transition:opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);">
166          <span style="font-family:'IBM Plex Mono',monospace; font-size:clamp(13px,1.05vw,17px); letter-spacing:.14em; color:var(--ac,#E8380C); white-space:nowrap;">04 — LIVE GANG</span>
167          <span style="width:clamp(28px,5vw,72px); height:1px; background:var(--ac,#E8380C);"></span>
168          <span style="width:9px; height:9px; background:var(--ac,#E8380C);"></span>
169        </div>
170      </div>
171
172      <div data-el="scan" style="position:absolute; left:0; right:0; top:0; height:2px; background:linear-gradient(90deg, transparent, rgba(232,56,12,.9) 45%, rgba(255,255,255,.9) 55%, transparent); box-shadow:0 0 26px rgba(232,56,12,.65); opacity:0; pointer-events:none;"></div>
173
174      <div data-el="text" style="position:relative; z-index:3; width:100%; padding:0 clamp(18px,4vw,56px); will-change:transform;">
175        <div style="max-width:820px;">
176          <div style="display:flex; align-items:center; gap:12px; margin-bottom:clamp(18px,3vh,34px); animation:w4pFade .8s ease both;">
177            <span style="width:7px; height:7px; background:var(--ac,#E8380C); border-radius:50%; animation:w4pPulse 2.4s ease-in-out infinite;"></span>
178            <span style="font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.22em; color:rgba(233,232,228,.72); text-transform:uppercase;">Digital Studio · Lanzarote / Europa</span>
179          </div>
180
181          <h1 style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(46px,7.6vw,124px); line-height:.9; letter-spacing:.005em; color:#FFFFFF;">
182            <span style="display:block; overflow:hidden; padding-bottom:.04em;"><span style="display:block; animation:w4pLine 1s cubic-bezier(.16,1,.3,1) .05s both;">Websites, die</span></span>
183            <span style="display:block; overflow:hidden; padding-bottom:.04em;"><span style="display:block; animation:w4pLine 1s cubic-bezier(.16,1,.3,1) .16s both;">Marken</span></span>
184            <span style="display:block; overflow:hidden; padding-bottom:.04em;"><span style="display:block; color:var(--ac,#E8380C); animation:w4pLine 1s cubic-bezier(.16,1,.3,1) .27s both;">voranbringen.</span></span>
185          </h1>
186
187          <p style="margin:clamp(20px,3.2vh,34px) 0 0; max-width:430px; font-size:clamp(15px,1.15vw,18px); line-height:1.6; color:rgba(233,232,228,.66); text-wrap:pretty; animation:w4pFade .9s ease .5s both;">Strategie, Design und Entwicklung für digitale Auftritte mit Substanz.</p>
188
189          <div style="display:flex; flex-wrap:wrap; gap:14px; margin-top:clamp(24px,4vh,40px); animation:w4pFade .9s ease .62s both;">
190            <a href="./kontakt.html#anfrage" style="display:inline-flex; align-items:center; gap:12px; background:var(--ac-tief,#CE320B);
190 color:#fff; padding:17px 28px; font-size:15px; font-weight:500; transition:transform .3s cubic-bezier(.16,1,.3,1), background .3s;" style-hover="background:#FF4A18; transform:translateY(-2px);">Projekt starten <span style="font-size:14px;">↗</span></a>
191            <a href="#projekte" style="display:inline-flex; align-items:center; gap:12px; border:1px solid rgba(255,255,255,.28); color:#E9E8E4; padding:17px 28px; font-size:15px; font-weight:500; transition:border-color .3s, transform .3s cubic-bezier(.16,1,.3,1);" style-hover="border-color:#fff; color:#fff; transform:translateY(-2px);">Arbeiten entdecken <span style="font-size:14px;">↓</span></a>
192          </div>
193        </div>
194      </div>
195
196      <a href="#leistungen" data-el="cue" aria-label="Weiter" style="position:absolute; left:50%; bottom:clamp(78px,11vh,124px); z-index:6; width:82px; height:82px; margin-left:-41px; display:flex; align-items:center; justify-content:center; opacity:0; transform:translateY(-72px) scale(.84); transition:opacity .7s cubic-bezier(.16,1,.3,1), transform .95s cubic-bezier(.16,1,.3,1); pointer-events:none;">
197        <span style="position:absolute; inset:0; border-radius:50%; border:1px dashed rgba(255,255,255,.3); animation:w4pSpin 16s linear infinite;"></span>
198        <span style="position:absolute; inset:9px; border-radius:50%; border:1px solid rgba(232,56,12,.55); animation:w4pHalo 2.6s ease-out infinite;"></span>
199        <span style="position:absolute; inset:15px; border-radius:50%; background:rgba(232,56,12,.16);"></span>
200        <span style="position:absolute; left:50%; top:100%; width:1px; height:38px; margin-left:-1px; background:linear-gradient(180deg, var(--ac,#E8380C), transparent); transform-origin:top; animation:w4pCueLine 2s ease-in-out infinite;"></span>
201        <span style="position:relative; font-size:21px; line-height:1; color:var(--ac,#E8380C); animation:w4pCueArrow 2s cubic-bezier(.16,1,.3,1) infinite;">↓</span>
202      </a>
203
204      <div data-el="foot" style="position:absolute; left:0; right:0; bottom:0; z-index:4; display:flex; align-items:center; justify-content:space-between; gap:24px; padding:0 clamp(18px,4vw,56px) clamp(22px,3.4vh,34px); animation:w4pFade .9s ease .8s both;">
205        <div style="display:flex; align-items:center; gap:clamp(14px,2vw,28px); font-size:13px; color:rgba(233,232,228,.8);">
206          <span>150+ Projekte</span><span style="color:var(--ac,#E8380C);">●</span>
207          <span>25+ Jahre Erfahrung</span><span style="color:var(--ac,#E8380C);">●</span>
208          <span>DE · ES · EN</span>
209        </div>
210        <div style="display:flex; align-items:center; gap:14px; font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.16em; color:rgba(233,232,228,.5);">
211          <span>SCROLL</span>
212          <span style="width:56px; height:1px; background:rgba(255,255,255,.2); position:relative; overflow:hidden;"><span data-el="bar" style="position:absolute; left:0; top:0; bottom:0; width:0%; background:var(--ac,#E8380C);"></span></span>
213          <span data-el="pct" style="color:rgba(233,232,228,.8);">000</span>
214        </div>
215      </div>
216
217    </div>
218  </section>
219
220  <div style="position:relative; z-index:5; background:#08090A; border-top:1px solid rgba(255,255,255,.1); border-bottom:1px solid rgba(255,255,255,.1); overflow:hidden; padding:16px 0;" data-grund="dunkel">
221    <div data-el="ticker" style="display:flex; width:max-content; will-change:transform; font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.24em; text-transform:uppercase; color:rgba(233,232,228,.5);">
222      <span style="display:flex; gap:44px; padding-right:44px;"><span>Strategie</span><span style="color:var(--ac,#E8380C);">✳</span><span>Webdesign</span><span style="color:var(--ac,#E8380C);">✳</span><span>WordPress</span><span style="color:var(--ac,#E8380C);">✳</span><span>SEO</span><span style="color:var(--ac,#E8380C);">✳</span><span>AI Content</span><span style="color:var(--ac,#E8380C);">✳</span><span>Hosting</span><span style="color:var(--ac,#E8380C);">✳</span><span>Care</span><span style="color:var(--ac,#E8380C);">✳</span></span>
223      <span style="display:flex; gap:44px; padding-right:44px;"><span>Strategie</span><span style="color:var(--ac,#E8380C);">✳</span><span>Webdesign</span><span style="color:var(--ac,#E8380C);">✳</span><span>WordPress</span><span style="color:var(--ac,#E8380C);">✳</span><span>SEO</span><span style="color:var(--ac,#E8380C);">✳</span><span>AI Content</span><span style="color:var(--ac,#E8380C);">✳</span><span>Hosting</span><span style="color:var(--ac,#E8380C);">✳</span><span>Care</span><span style="color:var(--ac,#E8380C);">✳</span></span>
224    </div>
225  </div>
226
227  <section id="leistungen" data-screen-label="Leistungen" style="position:relative; z-index:5; background:#FFFFFF; color:#0B0B0C; padding:clamp(56px,8vw,112px) clamp(18px,4vw,56px) clamp(64px,9vw,120px);" data-grund="hell">
228    <div style="max-width:1440px; margin:0 auto;">
229      <div style="display:flex; align-items:flex-end; justify-content:space-between; gap:32px; flex-wrap:wrap; margin-bottom:clamp(30px,4vw,52px);">
230        <div data-rv="0">
231          <div style="display:flex; align-items:center; gap:10px; margin-bottom:20px; font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.18em; color:#6C6C6C;">01<span style="width:26px; height:1px; background:#C9C9C9;"></span></div>
232          <h2 style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(30px,4.2vw,60px); line-height:.95;">Was ich bewege</h2>
233        </div>
234        <a href="./leistungen.html" data-rv="1" style="display:inline-flex; align-items:center; gap:10px; color:#0B0B0C; font-size:15px; font-weight:500; border-bottom:1px solid #0B0B0C; padding-bottom:5px;" style-hover="color:var(--ac,#E8380C); border-color:var(--ac,#E8380C);">Leistungen entdecken <span>↗</span></a>
235      </div>
236    </div>
237
238    <div data-el="bento" style="max-width:1440px; margin:0 auto; display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); grid-auto-rows:minmax(clamp(160px,14vw,206px),auto); gap:clamp(10px,1.1vw,16px);">
239
240      <a href="./leistungen.html#webdesign" data-bento="2x2" data-rv="0" data-on-mouseenter="rowEnter" data-on-mousemove="tiltMove" data-on-mouseleave="rowLeave" style="grid-column:span 2; grid-row:span 2; position:relative; overflow:hidden; display:flex; flex-direction:column; justify-content:space-between; gap:24px; padding:clamp(26px,2.6vw,40px); background:#0B0B0C; color:#FFFFFF; transition:background .45s ease;" style-hover="background:#151517;" data-grund="dunkel">
241        <img decoding="async" data-bg="1" src="uploads/bento-webdesign-ux2.webp?v=489411ad" alt="" draggable="false" style="position:absolute; z-index:0; right:-2%; top:-2%; width:100%; height:auto; opacity:.9; mix-blend-mode:screen; pointer-events:none; transition:transform 1.1s cubic-bezier(.16,1,.3,1), opacity .6s ease; -webkit-mask-image:linear-gradient(205deg, #000 46%, transparent 84%); mask-image:linear-gradient(205deg, #000 46%, transparent 84%);" width="1402" height="1122">
242        <div style="position:relative; z-index:1; display:flex; align-items:flex-start; justify-content:space-between; gap:20px;">
243          <span style="font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.18em; color:var(--ac,#E8380C);">01 / 06</span>
244          <span data-arw="1" style="font-size:22px; opacity:.45; transition:opacity .4s ease, transform .5s cubic-bezier(.16,1,.3,1);">↗</span>
245        </div>
246        <img decoding="async" data-ico="1" src="uploads/web4pros-design-assets/02-icon-webdesign-ux.webp?v=f5567503" alt="" draggable="false" style="position:relative; z-index:1; align-self:flex-start; width:clamp(140px,13.5vw,208px); height:auto; display:block; margin:-10px 0 -6px -10px; filter:brightness(0) invert(1); transition:transform .55s cubic-bezier(.16,1,.3,1);" width="1254" height="1254">
247        <div style="position:relative; z-index:1;">
248          <h3 style="margin:0 0 12px; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(26px,3.1vw,46px); line-height:1;">Webdesign &amp; UX</h3>
249          <p style="margin:0; max-width:34ch; font-size:15px; line-height:1.6; color:rgba(255,255,255,.62); text-wrap:pretty;">Markenstarke Websites mit klarer Struktur und intuitiven Nutzererlebnissen – vom Wireframe bis zum letzten Pixel.</p>
250        </div>
251      </a>
252
253      <a href="./leistungen.html#wordpress" data-bento="2x1" data-rv="1" data-on-mouseenter="rowEnter" data-on-mousemove="tiltMove" data-on-mouseleave="rowLeave" style="grid-column:span 2; position:relative; overflow:hidden; display:flex; align-items:center; gap:clamp(18px,2vw,30px); padding:clamp(24px,2.4vw,34px); background:#F1F0ED; color:#0B0B0C; transition:background .45s ease;" style-hover="background:#E8E7E3;" data-grund="hell">
254        <img decoding="async" data-ico="1" src="uploads/web4pros-design-assets/03-icon-wordpress-entwicklung.webp?v=bc24751a" alt="" draggable="false" style="flex:0 0 auto; width:clamp(104px,9.2vw,140px); height:auto; display:block; transition:transform .55s cubic-bezier(.16,1,.3,1);" width="1254" height="1254">
255        <div style="min-width:0;">
256          <div style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:var(--ac,#E8380C); margin-bottom:10px;">02 / 06</div>
257          <h3 style="margin:0 0 8px; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(19px,2vw,28px); line-height:1.05;">WordPress &amp; Entwicklung</h3>
258          <p style="margin:0; font-size:14px; line-height:1.55; color:#5F5F5F; text-wrap:pretty;">Individuelle Lösungen auf WordPress-Basis. Schnell, flexibel, zukunftssicher.</p>
259        </div>
260        <span data-arw="1" style="position:absolute; right:22px; top:20px; font-size:19px; opacity:.35; transition:opacity .4s ease, transform .5s cubic-bezier(.16,1,.3,1);">↗</span>
261      </a>
262
263      <a href="./leistungen.html#seo" data-bento="1x1" data-rv="2" data-on-mouseenter="rowEnter" data-on-mousemove="tiltMove" data-on-mouseleave="rowLeave" style="position:relative; overflow:hidden; display:flex; flex-direction:column; justify-content:space-between; gap:16px; padding:clamp(22px,2.2vw,30px); background:#F1F0ED; color:#0B0B0C; transition:background .45s ease;" style-hover="background:#E8E7E3;" data-grund="hell">
264        <div style="display:flex; align-items:flex-start; justify-content:space-between; gap:12px;">
265          <span style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:var(--ac,#E8380C);">03</span>
266          <span data-arw="1" style="font-size:18px; opacity:.35; transition:opacity .4s ease, transform .5s cubic-bezier(.16,1,.3,1);">↗</span>
267        </div>
268        <img decoding="async" data-ico="1" src="uploads/web4pros-design-assets/04-icon-seo-sichtbarkeit.webp?v=e42a4781" alt="" draggable="false" style="align-self:flex-start; width:clamp(92px,8vw,118px); margin-left:-8px; height:auto; display:block; transition:transform .55s cubic-bezier(.16,1,.3,1);" width="1254" height="1254">
269        <h3 style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(17px,1.7vw,24px); line-height:1.05;">SEO &amp;<br>Sichtbarkeit</h3>
270        <p style="margin:0; font-size:14px; line-height:1.55; color:#5F5F5F; text-wrap:pretty;">Technisches SEO und Inhalte, die bei Google gefunden werden.</p>
271      </a>
272
273      <a href="./leistungen.html#care" data-bento="1x1" data-rv="3" data-on-mouseenter="rowEnter" data-on-mousemove="tiltMove" data-on-mouseleave="rowLeave" style="position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; gap: 16px; padding: clamp(22px,2.2vw,30px); color: #0B0B0C; transition: background .45s ease; background-color: #DCD9CD" style-hover="background:#E8E7E3;" data-grund="beige">
274        <div style="display:flex; align-items:flex-start; justify-content:space-between; gap:12px;">
275          <span style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:var(--ac,#E8380C);">04</span>
276          <span data-arw="1" style="font-size:18px; opacity:.35; transition:opacity .4s ease, transform .5s cubic-bezier(.16,1,.3,1);">↗</span>
277        </div>
278        <img decoding="async" data-ico="1" src="uploads/web4pros-design-assets/05-icon-care-support.webp?v=8964d0b2" alt="" draggable="false" style="align-self:flex-start; width:clamp(92px,8vw,118px); margin-left:-8px; height:auto; display:block; transition:transform .55s cubic-bezier(.16,1,.3,1);" width="1254" height="1254">
279        <h3 style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(17px,1.7vw,24px); line-height:1.05;">Care &amp;<br>Support</h3>
280        <p style="margin:0; font-size:14px; line-height:1.55; color:#5F5F5F; text-wrap:pretty;">Updates, Backups und schnelle Hilfe, wenn es brennt.</p>
281      </a>
282
283      <a href="./leistungen.html#ai" data-bento="2x1" data-rv="4" data-on-mouseenter="rowEnter" data-on-mousemove="tiltMove" data-on-mouseleave="rowLeave" style="grid-column:span 2; position:relative; overflow:hidden; display:flex; align-items:center; gap:clamp(18px,2vw,30px); padding:clamp(24px,2.4vw,34px); background:var(--ac-tief,#CE320B); color:#FFFFFF; transition:background .45s ease;" style-hover="background:#FF4A18;">
284        <img decoding="async" data-ico="1" src="uploads/web4pros-design-assets/06-icon-ai-bild-video.webp?v=97afeb3f" alt="" draggable="false" style="flex:0 0 auto; width:clamp(104px,9.2vw,140px); height:auto; display:block; filter:brightness(0) invert(1); transition:transform .55s cubic-bezier(.16,1,.3,1);" width="1254" height="1254">
285        <div style="min-width:0;">
286          <div style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:#fff; margin-bottom:10px;">05 / 06 · NEU</div>
287          <h3 style="margin:0 0 8px; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(19px,2vw,28px); line-height:1.05;">AI Bild &amp; Video</h3>
288          <p style="margin:0; font-size:14px; line-height:1.55; color:#fff; text-wrap:pretty;">Visuals, Produktbilder und Clips – KI-gestützt produziert, markengerecht kuratiert.</p>
289        </div>
290        <span data-arw="1" style="position:absolute; right:22px; top:20px; font-size:19px; opacity:.6; transition:opacity .4s ease, transform .5s cubic-bezier(.16,1,.3,1);">↗</span>
291      </a>
292
293      <a href="./leistungen.html#hosting" data-bento="2x1" data-rv="5" data-on-mouseenter="rowEnter" data-on-mousemove="tiltMove" data-on-mouseleave="rowLeave" style="grid-column:span 2; position:relative; overflow:hidden; display:flex; align-items:center; gap:clamp(18px,2vw,30px); padding:clamp(24px,2.4vw,34px); background:#F1F0ED; color:#0B0B0C; transition:background .45s ease;" style-hover="background:#E8E7E3;" data-grund="hell">
294        <img decoding="async" data-ico="1" src="uploads/web4pros-design-assets/07-icon-hosting-domain.webp?v=44c36500" alt="" draggable="false" style="flex:0 0 auto; width:clamp(104px,9.2vw,140px); height:auto; display:block; transition:transform .55s cubic-bezier(.16,1,.3,1);" width="1254" height="1254">
295        <div style="min-width:0;">
296          <div style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:var(--ac,#E8380C); margin-bottom:10px;">06 / 06</div>
297          <h3 style="margin:0 0 8px; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(19px,2vw,28px); line-height:1.05;">Hosting &amp; Domain</h3>
298          <p style="margin:0; font-size:14px; line-height:1.55; color:#5F5F5F; text-wrap:pretty;">Schnelles, sicheres Hosting in Europa – inklusive Domains und Backups.</p>
299        </div>
300        <span data-arw="1" style="position:absolute; right:22px; top:20px; font-size:19px; opacity:.35; transition:opacity .4s ease, transform .5s cubic-bezier(.16,1,.3,1);">↗</span>
301      </a>
302
303    </div>
304
305  </section>
306
307  <section id="projekte" data-screen-label="Projekte" style="position:relative; z-index:5; background:#F1F0ED; color:#0B0B0C; padding:clamp(56px,8vw,112px) clamp(18px,4vw,56px) clamp(64px,9vw,128px);" data-grund="hell">
308    <div style="max-width:1440px; margin:0 auto;">
309      <div style="display:flex; align-items:flex-end; justify-content:space-between; gap:32px; flex-wrap:wrap; margin-bottom:clamp(32px,4vw,56px);">
310        <div data-rv="0">
311          <div style="display:flex; align-items:center; gap:10px; margin-bottom:20px; font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.18em; color:#6C6C6C;">02<span style="width:26px; height:1px; background:#C9C9C9;"></span></div>
312          <h2 style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(30px,4.2vw,60px); line-height:.95; letter-spacing:.005em;">Ausgewählte Projekte</h2>
313        </div>
314        <a href="./projekte.html" data-rv="1" style="display:inline-flex; align-items:center; gap:10px; color:#0B0B0C; font-size:15px; font-weight:500; border-bottom:1px solid #0B0B0C; padding-bottom:5px;" style-hover="color:var(--ac,#E8380C); border-color:var(--ac,#E8380C);">Alle Projekte ansehen <span>↗</span></a>
315      </div>
316
317      <div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr)); gap:clamp(14px,1.4vw,22px);">
318
319        <a href="./projekte.html" data-rv="0" data-on-mouseenter="cardEnter" data-on-mousemove="tiltMove" data-on-mouseleave="cardLeave" style="display:block; color:#0B0B0C;">
320          <div data-shot="1" style="position:relative; overflow:hidden; background:#E4E3DF; aspect-ratio:9/12; transition:transform .5s cubic-bezier(.16,1,.3,1), box-shadow .5s ease;">
321            <div data-zoom="1" style="position:absolute; top:0; left:0; right:0; height:100%; will-change:transform;">
322              <image-slot id="w4p-proj-1" shape="rect" fit="cover" placeholder="Screenshot Casa Bermejo" src="./profilersuzanne-screenshot-1800-msw4wr22-r0yd.webp?v=6abb84c1"></image-slot>
323            </div>
324            <div data-arrow="1" style="position:absolute; right:0; bottom:0; width:52px; height:52px; background:var(--ac-tief,#CE320B); color:#fff; display:flex; align-items:center; justify-content:center; font-size:17px; transform:translate(0,52px); transition:transform .45s cubic-bezier(.16,1,.3,1); pointer-events:none;">↗</div>
325          </div>
326          <div style="display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-top:18px;">
327            <span style="font-size:18px; font-weight:600;">Profiler Suzanne</span>
328            <span style="font-family:'IBM Plex Mono',monospace; font-size:12px; color:#6C6C6C; letter-spacing:.1em;">seit 2012</span>
329          </div>
330          <div style="margin-top:6px; font-size:14px; color:#6C6C6C;">Webdesign · WordPress · Support</div>
331        </a>
332
333        <a href="./projekte.html" data-rv="1" data-on-mouseenter="cardEnter" data-on-mousemove="tiltMove" data-on-mouseleave="cardLeave" style="display:block; color:#0B0B0C;">
334          <div data-shot="1" style="position:relative; overflow:hidden; background:#E4E3DF; aspect-ratio:9/12; transition:transform .5s cubic-bezier(.16,1,.3,1), box-shadow .5s ease;">
335            <div data-zoom="1" style="position:absolute; top:0; left:0; right:0; height:100%; will-change:transform;">
336              <image-slot id="w4p-proj-2" shape="rect" fit="cover" placeholder="Screenshot Red Star Surf" src="./wolff-screenshot-1400-msw4ywgt-7kow.webp?v=effcecb8"></image-slot>
337            </div>
338            <div data-arrow="1" style="position:absolute; right:0; bottom:0; width:52px; height:52px; background:var(--ac-tief,#CE320B); color:#fff; display:flex; align-items:center; justify-content:center; font-size:17px; transform:translate(0,52px); transition:transform .45s cubic-bezier(.16,1,.3,1); pointer-events:none;">↗</div>
339          </div>
340          <div style="display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-top:18px;">
341            <span style="font-size:18px; font-weight:600;">WOLFF CONSULTING</span>
342            <span style="font-family:'IBM Plex Mono',monospace; font-size:12px; color:#6C6C6C; letter-spacing:.1em;">2024</span>
343          </div>
344          <div style="margin-top:6px; font-size:14px; color:#6C6C6C;">Datenverarbeitung · Wordpress ·  SEO</div>
345        </a>
346
347        <a href="./projekte.html" data-rv="2" data-on-mouseenter="cardEnter" data-on-mousemove="tiltMove" data-on-mouseleave="cardLeave" style="display:block; color:#0B0B0C;">
348          <div data-shot="1" style="position:relative; overflow:hidden; background:#E4E3DF; aspect-ratio:9/12; transition:transform .5s cubic-bezier(.16,1,.3,1), box-shadow .5s ease;">
349            <div data-zoom="1" style="position:absolute; top:0; left:0; right:0; height:100%; will-change:transform;">
350              <image-slot id="w4p-proj-3" shape="rect" fit="cover" placeholder="Screenshot GoLanzarote" src="./uploads/w4p-proj-3.webp?v=3eae0002"></image-slot>
351            </div>
352            <div data-arrow="1" style="position:absolute; right:0; bottom:0; width:52px; height:52px; background:var(--ac-tief,#CE320B); color:#fff; display:flex; align-items:center; justify-content:center; font-size:17px; transform:translate(0,52px); transition:transform .45s cubic-bezier(.16,1,.3,1); pointer-events:none;">↗</div>
353          </div>
354          <div style="display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-top:18px;">
355            <span style="font-size:18px; font-weight:600;">Planet Bikes</span>
356            <span style="font-family:'IBM Plex Mono',monospace; font-size:12px; color:#6C6C6C; letter-spacing:.1em;">2024</span>
357          </div>
358          <div style="margin-top:6px; font-size:14px; color:#6C6C6C;">Tourismus · Rad Vermietung  ·  Wordpress</div>
359        </a>
360
361        <a href="./projekte.html" data-rv="3" data-on-mouseenter="cardEnter" data-on-mousemove="tiltMove" data-on-mouseleave="cardLeave" style="display:block; color:#0B0B0C;">
362          <div data-shot="1" style="position:relative; overflow:hidden; background:#E4E3DF; aspect-ratio:9/12; transition:transform .5s cubic-bezier(.16,1,.3,1), box-shadow .5s ease;">
363            <div data-zoom="1" style="position:absolute; top:0; left:0; right:0; height:100%; will-change:transform;">
364              <image-slot id="w4p-proj-4" shape="rect" fit="cover" placeholder="Screenshot Projekt 4" src="./uploads/w4p-proj-4.webp?v=99e69129"></image-slot>
365            </div>
366            <div data-arrow="1" style="position:absolute; right:0; bottom:0; width:52px; height:52px; background:var(--ac-tief,#CE320B);
366 color:#fff; display:flex; align-items:center; justify-content:center; font-size:17px; transform:translate(0,52px); transition:transform .45s cubic-bezier(.16,1,.3,1); pointer-events:none;">↗</div>
367          </div>
368          <div style="display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-top:18px;">
369            <span style="font-size:18px; font-weight:600;">Casa Verde Lanzarote</span>
370            <span style="font-family:'IBM Plex Mono',monospace; font-size:12px; color:#6C6C6C; letter-spacing:.1em;">2026</span>
371          </div>
372          <div style="margin-top:6px; font-size:14px; color:#6C6C6C;">Tourismus · Vermietung  ·  Statisch</div>
373        </a>
374
375      </div>
376    </div>
377  </section>
378
379  <section id="agentur" data-screen-label="Agentur" style="position:relative; z-index:5; background:#08090A; color:#E9E8E4; overflow:hidden; padding:0 clamp(18px,4vw,56px);" data-grund="dunkel">
380    <div style="max-width:1440px; margin:0 auto; padding:clamp(60px,8vw,120px) 0; display:grid; grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); gap:clamp(32px,5vw,72px); align-items:center;">
381      <div>
382        <div data-rv="0" style="display:flex; align-items:center; gap:10px; margin-bottom:22px; font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.18em; color:rgba(233,232,228,.5);">03<span style="width:26px; height:1px; background:rgba(255,255,255,.25);"></span></div>
383        <h2 data-rv="0" style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(32px,4.6vw,66px); line-height:.95; color:#fff;">Kleines Studio.<br>Grosse Sorgfalt<span style="color:var(--ac,#E8380C);">.</span></h2>
384        <p data-rv="1" style="margin:clamp(22px,3vw,32px) 0 0; max-width:460px; font-size:16px; line-height:1.7; color:rgba(233,232,228,.66); text-wrap:pretty;">Ich bin ein digitaler Nerd mit über 25 Jahren Erfahrung in Webdesign, Entwicklung und digitaler Strategie. Persönlich, direkt und ohne Umwege.</p>
385        <div data-rv="2" style="display:flex; gap:clamp(24px,4vw,56px); margin:clamp(30px,4vw,44px) 0; flex-wrap:wrap;">
386          <div><div data-count="150" style="font-family:'Anton',sans-serif; font-size:clamp(30px,3.4vw,44px); color:#fff; line-height:1;">150<span style="color:var(--ac,#E8380C);">+</span></div><div style="margin-top:8px; font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.16em; color:rgba(233,232,228,.5);">PROJEKTE</div></div>
387          <div><div data-count="18" style="font-family:'Anton',sans-serif; font-size:clamp(30px,3.4vw,44px); color:#fff; line-height:1;">25<span style="color: var(--ac,#E8380C);">+</span></div><div style="margin-top:8px; font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.16em; color:rgba(233,232,228,.5);">JAHRE</div></div>
388          <div><div data-count="3" style="font-family:'Anton',sans-serif; font-size:clamp(30px,3.4vw,44px); color:#fff; line-height:1;">3</div><div style="margin-top:8px; font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.16em; color:rgba(233,232,228,.5);">SPRACHEN</div></div>
389        </div>
390        <a href="./agentur.html" data-rv="3" style="display:inline-flex; align-items:center; gap:12px; border:1px solid rgba(255,255,255,.28); color:#E9E8E4; padding:16px 26px; font-size:15px; font-weight:500; transition:border-color .3s, transform .3s;" style-hover="border-color:#fff; color:#fff; transform:translateY(-2px);">Agentur kennenlernen <span>↗</span></a>
391      </div>
392      <div data-rv="1" style="position:relative;">
393        <div style="position:relative; overflow:hidden; aspect-ratio:16/11;">
394          <img decoding="async" data-el="agentur" src="./schreibtisch-msw7x61n-8jad.webp?v=d0ca6a8a" alt="Schreibtisch" style="position:absolute; inset:-8%; width:116%; height:116%; object-fit:cover; will-change:transform;">
395          <div style="position:absolute; left:0; right:0; bottom:0; height:42%; background:linear-gradient(180deg, rgba(8,9,10,0), rgba(8,9,10,.8)); pointer-events:none;"></div>
396          <div style="position:absolute; left:clamp(14px,1.8vw,22px); bottom:clamp(14px,1.8vw,22px); display:flex; align-items:center; gap:10px; font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.2em; color:#F2F1EE; pointer-events:none;"><span style="width:7px; height:7px; border-radius:50%; background:var(--ac,#E8380C); animation:w4pPulse 2.4s ease-in-out infinite;"></span>STUDIO · TAHICHE</div>
397        </div>
398        <div style="position:absolute; left:-14px; top:-14px; width:38px; height:38px; border-left:1px solid rgba(255,255,255,.5); border-top:1px solid rgba(255,255,255,.5); animation:w4pDrift 7s ease-in-out infinite;"></div>
399        <div style="position:absolute; right:-14px; bottom:-14px; width:38px; height:38px; border-right:1px solid rgba(255,255,255,.5); border-bottom:1px solid rgba(255,255,255,.5); animation:w4pDrift 7s ease-in-out 1.4s infinite;"></div>
400      </div>
401    </div>
402  </section>
403
404  <section id="kontakt" data-screen-label="Kontakt CTA" style="position:relative; z-index:5; background:#F1F0ED; color:#0B0B0C; padding:clamp(60px,8vw,116px) clamp(18px,4vw,56px);" data-grund="hell">
405    <div style="max-width: 1440px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit,minmax(300px,1fr)); gap: clamp(28px,4vw,60px); align-items: flex-end">
406      <div>
407        <div data-rv="0" style="display:flex; align-items:center; gap:10px; margin-bottom:22px; font-family:'IBM Plex Mono',monospace; font-size:12px; letter-spacing:.18em; color:#6C6C6C;">04<span style="width:26px; height:1px; background:#C9C9C9;"></span></div>
408        <h2 data-rv="0" style="margin:0; font-family:'Anton',sans-serif; font-weight:400; text-transform:uppercase; font-size:clamp(32px,5vw,72px); line-height:.95;">Lassen Sie uns etwas relevantes <span style="color:var(--ac,#E8380C);">schaffen.</span></h2>
409      </div>
410      <div data-rv="1" style="display:flex; flex-direction:column; align-items:flex-start; gap:14px;">
411        <a href="./kontakt.html#anfrage" style="display:inline-flex; align-items:center; justify-content:space-between; gap:24px; width:100%; max-width:440px; background:var(--ac-tief,#CE320B);
411 color:#fff; padding:26px 30px; font-size:18px; font-weight:500; transition:background .3s, transform .3s cubic-bezier(.16,1,.3,1);" style-hover="background:#FF4A18; transform:translateY(-3px);">Projekt anfragen <span style="font-size:16px;">↗</span></a>
412        <a href="mailto:[email protected]" style="display:inline-flex; align-items:center; justify-content:space-between; gap:24px; width:100%; max-width:440px; padding:26px 30px; font-size:18px; font-weight:500; transition:background .3s, color .3s, transform .3s cubic-bezier(.16,1,.3,1); background:#08090A; color:#F1F0ED;" style-hover="background:#141416; transform:translateY(-3px);" data-grund="dunkel">[email protected] <span style="font-size:16px;">↗</span></a>
413      </div>
414    </div>
415  </section>
416
417  </main>
418
419  <footer style="position:relative; z-index:5; background:#08090A; color:rgba(233,232,228,.72); padding:clamp(40px,5vw,64px) clamp(18px,4vw,56px) 28px;" data-grund="dunkel">
420    <div style="max-width:1440px; margin:0 auto; display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:clamp(28px,4vw,56px); padding-bottom:clamp(32px,4vw,52px); border-bottom:1px solid rgba(255,255,255,.12);">
421      <div>
422        <div style="display:flex; flex-direction:column; gap:4px; margin-bottom:20px;">
423          <span style="font-family:'Anton',sans-serif; font-size:clamp(34px,3.4vw,48px); line-height:.86; color:#FFFFFF;">Web<span style="color:var(--ac,#E8380C);">4</span>Pros</span>
424          <span style="font-family:'IBM Plex Mono',monospace; font-size:clamp(9px,.8vw,11px); letter-spacing:.44em; color:rgba(233,232,228,.5);">BUSINESS SOLUTIONS</span>
425        </div>
426        <div style="font-size:14px; line-height:1.7;">Tahiche · Lanzarote<br>Islas Canarias, España</div>
427      </div>
428      <div style="display:flex; flex-direction:column; gap:10px; font-size:14px;">
429        <div style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:rgba(233,232,228,.5); margin-bottom:6px;">SEITEN</div>
430        <a href="./projekte.html" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Projekte</a>
431        <a href="./leistungen.html" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Leistungen</a>
432        <a href="./agentur.html" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Agentur</a>
433        <a href="./kontakt.html" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Kontakt</a>
434      </div>
435      <div style="display:flex; flex-direction:column; gap:10px; font-size:14px;">
436        <div style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:rgba(233,232,228,.5); margin-bottom:6px;">RECHTLICHES</div>
437        <a href="./impressum.html" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Impressum</a>
438        <a href="./datenschutz.html" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Datenschutz</a>
439        <a href="./datenschutz.html#cookies" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">Cookies</a>
440      </div>
441      <div style="display:flex; flex-direction:column; gap:10px; font-size:14px;">
442        <div style="font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.18em; color:rgba(233,232,228,.5); margin-bottom:6px;">KONTAKT</div>
443        <a href="mailto:[email protected]" style="color:rgba(233,232,228,.72);" style-hover="color:#fff;">[email protected]</a>
444      </div>
445    </div>
446    <div style="max-width:1440px; margin:0 auto; padding-top:22px; display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap; font-family:'IBM Plex Mono',monospace; font-size:11px; letter-spacing:.14em; color:rgba(233,232,228,.5);">
447      <span>© 2026 WEB4PROS BUSINESS SOLUTIONS</span>
448      <span style="color:var(--ac,#E8380C);">+</span>
449      <span>MADE ON LANZAROTE</span>
450    </div>
451  </footer>
452
453</div>
454<script src="./w4p-runtime.js?v=87d44bf6"></script>
vendor: 1 bytes, line 454
454
455<script>
456class Component {
457  rootRef = W4P.ref();
458  stageRef = W4P.ref();
459  p = 0; mx = 0; my = 0; tmx = 0; tmy = 0; cache = {}; vel = 0; tx = 0;
460
461  q(name) {
462    const c = this.cache[name];
463    if (c && c.isConnected) return c;
464    const r = this.rootRef.current;
465    const el = r ? r.querySelector('[data-el="' + name + '"]') : null;
466    if (el) this.cache[name] = el;
467    return el;
468  }
469
470  componentDidMount() {
471    this.applyProps();
472    this.onScroll = () => {
473      this.layout();
474      const s = this.stageRef.current;
475      if (s) {
476        const r = s.getBoundingClientRect();
477        const d = r.height - window.innerHeight;
478        this.p = d > 0 ? Math.min(1, Math.max(0, -r.top / d)) : 0;
479      }
480      const nav = this.q('nav');
481      if (nav) {
482        const on = window.scrollY > 60;
483        nav.style.background = on ? 'rgba(8,9,10,.82)' : 'transparent';
484        nav.style.backdropFilter = on ? 'blur(14px)' : 'none';
485        nav.style.borderBottomColor = on ? 'rgba(255,255,255,.1)' : 'rgba(255,255,255,0)';
486        nav.style.paddingTop = on ? '10px' : '16px';
487        nav.style.paddingBottom = on ? '10px' : '16px';
488      }
489      const b = this.q('bento');
490      if (b) {
491        const w = b.clientWidth;
492        const cols = w > 980 ? 4 : (w > 560 ? 2 : 1);
493        if (this.bentoCols !== cols) {
494          this.bentoCols = cols;
495          b.style.gridTemplateColumns = 'repeat(' + cols + ',minmax(0,1fr))';
496          Array.from(b.children).forEach((el) => {
497            const t = el.getAttribute('data-bento');
498            el.style.gridColumn = 'span ' + Math.min(t === '1x1' ? 1 : 2, cols);
499            el.style.gridRow = (t === '2x2' && cols === 4) ? 'span 2' : 'span 1';
500          });
501        }
502      }
503      this.revealCheck();
504      const ag = this.q('agentur');
505      if (ag) {
506        const r2 = ag.getBoundingClientRect();
507        const t = (r2.top + r2.height / 2 - window.innerHeight / 2) / window.innerHeight;
508        ag.style.transform = 'translate3d(0,' + (t * -8).toFixed(2) + '%,0) scale(' + (1.03 + Math.min(0.04, Math.abs(t) * 0.05)).toFixed(3) + ')';
509      }
510    };
511    this.onMove = (e) => {
512      this.tmx = e.clientX / window.innerWidth - 0.5;
513      this.tmy = e.clientY / window.innerHeight - 0.5;
514      this.cx = e.clientX; this.cy = e.clientY;
515      if (this.dx == null) { this.dx = e.clientX; this.dy = e.clientY; this.rx = e.clientX; this.ry = e.clientY; }
516      this.curVisible = true;
517      const t = e.target;
518      this.overClick = !!(t && t.closest && t.closest('a,button,input,textarea,select,[role="button"]'));
519      this.overAccent = this.aufAkzent(t);
520    };
521    this.onLeaveWin = () => { this.curVisible = false; };
522    this.onDown = () => { this.curDown = true; };
523    this.onUp = () => { this.curDown = false; };
524    document.addEventListener('mouseleave', this.onLeaveWin);
525    window.addEventListener('mousedown', this.onDown);
526    window.addEventListener('mouseup', this.onUp);
527    window.addEventListener('scroll', this.onScroll, { passive: true });
528    window.addEventListener('resize', this.onScroll);
529    window.addEventListener('mousemove', this.onMove, { passive: true });
530    this.onScroll();
531    this.raf = requestAnimationFrame(this.loop);
532    this.wire();
533  }
534
535  componentDidUpdate() { this.applyProps(); this.wire(); }
536
537  componentWillUnmount() {
538    cancelAnimationFrame(this.raf);
539    clearInterval(this.timer);
540    window.removeEventListener('scroll', this.onScroll);
541    window.removeEventListener('resize', this.onScroll);
542    window.removeEventListener('mousemove', this.onMove);
543    document.removeEventListener('mouseleave', this.onLeaveWin);
544    window.removeEventListener('mousedown', this.onDown);
545    window.removeEventListener('mouseup', this.onUp);
546    delete document.body.dataset.cursor;
547    if (this.io) this.io.disconnect();
548  }
549
550  applyProps() {
551    const r = this.rootRef.current;
552    if (!r) return;
553    r.style.setProperty('--ac', this.props.accent || '#E8380C');
554
555    const want = window.matchMedia('(hover:hover) and (pointer:fine)').matches
556      && !this.editing();
557    if (want !== this.fine) {
558      this.fine = want;
559      if (want) {
560        document.body.dataset.cursor = 'on';
561      } else {
562        delete document.body.dataset.cursor;
563        const d = this.q('cur'), rg = this.q('curRing');
564        if (d) d.style.opacity = '0';
565        if (rg) rg.style.opacity = '0';
566      }
567    }
568  }
569
570  loop = () => {
571    this.raf = requestAnimationFrame(this.loop);
572    this.revealCheck();
573    this.mx += (this.tmx - this.mx) * 0.06;
574    this.my += (this.tmy - this.my) * 0.06;
575    const p = this.p;
576    const k = this.props.heroMotion == null ? 1 : this.props.heroMotion;
577    const e = p * p * (3 - 2 * p);
578
579    const img = this.q('img');
580    if (img) img.style.transform = 'translateY(-50%) translate3d(' + (this.mx * -26 - e * 4 * k).toFixed(2) + 'px,' + (this.my * -20 - e * 40 * k).toFixed(2) + 'px,0) scale(' + (1 + e * 0.5 * k).toFixed(3) + ') rotate(' + (-e * 4 * k).toFixed(2) + 'deg)';
581
582    const glow = this.q('glow');
583    if (glow) glow.style.opacity = String(0.55 + e * 0.75);
584
585    const grid = this.q('grid');
586    if (grid) {
587      grid.style.transform = 'translate3d(' + (this.mx * 18).toFixed(1) + 'px,' + (-e * 90 * k).toFixed(1) + 'px,0) scale(' + (1 + e * 0.35).toFixed(3) + ')';
588      grid.style.opacity = String(1 - e * 0.6);
589    }
590
591    const text = this.q('text');
592    if (text) text.style.transform = 'translate3d(0,' + (-e * 46 * k).toFixed(1) + 'px,0)';
593
594    const notes = this.q('notes');
595    if (notes) {
596      if (!this.noteEls || !this.noteEls.length || !this.noteEls[0].isConnected) this.noteEls = Array.from(notes.children);
597      const off = this.props.showAnnotations === false;
598      this.noteEls.forEach((el, i) => {
599        const on = !off && p > 0.14 + i * 0.19;
600        el.style.opacity = on ? '1' : '0';
601        el.style.transform = on ? 'translateX(0)' : 'translateX(90px)';
602      });
603    }
604
605    const layersEl = this.q('layers');
606    if (layersEl) {
607      if (!this.layerKids || !this.layerKids.length || !this.layerKids[0].isConnected) this.layerKids = Array.from(layersEl.children);
608      this.layerKids.forEach((el, i) => {
609        const d = (el.getAttribute('data-depth') || '0,0').split(',');
610        const dx = parseFloat(d[0]) || 0, dy = parseFloat(d[1]) || 0;
611        const f = 1 + i * 0.12;
612        el.style.transform = 'translate3d(' + (dx * e * k + this.mx * dx * 0.35).toFixed(1) + 'px,' + (dy * e * k + this.my * dy * 0.35).toFixed(1) + 'px,0) rotate(' + (dx * e * 0.02).toFixed(2) + 'deg)';
613        el.style.opacity = String(Math.max(0, 1 - e * f * 0.9));
614      });
615    }
616
617    const cue = this.q('cue');
618    if (cue) {
619      const on = p > 0.8;
620      if (this._cueOn !== on) {
621        this._cueOn = on;
622        cue.style.opacity = on ? '1' : '0';
623        cue.style.transform = on ? 'translateY(0) scale(1)' : 'translateY(-72px) scale(.84)';
624        cue.style.pointerEvents = on ? 'auto' : 'none';
625      }
626    }
627
628    const scan = this.q('scan');
629    if (scan) {
630      const sp = (p * 2) % 1;
631      scan.style.transform = 'translateY(' + (sp * window.innerHeight).toFixed(0) + 'px)';
632      scan.style.opacity = String(p > 0.02 && p < 0.98 ? 0.85 * Math.sin(sp * Math.PI) : 0);
633    }
634
635    this.fx();
636    this.cursorFx();
637
638    const bar = this.q('bar');
639    if (bar) bar.style.width = (p * 100).toFixed(1) + '%';
640    const pct = this.q('pct');
641    if (pct) {
642      const v = String(Math.round(p * 100)).padStart(3, '0');
643      if (pct.textContent !== v) pct.textContent = v;
644    }
645  };
646
647  wire() {
648    const root = this.rootRef.current;
649    if (!root) return;
650
651    this.rvList = this.rvList || [];
652    root.querySelectorAll('[data-rv]').forEach((el) => {
653      if (el.dataset.rvDone === '1') return;
654      if (el.dataset.rvOn === '1') { if (this.rvList.indexOf(el) < 0) this.rvList.push(el); return; }
655      el.dataset.rvOn = '1';
656      const d = parseFloat(el.getAttribute('data-rv')) || 0;
657      el.style.transition = 'opacity .8s cubic-bezier(.16,1,.3,1) ' + (d * 0.08).toFixed(2) + 's, transform .8s cubic-bezier(.16,1,.3,1) ' + (d * 0.08).toFixed(2) + 's';
658      const r = el.getBoundingClientRect();
659      if (r.top < window.innerHeight * 0.95) { el.dataset.rvDone = '1'; return; }
660      el.style.opacity = '0';
661      el.style.transform = 'translateY(26px)';
662      this.rvList.push(el);
663    });
664    this.revealCheck();
665  }
666
667  editing() {
668    if (this.props.effekteImEditor === true) return false;
669    return /[?&]srcmap=1/.test(location.search);
670  }
671
672  /* Liest die Hintergrundfarbe unter dem Cursor und meldet, ob sie der
673     Akzentfarbe entspricht. Ergebnis wird je Element zwischengespeichert —
674     getComputedStyle bei jeder Mausbewegung waere sonst zu teuer. */
675  zuRGB(wert) {
676    if (!wert) return null;
677    const m = wert.match(/rgba?\(([^)]+)\)/);
678    if (m) {
679      const t = m[1].split(',').map(parseFloat);
680      if (t.length > 3 && t[3] < 0.5) return null;   // zu durchsichtig -> weitersuchen
681      return [t[0], t[1], t[2]];
682    }
683    const h = wert.trim().match(/^#([0-9a-f]{6})$/i);
684    if (h) { const n = parseInt(h[1], 16); return [n >> 16 & 255, n >> 8 & 255, n & 255]; }
685    return null;
686  }
687
688  aufAkzent(el) {
689    if (!el || el.nodeType !== 1) return false;
690    if (el === this._akzEl) return this._akzRes;
691    this._akzEl = el;
692    if (!this._akzRGB) {
693      const r = this.rootRef.current;
694      const v = r ? getComputedStyle(r).getPropertyValue('--ac') : '';
695      this._akzRGB = this.zuRGB(v) || [232, 56, 12];
696    }
697    let n = el, tiefe = 0;
698    while (n && n.nodeType === 1 && tiefe++ < 12) {
699      const bg = this.zuRGB(getComputedStyle(n).backgroundColor);
700      if (bg) {
701        const d = Math.abs(bg[0] - this._akzRGB[0]) + Math.abs(bg[1] - this._akzRGB[1])
702                + Math.abs(bg[2] - this._akzRGB[2]);
703        this._akzRes = d < 120;      // deckt auch den Hover-Ton #FF4A18 ab
704        return this._akzRes;
705      }
706      n = n.parentElement;
707    }
708    this._akzRes = false;
709    return false;
710  }
711
712  cursorFx() {
713    if (!this.fine || this.dx == null) return;
714    const dot = this.q('cur'), ring = this.q('curRing');
715    if (!dot || !ring) return;
716    this.dx += (this.cx - this.dx) * 0.4;
717    this.dy += (this.cy - this.dy) * 0.4;
718    this.rx += (this.cx - this.rx) * 0.16;
719    this.ry += (this.cy - this.ry) * 0.16;
720    const on = !!this.overClick;
721    const ds = this.curDown ? 0.82 : 1;
722    const rs = this.curDown ? 0.85 : (on ? 1.45 : 1);
723    dot.style.transform = 'translate3d(' + this.dx.toFixed(1) + 'px,' + this.dy.toFixed(1) + 'px,0) scale(' + ds + ')';
724    ring.style.transform = 'translate3d(' + this.rx.toFixed(1) + 'px,' + this.ry.toFixed(1) + 'px,0) scale(' + rs + ')';
725    const op = this.curVisible ? '1' : '0';
726    if (dot.style.opacity !== op) { dot.style.opacity = op; ring.style.opacity = op; }
727    const akz = !!this.overAccent;
728    if (this._curOn !== on || this._curAkz !== akz) {
729      this._curOn = on; this._curAkz = akz;
730      // Auf orangem Grund waere der orange Cursor unsichtbar -> auf Weiss wechseln
731      const puls = akz ? 'w4pCurPulseW' : 'w4pCurPulse';
732      const kanal = akz ? '255,255,255' : '232,56,12';
733      ring.style.animation = on ? puls + ' 1.15s ease-out infinite' : 'none';
734      ring.style.borderColor = 'rgba(' + kanal + ',' + (on ? '.9' : '.5') + ')';
735      dot.style.background = akz ? '#FFFFFF' : 'var(--ac,#E8380C)';
736      dot.style.transition = 'opacity .3s ease, transform .25s cubic-bezier(.16,1,.3,1)';
737    }
738  }
739
740  layout() {
741    const mob = window.innerWidth < 760;
742    if (this.mobile === mob) return;
743    this.mobile = mob;
744    const set = (n, o) => { const el = this.q(n); if (el) Object.assign(el.style, o); };
745    const st = this.stageRef.current;
746    if (st) { st.style.height = mob ? '100vh' : '230vh'; if (mob) st.style.height = '100svh'; }
747    const sticky = this.q('sticky');
748    if (sticky) { sticky.style.height = '100vh'; if (mob) sticky.style.height = '100svh'; }
749    set('img', mob
750      ? { right: '-34%', top: '50%', width: '168%', opacity: '.32' }
751      : { right: '-3%', top: '50%', width: 'min(66vw,1400px)', opacity: '1' });
752    set('layers', { display: mob ? 'none' : 'block' });
753    set('notes', { display: mob ? 'none' : 'flex' });
754    set('glow', { opacity: mob ? '.5' : '1' });
755    set('text', { paddingTop: mob ? '92px' : '0', paddingBottom: mob ? '96px' : '0' });
756    set('navlinks', { display: mob ? 'none' : 'flex' });
757    set('delang', { display: mob ? 'none' : 'flex' });
758    set('burger', { display: mob ? 'flex' : 'none' });
759    const foot = this.q('foot');
760    if (foot && foot.children[1]) foot.children[1].style.display = mob ? 'none' : 'flex';
761    if (foot) foot.style.fontSize = mob ? '12px' : '';
762    if (!mob) { const m = this.q('menu'); if (m) m.style.display = 'none'; }
763  }
764
765  fx() {
766    const root = this.rootRef.current;
767    if (!root) return;
768    const se = document.scrollingElement || document.documentElement;
769    const y = se.scrollTop;
770    if (this.lastY == null) this.lastY = y;
771    this.vel += ((y - this.lastY) - this.vel) * 0.16;
772    this.lastY = y;
773
774    const tb = this.q('topbar');
775    if (tb) {
776      const max = se.scrollHeight - window.innerHeight;
777      tb.style.width = (max > 0 ? Math.min(100, (y / max) * 100) : 0).toFixed(2) + '%';
778    }
779
780    const tk = this.q('ticker');
781    if (tk) {
782      if (!this.tw) this.tw = tk.scrollWidth / 2;
783      const dir = this.vel < -0.6 ? -1 : 1;
784      this.tx = (this.tx || 0) - (0.5 + Math.min(7, Math.abs(this.vel) * 0.14)) * dir;
785      if (this.tw) {
786        if (this.tx <= -this.tw) this.tx += this.tw;
787        if (this.tx > 0) this.tx -= this.tw;
788      }
789      tk.style.transform = 'translate3d(' + this.tx.toFixed(1) + 'px,0,0)';
790    }
791
792    if (this.counters == null) this.counters = [];
793    if (!this.counters.length && !this.countersFound) {
794      const q = root.querySelectorAll('[data-count]');
795      if (q.length) { this.counters = Array.from(q); this.countersFound = true; }
796    }
797    if (this.counters.length) {
798      this.counters = this.counters.filter((c) => {
799        if (c.getBoundingClientRect().top < window.innerHeight * 0.88) { this.countUp(c); return false; }
800        return true;
801      });
802    }
803
804    this.tick = (this.tick || 0) + 1;
805    if (this.tick % 20 === 0) this.sizeShots();
806  }
807
808  sizeShots() {
809    const root = this.rootRef.current;
810    if (!root) return;
811    if (!this.zooms || !this.zooms.length || !this.zooms[0].isConnected) this.zooms = Array.from(root.querySelectorAll('#projekte [data-zoom]'));
812    this.zooms.forEach((el) => {
813      const box = el.parentElement;
814      if (!box) return;
815      const cw = box.clientWidth, ch = box.clientHeight;
816      if (!cw || !ch) return;
817      const slot = el.querySelector('image-slot');
818      const img = slot && slot.shadowRoot ? slot.shadowRoot.querySelector('img') : null;
819      let h = ch;
820      if (img && img.naturalWidth && img.naturalHeight && img.style.display !== 'none') {
821        h = Math.max(ch, Math.round(cw * img.naturalHeight / img.naturalWidth));
822      }
823      el._scroll = Math.max(0, h - ch);
824      const px = h + 'px';
825      if (el.style.height !== px) el.style.height = px;
826    });
827  }
828
829  countUp(el) {
830    if (el.dataset.counted) return;
831    const node = el.firstChild;
832    if (!node || node.nodeType !== 3) return;
833    const target = parseFloat(String(node.nodeValue).replace(/[^\d.]/g, ''));
834    if (!isFinite(target)) return;
835    el.dataset.counted = '1';
836    const t0 = performance.now(), dur = 1300;
837    const step = (t) => {
838      const k = Math.min(1, (t - t0) / dur);
839      node.nodeValue = String(Math.round(target * (1 - Math.pow(1 - k, 3))));
840      if (k < 1) requestAnimationFrame(step);
841    };
842    node.nodeValue = '0';
843    requestAnimationFrame(step);
844  }
845
846  revealCheck() {
847    if (!this.rvList || !this.rvList.length) return;
848    const h = window.innerHeight;
849    this.rvList = this.rvList.filter((el) => {
850      if (!el.isConnected) return false;
851      if (el.getBoundingClientRect().top > h * 0.92) return true;
852      el.style.opacity = '1';
853      el.style.transform = 'none';
854      el.dataset.rvDone = '1';
855      return false;
856    });
857  }
858
859  renderVals() {
860    return {
861      rootRef: this.rootRef,
862      stageRef: this.stageRef,
863      navEnter: (e) => {
864        const u = e.currentTarget.querySelector('[data-ul]');
865        if (u) { u.style.transformOrigin = 'left center'; u.style.transform = 'scaleX(1)'; }
866      },
867      navLeave: (e) => {
868        const u = e.currentTarget.querySelector('[data-ul]');
869        if (u) { u.style.transformOrigin = 'right center'; u.style.transform = 'scaleX(0)'; }
870      },
871      rowEnter: (e) => {
872        const i = e.currentTarget.querySelector('[data-ico]');
873        if (i) i.style.transform = 'scale(1.07)';
874        const bg = e.currentTarget.querySelector('[data-bg]');
875        if (bg) { bg.style.transform = 'scale(1.05)'; bg.style.opacity = '1'; }
876        const a = e.currentTarget.querySelector('[data-arw]');
877        if (a) { a.style.opacity = '1'; a.style.transform = 'translate(4px,-4px)'; }
878      },
879      rowLeave: (e) => {
880        const i = e.currentTarget.querySelector('[data-ico]');
881        if (i) i.style.transform = 'none';
882        const bg = e.currentTarget.querySelector('[data-bg]');
883        if (bg) { bg.style.transform = 'none'; bg.style.opacity = '.9'; }
884        const a = e.currentTarget.querySelector('[data-arw]');
885        if (a) { a.style.opacity = '.35'; a.style.transform = 'none'; }
886        const el = e.currentTarget;
887        el.style.transition = 'transform .6s cubic-bezier(.16,1,.3,1)';
888        el.style.transform = 'none';
889      },
890      toggleMenu: () => {
891        const m = this.q('menu'), b = this.q('burger');
892        if (!m) return;
893        const open = m.style.display !== 'flex';
894        m.style.display = open ? 'flex' : 'none';
895        if (b) b.textContent = open ? 'SCHLIESSEN' : 'MENÜ';
896        document.body.style.overflow = open ? 'hidden' : '';
897      },
898      closeMenu: () => {
899        const m = this.q('menu'), b = this.q('burger');
900        if (m) m.style.display = 'none';
901        if (b) b.textContent = 'MENÜ';
902        document.body.style.overflow = '';
903      },
904      cardEnter: (e) => {
905        const z = e.currentTarget.querySelector('[data-zoom]');
906        if (z && !this.editing()) {
907          this.sizeShots();
908          const d = z._scroll || 0;
909          if (d > 4) {
910            z.style.transition = 'transform ' + Math.min(7, Math.max(1.4, d / 240)).toFixed(2) + 's linear';
911            z.style.transform = 'translate3d(0,' + -d + 'px,0)';
912          }
913        }
914        const a = e.currentTarget.querySelector('[data-arrow]');
915        if (a) a.style.transform = 'translate(0,0)';
916        const box = e.currentTarget.querySelector('[data-shot]');
917        if (box) { box.style.transform = 'translateY(-5px)'; box.style.boxShadow = '0 30px 60px rgba(11,11,12,.28)'; }
918      },
919      cardLeave: (e) => {
920        const z = e.currentTarget.querySelector('[data-zoom]');
921        if (z) { z.style.transition = 'transform .9s cubic-bezier(.16,1,.3,1)';
921 z.style.transform = 'translate3d(0,0,0)'; }
922        const a = e.currentTarget.querySelector('[data-arrow]');
923        if (a) a.style.transform = 'translate(0,52px)';
924        const box = e.currentTarget.querySelector('[data-shot]');
925        if (box) { box.style.transform = 'none'; box.style.boxShadow = 'none'; }
926        const el = e.currentTarget;
927        el.style.transition = 'transform .6s cubic-bezier(.16,1,.3,1)';
928        el.style.transform = 'none';
929      },
930      tiltMove: (e) => {
931        const el = e.currentTarget;
932        const r = el.getBoundingClientRect();
933        const x = (e.clientX - r.left) / r.width - 0.5;
934        const y = (e.clientY - r.top) / r.height - 0.5;
935        el.style.transition = 'transform .2s ease-out';
936        el.style.transform = 'perspective(1000px) rotateX(' + (-y * 3.2).toFixed(2) + 'deg) rotateY(' + (x * 3.2).toFixed(2) + 'deg) translateY(-4px)';
937      }
938    };
939  }
940}
941W4P.mount(Component, {"accent": "#E8380C", "heroMotion": 1, "showAnnotations": true, "effekteImEditor": false});
942</script>
942
943</body>
944</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.