zwischenstnad

This commit is contained in:
2025-10-06 17:01:41 +00:00
parent dc1de8cd39
commit 747e6dae3e
5 changed files with 298 additions and 30 deletions

View File

@@ -28,6 +28,7 @@ export const headerLinks: HeaderLink[] = [
{ label: "Überblick", sectionId: "leistungen" }, { label: "Überblick", sectionId: "leistungen" },
{ label: "Voicebot", sectionId: "voicebot-demo" }, { label: "Voicebot", sectionId: "voicebot-demo" },
{ label: "Chatbot", sectionId: "chatbot-demo" }, { label: "Chatbot", sectionId: "chatbot-demo" },
{ label: "FAQ", sectionId: "faq" },
{ label: "Angebote", sectionId: "angebote" }, { label: "Angebote", sectionId: "angebote" },
{ label: "Kontakt", sectionId: "kontakt", type: "button" }, { label: "Kontakt", sectionId: "kontakt", type: "button" },
] ]

View File

@@ -2,10 +2,12 @@
import CrinkledSection from "../CrinkledSection.svelte" import CrinkledSection from "../CrinkledSection.svelte"
import Input from "../widgets/Input.svelte" import Input from "../widgets/Input.svelte"
import { apiBaseURL } from "../../../config" import { apiBaseURL } from "../../../config"
import SectionTitle from "../widgets/SectionTitle.svelte"
let firstName = "" let firstName = ""
let lastName = "" let lastName = ""
let message = "" let message = ""
let email = ""
let submitting = false let submitting = false
let responseMessage = "" let responseMessage = ""
let responseType: "success" | "error" | "" = "" let responseType: "success" | "error" | "" = ""
@@ -34,6 +36,9 @@
const onMessageChange = updateField((value) => { const onMessageChange = updateField((value) => {
message = value message = value
}) })
const onEmailChange = updateField((value) => {
email = value
})
const submitContact = async () => { const submitContact = async () => {
if (submitting) return if (submitting) return
@@ -89,15 +94,12 @@
id="kontakt" id="kontakt"
> >
<div class="contact-wrapper"> <div class="contact-wrapper">
<div class="copy"> <SectionTitle
<small>Kontakt</small> brightBackground={true}
<h2>Jetzt unverbindlich anfragen</h2> title="Kontaktformular"
<p> subtitle="Wir sind für Sie da"
Sie haben Fragen oder wollen Ihr Projekt direkt besprechen? <br /> description="Füllen Sie das Formular aus und wir melden uns zeitnah bei Ihnen."
Schreiben Sie uns wir antworten innerhalb von 24&nbsp;Stunden und zeigen Ihnen den schnellsten />
Weg zum produktiven Chat- oder Voicebot.
</p>
</div>
<form <form
class="contact-form" class="contact-form"
on:submit|preventDefault={submitContact} on:submit|preventDefault={submitContact}
@@ -126,6 +128,18 @@
classList="contact-input" classList="contact-input"
/> />
</div> </div>
<div class="row">
<Input
id="contact-email"
name="E-Mail"
type="text"
placeholder="E-Mail"
bind:value={email}
onChange={onEmailChange}
disabled={submitting}
classList="contact-input"
/>
</div>
<div class="row"> <div class="row">
<Input <Input
id="contact-message" id="contact-message"

View File

@@ -0,0 +1,253 @@
<script lang="ts">
import CrinkledSection from "../CrinkledSection.svelte"
import Icon from "../widgets/Icon.svelte"
import { mdiChevronDown, mdiChevronUp } from "@mdi/js"
import SectionTitle from "../widgets/SectionTitle.svelte"
const faqs: Array<{ question: string; answer: string }> = [
{
question: "Wie schnell sind wir mit Kontextwerk live?",
answer: "Ein FAQ-Chatbot ist in 35 Tagen einsatzbereit, komplexere Voice- oder Multichannel-Lösungen benötigen je nach Integrationen 36 Wochen. Ein klarer Projektplan mit festen Meilensteinen sorgt dafür, dass Sie jederzeit den Überblick behalten.",
},
{
question: "Brauchen wir eigene Entwickler oder IT-Ressourcen?",
answer: "Nein im Starter-Paket übernehmen wir Analyse, Implementierung, Hosting und Optimierung vollständig. Wenn Sie später selbst eingreifen möchten, schulen wir Ihr Team und übergeben Code sowie Container-Artefakte.",
},
{
question: "Welche Sprachen, Kanäle und Anwendungsfälle sind möglich?",
answer: "Unsere Bots sprechen über 90 Sprachen und unterstützen Website-Chat, WhatsApp, Slack, MS Teams, Telefon sowie WebRTC. Typische Use-Cases: Hotline-Entlastung, Lead-Qualifizierung, internes Wissensportal oder Außendienst-Support.",
},
{
question: "Wie sicher sind unsere Daten?",
answer: "Alle Daten liegen verschlüsselt in einem deutschen Rechenzentrum (ISO 27001). Wir schließen einen DSGVO-konformen AVV und nutzen TLS 1.3, rollenbasierte Zugriffe und optionale On-Premise-Deployments, falls Sie maximale Datenhoheit wünschen.",
},
{
question: "Welche messbaren Ergebnisse können wir erwarten?",
answer: "Wir tracken KPIs wie Deflection-Rate, AHT und CSAT in Echtzeit. Typische Effekte: bis zu 40 % weniger Hotline-Aufkommen, +30 % Lead-Conversion und messbar höhere Kundenzufriedenheit. Monatliche Reports machen den Erfolg transparent.",
},
]
let activeIndex: number | null = 0
const toggle = (index: number) => {
activeIndex = activeIndex === index ? null : index
}
const answerId = (index: number) => `faq-answer-${index}`
</script>
<CrinkledSection
brightBackground={true}
border={true}
>
{#snippet contentSnippet()}
<section
class="faq-row"
id="faq"
>
<div class="faq-wrapper">
<SectionTitle
brightBackground={true}
subtitle="FAQ"
title="Häufige Fragen"
description="Von Implementierung bis Betrieb: Wir haben die wichtigsten Fragen gesammelt und liefern klare Antworten für alles andere können Sie uns kontaktieren, oder einen unserer Bots fragen."
/>
<div class="faq-list">
{#each faqs as faq, index}
<article
class="faq-item"
class:expanded={activeIndex === index}
>
<button
class="faq-question"
type="button"
aria-expanded={activeIndex === index}
aria-controls={answerId(index)}
onclick={() => toggle(index)}
>
<span>{faq.question}</span>
<span class="faq-icon">
<Icon
path={activeIndex === index ? mdiChevronUp : mdiChevronDown}
size="1.2rem"
/>
</span>
</button>
<div
class="faq-answer"
id={answerId(index)}
style={`max-height: ${activeIndex === index ? "420px" : "0"};`}
aria-hidden={activeIndex === index ? "false" : "true"}
>
<p>{faq.answer}</p>
</div>
</article>
{/each}
</div>
</div>
</section>
{/snippet}
</CrinkledSection>
<style lang="less">
@import "../../assets/css/variables.less";
.faq-row {
display: flex;
justify-content: center;
background-color: var(--neutral-white);
color: var(--text-invers-100);
width: 100%;
padding: 4.8rem 0;
.faq-wrapper {
max-width: var(--small-max-width);
width: 100%;
display: flex;
flex-direction: column;
gap: 2.8rem;
margin: 0 auto;
padding: 0 var(--horizontal-default-margin);
}
}
.faq-list {
display: flex;
flex-direction: column;
gap: 1.6rem;
}
.faq-item {
position: relative;
border-radius: 1.25rem;
background:
radial-gradient(130% 160% at 15% -20%, rgba(173, 81, 76, 0.12) 0%, rgba(255, 255, 255, 0.94) 65%),
rgba(255, 255, 255, 0.96);
border: 1px solid rgba(173, 81, 76, 0.12);
box-shadow:
0 20px 48px rgba(13, 12, 12, 0.08),
inset 0 0 0 1px rgba(255, 255, 255, 0.6);
overflow: hidden;
transition:
border-color 0.3s ease,
box-shadow 0.3s ease,
transform 0.3s ease;
&::after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(
145deg,
rgba(173, 81, 76, 0.12) 0%,
rgba(255, 255, 255, 0.75) 40%,
transparent 95%
);
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
}
&:hover,
&.expanded {
border-color: rgba(173, 81, 76, 0.38);
box-shadow:
0 26px 56px rgba(13, 12, 12, 0.12),
inset 0 0 0 1px rgba(255, 255, 255, 0.75);
transform: translateY(-4px);
&::after {
opacity: 1;
}
}
}
.faq-question {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
gap: 1.6rem;
padding: 1.4rem 1.8rem;
background: none;
border: none;
color: var(--text-invers-100);
font: inherit;
text-align: left;
cursor: pointer;
position: relative;
z-index: 1;
span:first-child {
font-size: 1.05rem;
font-weight: 600;
line-height: 1.45;
color: inherit;
transition: color 0.3s ease;
}
.faq-icon {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 50%;
background: rgba(173, 81, 76, 0.12);
box-shadow: inset 0 0 0 1px rgba(173, 81, 76, 0.28);
transition:
background 0.3s ease,
transform 0.3s ease,
box-shadow 0.3s ease;
}
}
.faq-item:hover span:first-child {
color: var(--primary-200);
}
.faq-item.expanded span:first-child {
color: var(--primary-100);
}
.faq-item.expanded .faq-icon {
background: rgba(255, 82, 82, 0.2);
box-shadow: inset 0 0 0 1px rgba(255, 82, 82, 0.4);
transform: rotate(180deg);
}
.faq-answer {
overflow: hidden;
transition: max-height 0.35s ease;
padding: 0 1.8rem;
p {
margin: 0 0 1.6rem 0;
line-height: 1.6;
color: rgba(47, 72, 88, 0.9);
}
}
.faq-item:not(.expanded) .faq-answer {
padding-bottom: 0;
}
@media @mobile {
.faq-row {
padding: 3.6rem 0;
}
.faq-wrapper {
gap: 2rem;
}
.faq-question {
padding: 1.2rem 1.4rem;
}
.faq-answer {
padding: 0 1.4rem;
}
}
</style>

View File

@@ -2,7 +2,7 @@
import CrinkledSection from "../CrinkledSection.svelte" import CrinkledSection from "../CrinkledSection.svelte"
import CardWrapper from "../widgets/CardWrapper.svelte" import CardWrapper from "../widgets/CardWrapper.svelte"
import Icon from "../widgets/Icon.svelte" import Icon from "../widgets/Icon.svelte"
import { mdiCheckCircleOutline } from "@mdi/js" import { mdiCheck, mdiCheckAll, mdiCheckCircleOutline } from "@mdi/js"
import SectionTitle from "../widgets/SectionTitle.svelte" import SectionTitle from "../widgets/SectionTitle.svelte"
const offers: Array<{ const offers: Array<{
@@ -19,13 +19,13 @@
badge: "Beliebtestes Paket", badge: "Beliebtestes Paket",
accent: true, accent: true,
features: [ features: [
"Einmalige Bot-Entwicklung inkl. Workshop &amp; Integration: <strong>ab 2 500 €</strong>", "Komplettlösung: ab 2 500 €",
"Hosting &amp; Monitoring im deutschen Rechenzentrum: <strong>99 €/Monat</strong>", "Hosting &amp; Monitoring im deutschen Rechenzentrum: ab 100&nbsp;€/Monat",
"Transparente Nutzungskosten: ca. <strong>2 €</strong> pro 100 Chat-Sessions bzw. <strong>5 €</strong> pro 100 Voice-Calls*", "Transparente Nutzungskosten: ca. 2&nbsp;€ pro 100&nbsp;Chat-Sessions bzw. 5&nbsp;€ pro 100&nbsp;Telefongespräche*",
"Optionales Optimierungspaket (Prompt- &amp; KPI-Tuning): <strong>ab 250 €/Monat</strong>", "Optionale laufende Optimierungen: ab 250&nbsp;€/Monat",
"Vollständig DSGVO-konform, kündbar mit 30 Tagen Frist", "Vollständig DSGVO-konform, jederzeit kündbar mit 30 Tagen Frist",
], ],
note: "*ca. 10 Minuten Dialogdauer pro Session; tatsächliche API-Preise werden 1:1 durchgereicht.", note: "*ca. 10 Minuten Dialogdauer pro Session; tatsächliche API-Preise werden 1:1 durchgereicht und hängen vom gewählten Anbieter ab.",
}, },
{ {
title: "Kontextwerk Enterprise", title: "Kontextwerk Enterprise",
@@ -33,9 +33,9 @@
badge: "Für komplexe Landschaften", badge: "Für komplexe Landschaften",
features: [ features: [
"On-Premise- oder Private-Cloud-Deployment (Kubernetes/Docker)", "On-Premise- oder Private-Cloud-Deployment (Kubernetes/Docker)",
"Schulung &amp; Enablement Ihres Teams: <strong>13 Tage</strong>, feste Tagessätze", "Schulung &amp; Enablement Ihres Teams: 13 Tage, feste Tagessätze",
"Plattform-Lizenz nach Server-Knoten oder CPU/VRAM-Paketen", "Plattform-Lizenz nach Server-Knoten oder CPU/VRAM-Paketen",
"Premium-Support &amp; individuelle SLA bis <strong>24/7</strong> verfügbar", "Premium-Support &amp; individuelle SLA bis 24/7 verfügbar",
"Gleicher Funktionsumfang wie Starter, jedoch mit eigener Datenhoheit und Möglichkeit, firmeneigene LLMs anzubinden.", "Gleicher Funktionsumfang wie Starter, jedoch mit eigener Datenhoheit und Möglichkeit, firmeneigene LLMs anzubinden.",
], ],
}, },
@@ -74,9 +74,12 @@
<ul> <ul>
{#each offer.features as feature} {#each offer.features as feature}
<li> <li>
<span class="icon"> <span
class="icon"
style="color: var(--primary-200);"
>
<Icon <Icon
path={mdiCheckCircleOutline} path={mdiCheck}
size="1.1rem" size="1.1rem"
/> />
</span> </span>
@@ -105,6 +108,7 @@
margin: 0 auto; margin: 0 auto;
width: 100%; width: 100%;
color: var(--neutral-white); color: var(--neutral-white);
padding-bottom: 4.8rem;
} }
.offer-cards { .offer-cards {
@@ -204,19 +208,18 @@
li { li {
display: grid; display: grid;
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
align-items: flex-start; align-items: center;
gap: 0.9rem; gap: 0.9rem;
line-height: 1.55; line-height: 1.55;
background-color: none;
border: none;
.icon { .icon {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 1.6rem; width: 1.6rem;
height: 1.6rem; height: 1.6rem;
border-radius: 50%;
background: rgba(173, 81, 76, 0.2);
box-shadow: inset 0 0 0 1px rgba(173, 81, 76, 0.55);
svg { svg {
filter: drop-shadow(0 0 6px rgba(173, 81, 76, 0.45)); filter: drop-shadow(0 0 6px rgba(173, 81, 76, 0.45));
} }
@@ -256,11 +259,6 @@
&:hover { &:hover {
border-color: rgba(255, 82, 82, 0.65); border-color: rgba(255, 82, 82, 0.65);
} }
.icon {
background: rgba(255, 82, 82, 0.16);
box-shadow: inset 0 0 0 1px rgba(255, 82, 82, 0.4);
}
} }
@media @mobile { @media @mobile {

View File

@@ -2,6 +2,7 @@
import ChatbotPreview from "../lib/components/staticPageRows/ChatbotPreview.svelte" import ChatbotPreview from "../lib/components/staticPageRows/ChatbotPreview.svelte"
import ContactFormRow from "../lib/components/staticPageRows/ContactFormRow.svelte" import ContactFormRow from "../lib/components/staticPageRows/ContactFormRow.svelte"
import CoreSellingPoints from "../lib/components/staticPageRows/CoreSellingPoints.svelte" import CoreSellingPoints from "../lib/components/staticPageRows/CoreSellingPoints.svelte"
import FAQSection from "../lib/components/staticPageRows/FAQSection.svelte"
import VoicebotPreview from "../lib/components/staticPageRows/VoicebotPreview.svelte" import VoicebotPreview from "../lib/components/staticPageRows/VoicebotPreview.svelte"
import OfferPackages from "../lib/components/staticPageRows/OfferPackages.svelte" import OfferPackages from "../lib/components/staticPageRows/OfferPackages.svelte"
</script> </script>
@@ -10,5 +11,6 @@
<VoicebotPreview /> <VoicebotPreview />
<ChatbotPreview /> <ChatbotPreview />
<FAQSection />
<OfferPackages /> <OfferPackages />
<ContactFormRow /> <ContactFormRow />