diff --git a/public/project pics/emailsorter.png b/public/project pics/emailsorter.png new file mode 100644 index 0000000..28eee0f Binary files /dev/null and b/public/project pics/emailsorter.png differ diff --git a/src/App.tsx b/src/App.tsx index 5bcd920..5f6e190 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Index from "./pages/Index"; import ContactPage from "./pages/Contact"; +import AGBPage from "./pages/AGB"; import NotFound from "./pages/NotFound"; const queryClient = new QueryClient(); @@ -18,6 +19,7 @@ const App = () => ( } /> } /> + } /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} } /> diff --git a/src/components/Contact.tsx b/src/components/Contact.tsx index fdbf344..60c8783 100644 --- a/src/components/Contact.tsx +++ b/src/components/Contact.tsx @@ -36,13 +36,13 @@ const Contact = () => { {/* Contact Info */}
- + - hello@webklar.de + support@webklar.com - + - +49 123 456 78 + 0170 4969375
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx index de0791a..2686b5c 100644 --- a/src/components/Hero.tsx +++ b/src/components/Hero.tsx @@ -1,6 +1,6 @@ import { useNavigate } from "react-router-dom"; import { ArrowRight } from "lucide-react"; -import { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import Silk from "@/components/Silk"; import CountUp from "@/components/CountUp"; @@ -15,10 +15,28 @@ const SPARKLE_SVG = ( ); function DemoButtonLetters({ text }: { text: string }) { + // #region agent log + const chars = text.split(""); + const spaceIndex = chars.findIndex((c) => c === " "); + const lastIndex = chars.length - 1; + const lastChar = chars[lastIndex]; + fetch("http://127.0.0.1:7244/ingest/72f53105-0a54-4d4c-a295-fb93aa72afcc", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + location: "Hero.tsx:DemoButtonLetters", + message: "Letter split for button text", + data: { text, len: chars.length, spaceIndex, spaceChar: spaceIndex >= 0 ? chars[spaceIndex] : null, lastIndex, lastChar }, + timestamp: Date.now(), + sessionId: "debug-session", + hypothesisId: "A,C", + }), + }).catch(() => {}); + // #endregion return ( <> - {text.split("").map((char, i) => ( - + {chars.map((char, i) => ( + {char} ))} @@ -31,6 +49,31 @@ const FOUNDING_DATE = new Date("2026-01-25"); // Samstag, 25. Januar 2026 const Hero = () => { const navigate = useNavigate(); const [companyAge, setCompanyAge] = useState(""); + const secondBtnRef = useRef(null); + + useEffect(() => { + const el = secondBtnRef.current; + if (!el) return; + const firstTxtWrapper = el.querySelector(".txt-wrapper"); + const letters = firstTxtWrapper ? firstTxtWrapper.querySelectorAll(".btn-letter") : []; + const spaceIdx = 8; + const lastIdx = 16; + const wSpace = letters[spaceIdx]?.getBoundingClientRect?.()?.width ?? -1; + const wLast = letters[lastIdx]?.getBoundingClientRect?.()?.width ?? -1; + fetch("http://127.0.0.1:7244/ingest/72f53105-0a54-4d4c-a295-fb93aa72afcc", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + location: "Hero.tsx:useEffect:measure", + message: "Measured btn-letter widths (space + last)", + data: { letterCount: letters.length, wSpace, wLast, spaceIdx, lastIdx }, + timestamp: Date.now(), + sessionId: "debug-session", + runId: "post-fix", + hypothesisId: "B,D,E", + }), + }).catch(() => {}); + }, []); useEffect(() => { const calculateAge = () => { @@ -113,21 +156,26 @@ const Hero = () => {
diff --git a/src/components/ProblemSection.tsx b/src/components/ProblemSection.tsx index e4b90a9..b491817 100644 --- a/src/components/ProblemSection.tsx +++ b/src/components/ProblemSection.tsx @@ -58,7 +58,7 @@ const ProblemSection = () => { {problems.map((problem, index) => (
diff --git a/src/components/ProjectShowcase.tsx b/src/components/ProjectShowcase.tsx index 6905758..a9d2a83 100644 --- a/src/components/ProjectShowcase.tsx +++ b/src/components/ProjectShowcase.tsx @@ -1,30 +1,42 @@ import { ArrowUpRight } from "lucide-react"; -const projects = [ +type Project = { + title: string; + description: string; + image: string; + url: string; +}; + +const projects: Project[] = [ { - title: "Triple AI", - description: "Webentwicklung / UI Design / Custom Code", - image: "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&h=600&fit=crop", + title: "Email Sorter", + description: "E-Mails automatisch sortieren", + image: "/project%20pics/emailsorter.png", + url: "https://emailsorter.webklar.com/", }, { title: "Neutral", description: "Webentwicklung / Custom Code", image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&h=600&fit=crop", + url: "#", }, { title: "Verbatim Labs", description: "Webentwicklung / UI Design / Custom Code", image: "https://images.unsplash.com/photo-1559028012-481c04fa702d?w=800&h=600&fit=crop", + url: "#", }, { title: "JMK Engineers", description: "Webentwicklung / UI Design / Custom Code", image: "https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=800&h=600&fit=crop", + url: "#", }, { title: "GOODZ Club", description: "Webentwicklung / Custom Code / Lokalisierung", image: "https://images.unsplash.com/photo-1542744094-3a31f272c490?w=800&h=600&fit=crop", + url: "#", }, ]; @@ -45,7 +57,9 @@ const ProjectShowcase = () => { {projects.map((project, index) => ( diff --git a/src/components/SolutionSection.tsx b/src/components/SolutionSection.tsx index 4cd84cc..9c0bbee 100644 --- a/src/components/SolutionSection.tsx +++ b/src/components/SolutionSection.tsx @@ -66,7 +66,7 @@ const SolutionSection = () => { {/* Right Content - Visual Element */}
-
+
Das Ergebnis

diff --git a/src/index.css b/src/index.css index b2ace32..0a43abc 100644 --- a/src/index.css +++ b/src/index.css @@ -159,6 +159,32 @@ background-color: hsl(var(--background)); } + /* Leichter roter Tint auf Inhaltsblöcken der Problem-Sektion */ + .problem-section-tint { + position: relative; + } + .problem-section-tint::before { + content: ""; + position: absolute; + inset: 0; + background-color: rgb(239 68 68 / 0.06); + pointer-events: none; + border-radius: inherit; + } + + /* Leichter blauer Tint auf dem Ergebnis-Block der Lösungs-Sektion */ + .solution-section-tint { + position: relative; + } + .solution-section-tint::before { + content: ""; + position: absolute; + inset: 0; + background-color: rgb(34 211 238 / 0.06); + pointer-events: none; + border-radius: inherit; + } + /* Minimal glass nav */ .glass-nav { @apply backdrop-blur-xl border-b; @@ -375,7 +401,7 @@ flex-shrink: 0; overflow: hidden; min-width: 0; - padding-right: 2px; + padding-right: 6px; } .txt-width-helper { @@ -390,6 +416,10 @@ animation: none; } + .btn-letter-space { + min-width: 0.25em; + } + .txt-1, .txt-2 { position: absolute; diff --git a/src/pages/AGB.tsx b/src/pages/AGB.tsx new file mode 100644 index 0000000..abcff56 --- /dev/null +++ b/src/pages/AGB.tsx @@ -0,0 +1,292 @@ +import { Link } from "react-router-dom"; +import { Button } from "@/components/ui/button"; +import { ArrowLeft, FileText } from "lucide-react"; + +const contractDivider = ( +
+); + +const AGB = () => { + return ( +
+ {/* Header */} +
+
+
+ + + Webklar + + + + + +
+
+
+ + {/* Main Content */} +
+
+
+ {/* Page Header */} +
+
+ + Vertrag +
+

+ Kaufvertrag – WEBklar +

+

+ (Modularer Projektvertrag) +

+
+

zwischen

+

WEBklar
(im Folgenden „Anbieter“)

+

und

+

Kunde laut Angebot
(im Folgenden „Kunde“)

+
+
+ + {/* Contract Content */} +
+ {/* 1. Vertragsgegenstand */} +
+

+ 1. Vertragsgegenstand +

+
    +
  1. Gegenstand dieses Vertrages ist die Erbringung der im Angebot definierten Leistungen.
  2. +
  3. Der Vertrag besteht aus diesem Grundvertrag sowie den ausgewählten Leistungsmodulen.
  4. +
  5. Maßgeblich ist das jeweils angenommene Angebot von WEBklar.
  6. +
+
+ {contractDivider} + + {/* 2. Leistungsart */} +
+

+ 2. Leistungsart +

+
    +
  1. Sämtliche Leistungen von WEBklar stellen Dienst- und Entwicklungsleistungen dar.
  2. +
  3. Ein bestimmter wirtschaftlicher, technischer oder rechtlicher Erfolg wird nicht geschuldet.
  4. +
  5. WEBklar erbringt keinen laufenden Betrieb, sofern dieser nicht explizit vereinbart wurde.
  6. +
+
+ {contractDivider} + + {/* 3. Leistungsmodul A – Webseite */} +
+

+ 3. Leistungsmodul A – Webseite (einmalig) +

+

(aktiv, wenn im Angebot enthalten)

+
    +
  1. WEBklar erstellt eine individuelle Webseite gemäß Angebot.
  2. +
  3. Die Umsetzung erfolgt nach den vom Kunden gelieferten Inhalten und Vorgaben.
  4. +
  5. Zusätzliche Leistungen wie Domain, Hosting, Wartung oder SEO sind nicht Bestandteil, sofern sie nicht gesondert beauftragt wurden.
  6. +
  7. Der Kunde ist nicht berechtigt, Änderungen am Quellcode selbst vorzunehmen.
  8. +
  9. Änderungen erfolgen ausschließlich durch WEBklar gegen gesonderte Vergütung.
  10. +
+
+ {contractDivider} + + {/* 4. Leistungsmodul B – Automatisierung / Virtualisierung */} +
+

+ 4. Leistungsmodul B – Automatisierung / Virtualisierung (einmalig) +

+

(aktiv, wenn im Angebot enthalten)

+
    +
  1. WEBklar entwickelt individuelle Automatisierungen, Apps oder Virtualisierungssysteme.
  2. +
  3. Die Leistung stellt eine reine Entwicklungsleistung dar.
  4. +
  5. Optional kann eine Beratungsleistung Bestandteil des Projektes sein.
  6. +
  7. Ein laufender Betrieb, Monitoring oder Wartung ist nicht geschuldet, außer dies wurde explizit vereinbart.
  8. +
  9. Der Kunde entscheidet über Inhalte, Daten und Prozesse und trägt dafür die rechtliche Verantwortung.
  10. +
+
+ {contractDivider} + + {/* 5. Leistungsmodul C – Hosting */} +
+

+ 5. Leistungsmodul C – Hosting (jährlich) +

+

(aktiv, wenn im Angebot enthalten)

+
    +
  1. WEBklar stellt optional Hosting-Leistungen zur Verfügung.
  2. +
  3. Hostingverträge haben eine jährliche Laufzeit und verlängern sich automatisch, sofern nicht fristgerecht gekündigt wird.
  4. +
  5. WEBklar ist berechtigt, externe Anbieter (z. B. Rechenzentren) einzusetzen.
  6. +
  7. WEBklar übernimmt keine Haftung für Ausfälle externer Anbieter.
  8. +
+
+ {contractDivider} + + {/* 6. Quellcode und Eigentum */} +
+

+ 6. Quellcode und Eigentum +

+
+
+

6.1 Webseite

+
    +
  1. Der Kunde erhält ein einfaches, zeitlich unbegrenztes Nutzungsrecht an der fertigen Webseite.
  2. +
  3. Der Quellcode der Webseite wird nur auf ausdrückliche Anfrage und nach Vereinbarung herausgegeben.
  4. +
  5. Ohne Vereinbarung verbleibt der Quellcode bei WEBklar und wird archiviert.
  6. +
+
+
+

6.2 Apps, Automatisierungen und Backend

+
    +
  1. Der Quellcode von Apps, Automatisierungen und Backend-Systemen verbleibt vollständig bei WEBklar.
  2. +
  3. Eine Herausgabe erfolgt ausschließlich nach gesonderter schriftlicher Vereinbarung.
  4. +
  5. Der Kunde erhält lediglich Zugriff auf die Bedienoberfläche bzw. das Frontend.
  6. +
+
+
+
+ {contractDivider} + + {/* 7. Mitwirkungspflichten */} +
+

+ 7. Mitwirkungspflichten des Kunden +

+
    +
  1. Der Kunde stellt alle benötigten Inhalte, Daten und Freigaben rechtzeitig bereit.
  2. +
  3. Verzögerungen durch fehlende Mitwirkung gehen nicht zu Lasten von WEBklar.
  4. +
  5. WEBklar ist nicht verpflichtet, rechtliche Prüfungen der Inhalte vorzunehmen.
  6. +
+
+ {contractDivider} + + {/* 8. Abnahme */} +
+

+ 8. Abnahme +

+
    +
  1. Nach Fertigstellung wird dem Kunden die Leistung zur Abnahme bereitgestellt.
  2. +
  3. Erfolgt innerhalb von 14 Tagen keine Rückmeldung, gilt die Leistung als abgenommen.
  4. +
  5. Nach Abnahme sind nur noch kostenpflichtige Änderungen möglich.
  6. +
+
+ {contractDivider} + + {/* 9. Vergütung und Zahlung */} +
+

+ 9. Vergütung und Zahlung +

+
    +
  1. Die Vergütung ergibt sich aus dem Angebot.
  2. +
  3. Projektleistungen sind nach Vereinbarung fällig.
  4. +
  5. Hosting-Leistungen sind jährlich im Voraus zu zahlen.
  6. +
+
+ {contractDivider} + + {/* 10. Zahlungsverzug */} +
+

+ 10. Zahlungsverzug +

+
    +
  1. Bei Zahlungsverzug erfolgen bis zu zwei Mahnungen.
  2. +
  3. Danach ist WEBklar berechtigt: +
      +
    • Leistungen zu sperren
    • +
    • Verzugszinsen zu berechnen
    • +
    • den Vertrag außerordentlich zu kündigen
    • +
    +
  4. +
+
+ {contractDivider} + + {/* 11. Haftung */} +
+

+ 11. Haftung +

+
    +
  1. WEBklar haftet nur bei Vorsatz und grober Fahrlässigkeit.
  2. +
  3. Keine Haftung für: +
      +
    • Umsatzausfälle
    • +
    • Datenverlust
    • +
    • Systemausfälle
    • +
    • externe Dienste
    • +
    +
  4. +
  5. Die Haftung ist der Höhe nach auf den Auftragswert begrenzt.
  6. +
+
+ {contractDivider} + + {/* 12. Kündigung */} +
+

+ 12. Kündigung +

+
    +
  1. Laufzeitverträge (z. B. Hosting, Wartung) können zum Ende der jeweiligen Laufzeit gekündigt werden.
  2. +
  3. Das Recht zur außerordentlichen Kündigung bleibt unberührt.
  4. +
+
+ {contractDivider} + + {/* 13. Referenzen */} +
+

+ 13. Referenzen +

+

+ WEBklar darf das Projekt nur nach ausdrücklicher Zustimmung des Kunden als Referenz verwenden. +

+
+ {contractDivider} + + {/* 14. Schlussbestimmungen */} +
+

+ 14. Schlussbestimmungen +

+
    +
  1. Es gilt deutsches Recht.
  2. +
  3. Gerichtsstand ist der Sitz von WEBklar, soweit zulässig.
  4. +
  5. Sollten einzelne Bestimmungen unwirksam sein, bleibt der Vertrag im Übrigen wirksam.
  6. +
+
+
+ + {/* Back / Contact */} +
+ + + + + + +
+
+
+
+
+ ); +}; + +export default AGB; diff --git a/src/pages/Contact.tsx b/src/pages/Contact.tsx index 8ed07a1..eed2979 100644 --- a/src/pages/Contact.tsx +++ b/src/pages/Contact.tsx @@ -171,19 +171,19 @@ const Contact = () => {