Compare commits

5 Commits

Author SHA1 Message Date
64aece1dbc website-change hinzugefügt 2026-02-10 14:49:44 +00:00
9231f76c61 Update Dockerfile 2026-02-05 15:14:25 +00:00
4f8f81bc88 Update Dockerfile 2026-02-05 15:09:23 +00:00
077c0603f9 Update Dockerfile 2026-02-05 15:05:57 +00:00
8007898e89 Add Dockerfile 2026-02-05 15:02:50 +00:00
133 changed files with 9767 additions and 7265 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,9 @@
FROM webdevops/php-nginx:8.2-alpine
FROM nginx:alpine
ENV WEB_DOCUMENT_ROOT=/app
COPY ["Profice WebSite/", "/app/"]
RUN rm -rf /usr/share/nginx/html/*
COPY vhost.conf /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
COPY ["Profice WebSite/", "/usr/share/nginx/html/"]
RUN chown -R application:application /app && chmod -R 755 /app
RUN chmod -R 755 /usr/share/nginx/html/
EXPOSE 80

View File

@@ -0,0 +1 @@
Options -Indexes

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1006 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

View File

@@ -0,0 +1,257 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice - Digitale Lösungen</title>
<link rel="stylesheet" href="style/design.css">
<link rel="stylesheet" href="style/cursor.css">
<link rel="stylesheet" href="style/cookie-consent.css">
</head>
<body>
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menü">
<span></span>
<span></span>
<span></span>
</button>
<a href="index.html" class="logo-link">
<img src="images/logo/logo-01-complete.png" alt="Profice Logo" class="logo" loading="lazy">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="#hero-section" class="nav-link">Startseite</a>
<a href="#enterprise" class="nav-link">Unternehmen</a>
<a href="#pricing" class="nav-link">Preise</a>
<a href="#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Cursor umschalten" title="Benutzerdefinierten Cursor umschalten">
<img src="images/additional/cursor.png" alt="Standard Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Anmelden" title="Anmelden">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Anmelden
</button>
</div>
</header>
<nav class="slide-menu" id="slideMenu">
<a href="index.html" class="active">Startseite</a>
<a href="sites/offers.html">Kontakt & Anfrage</a>
<a href="sites/leads.html">Leads Dashboard</a>
</nav>
<div class="overlay" id="overlay"></div>
<main class="home-content">
<section id="hero-section" class="hero-section">
<div class="hero-text">
<h1>Transformieren Sie Ihr Unternehmen digital</h1>
<p>Maßgeschneiderte Lösungen für Web, KI-Integration und Prozessautomatisierung. Wir bringen Ihre Vision in die digitale Realität.</p>
<div class="hero-buttons">
<a href="sites/offers.html" class="cta-btn primary">Projekt starten</a>
<a href="#services" class="cta-btn secondary">Mehr erfahren</a>
</div>
</div>
<div class="hero-image-placeholder">
<span>[Bild: Digitale Transformation Illustration]</span>
</div>
</section>
<section id="enterprise" class="enterprise-section">
<h2 class="section-title">Unternehmenslösungen</h2>
<div class="enterprise-content">
<p>Maßgeschneiderte Lösungen für große Unternehmen mit komplexen Anforderungen.</p>
<div class="enterprise-features">
<div class="feature-item">
<h3>Skalierbarkeit</h3>
<p>Lösungen, die mit Ihrem Unternehmen wachsen</p>
</div>
<div class="feature-item">
<h3>Sicherheit</h3>
<p>Unternehmenssicherheit und Compliance</p>
</div>
<div class="feature-item">
<h3>Integration</h3>
<p>Nahtlose Integration mit bestehenden Systemen</p>
</div>
</div>
</div>
</section>
<section id="pricing" class="pricing-section">
<h2 class="section-title">Preise</h2>
<div class="pricing-grid">
<div class="pricing-card">
<h3>Starter</h3>
<div class="price">€999</div>
<p>Perfekt für kleine Unternehmen</p>
<ul>
<li>Webentwicklung</li>
<li>Grundlegende KI-Integration</li>
<li>3 Monate Support</li>
</ul>
</div>
<div class="pricing-card featured">
<h3>Professional</h3>
<div class="price">€2.499</div>
<p>Ideal für wachsende Unternehmen</p>
<ul>
<li>Erweiterte Webentwicklung</li>
<li>KI & Automatisierung</li>
<li>6 Monate Support</li>
<li>SEO Optimierung</li>
</ul>
</div>
<div class="pricing-card">
<h3>Unternehmen</h3>
<div class="price">Individuell</div>
<p>Für große Unternehmen</p>
<ul>
<li>Volle Unternehmenslösungen</li>
<li>Custom KI-Entwicklung</li>
<li>12 Monate Support</li>
<li>Dediziertes Team</li>
</ul>
</div>
</div>
</section>
<section id="services" class="services-section">
<h2 class="section-title">Unsere Expertise</h2>
<div class="services-grid">
<div class="service-card">
<div class="service-icon">
🌐
</div>
<h3>Webentwicklung</h3>
<p>Moderne, responsive Webseiten, die konvertieren und Ihre Marke perfekt repräsentieren.</p>
</div>
<div class="service-card">
<div class="service-icon">
🤖
</div>
<h3>KI Integration</h3>
<p>Nutzen Sie die Kraft künstlicher Intelligenz, um Ihre Daten besser zu verstehen und Prozesse zu optimieren.</p>
</div>
<div class="service-card">
<div class="service-icon">
⚙️
</div>
<h3>Automatisierung</h3>
<p>Sparen Sie Zeit und Ressourcen durch intelligente Workflow-Automatisierungen.</p>
</div>
</div>
</section>
<section class="info-section">
<div class="info-container">
<div class="info-content">
<h2>Warum Profice?</h2>
<p>Wir verbinden technologische Exzellenz mit tiefgreifendem Geschäftsverständnis. Unser Ziel ist nicht nur die Lieferung von Software, sondern die Schaffung von echtem Mehrwert für Ihr Unternehmen.</p>
<ul class="info-list">
<li>Individuelle Beratung</li>
<li>Transparente Prozesse</li>
<li>Zukunftssichere Technologien</li>
</ul>
</div>
<div class="info-image-placeholder">
<span>[Bild: Team bei der Arbeit]</span>
</div>
</div>
</section>
</main>
<!-- Cookie Consent Banner -->
<div id="cookieBanner" class="cookie-banner" role="dialog" aria-labelledby="cookieTitle" aria-describedby="cookieDescription">
<div class="cookie-banner-content">
<div class="cookie-text">
<h3 id="cookieTitle">Cookie-Einstellungen</h3>
<p id="cookieDescription">
Wir verwenden Cookies, um Ihre Erfahrung zu verbessern und unsere Website zu analysieren.
Durch die Nutzung unserer Website stimmen Sie unserem <a href="#privacy">Datenschutz</a> zu.
</p>
</div>
<div class="cookie-buttons">
<button id="cookieAcceptAll" class="cookie-btn cookie-btn-primary">Alle akzeptieren</button>
<button id="cookieRejectAll" class="cookie-btn cookie-btn-secondary">Alle ablehnen</button>
<button id="cookieSettings" class="cookie-btn cookie-btn-settings">Einstellungen</button>
</div>
</div>
</div>
<!-- Cookie Settings Modal -->
<div id="cookieModal" class="cookie-modal" role="dialog" aria-labelledby="cookieModalTitle" aria-modal="true">
<div class="cookie-modal-content">
<div class="cookie-modal-header">
<h2 id="cookieModalTitle">Cookie-Einstellungen</h2>
<button id="cookieModalClose" class="cookie-modal-close" aria-label="Schließen">&times;</button>
</div>
<div class="cookie-option">
<div class="cookie-option-header">
<h3 class="cookie-option-title">Notwendige Cookies</h3>
<div id="cookie-toggle-necessary" class="cookie-toggle active disabled" role="switch" aria-checked="true" aria-disabled="true">
<div class="cookie-toggle-slider"></div>
</div>
</div>
<p class="cookie-option-description">
Diese Cookies sind für die Funktionsweise der Website unerlässlich und können nicht in Ihren Browsern deaktiviert werden.
</p>
</div>
<div class="cookie-option">
<div class="cookie-option-header">
<h3 class="cookie-option-title">Analyse-Cookies</h3>
<div id="cookie-toggle-analytics" class="cookie-toggle" role="switch" aria-checked="false">
<div class="cookie-toggle-slider"></div>
</div>
</div>
<p class="cookie-option-description">
Diese Cookies helfen uns zu verstehen, wie Besucher mit unserer Website interagieren, indem sie Informationen anonym sammeln und melden.
</p>
</div>
<div class="cookie-option">
<div class="cookie-option-header">
<h3 class="cookie-option-title">Marketing-Cookies</h3>
<div id="cookie-toggle-marketing" class="cookie-toggle" role="switch" aria-checked="false">
<div class="cookie-toggle-slider"></div>
</div>
</div>
<p class="cookie-option-description">
Diese Cookies werden verwendet, um Besucher über Websites hinweg zu verfolgen, um relevante Anzeigen zu zeigen.
</p>
</div>
<div class="cookie-modal-footer">
<button id="cookieSavePreferences" class="cookie-btn cookie-btn-primary">Einstellungen speichern</button>
</div>
</div>
</div>
<script src="scripts/script.js" defer></script>
<script src="scripts/cookie-consent.js" defer></script>
<script src="scripts/cursor.js" defer></script>
<script src="scripts/scroll-header.js" defer></script>
</body>
</html>

View File

@@ -0,0 +1,637 @@
<?php
/**
* Profice Web API Handler - Centralized Configuration
* ALL SENSITIVE DATA STORED HERE - NOT VISIBLE TO CLIENT
* Handles webhooks, API, tokens, cookie consent, tracking
*/
// ==========================================
// SECURITY HEADERS
// ==========================================
header('Content-Type: application/json');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');
// CORS - Restrict to your domain in production
$allowedOrigins = [
'https://profice.de',
'https://www.profice.de',
'http://localhost',
'http://127.0.0.1'
];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: $origin");
} else {
header('Access-Control-Allow-Origin: *'); // Development fallback
}
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Max-Age: 86400');
// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
// ==========================================
// SENSITIVE CONFIGURATION - HIDDEN FROM CLIENT
// ==========================================
// Environment
define('USE_PRODUCTION', false); // Use test webhook for debugging
define('DEBUG_MODE', true); // Enable debug to see errors
// N8N Webhooks
define('WEBHOOK_TEST', 'https://n8n.profice.de/webhook-test/d94ef798-3f43-46dd-8207-1e335e64518f');
define('WEBHOOK_PROD', 'https://n8n.profice.de/webhook/d94ef798-3f43-46dd-8207-1e335e64518f');
define('WEBHOOK_URL', USE_PRODUCTION ? WEBHOOK_PROD : WEBHOOK_TEST);
// Google Analytics
define('GA_MEASUREMENT_ID', 'G-XXXXXXXXXX'); // Replace with your actual ID
define('GA_API_SECRET', ''); // For server-side tracking
// Google Tag Manager
define('GTM_CONTAINER_ID', 'GTM-XXXXXXX'); // Replace with your actual ID
// Facebook Pixel
define('FB_PIXEL_ID', ''); // Replace with your actual ID
define('FB_ACCESS_TOKEN', ''); // For Conversions API
// Google Ads
define('GADS_CONVERSION_ID', 'AW-XXXXXXXXXX');
define('GADS_CONVERSION_LABEL', '');
// LinkedIn Insight
define('LINKEDIN_PARTNER_ID', '');
// API Keys
define('API_SECRET_KEY', 'your-secret-key-here'); // For API authentication
// Rate Limiting
define('RATE_LIMIT_REQUESTS', 100);
define('RATE_LIMIT_WINDOW', 3600); // 1 hour
// ==========================================
// HELPER FUNCTIONS
// ==========================================
function sendResponse($success, $message, $data = null, $statusCode = 200) {
http_response_code($statusCode);
$response = [
'success' => $success,
'message' => $message,
'timestamp' => date('c')
];
// Only include data if not null and not in production (security)
if ($data !== null && (!USE_PRODUCTION || DEBUG_MODE)) {
$response['data'] = $data;
} elseif ($data !== null && $success) {
// In production, only return safe data
$response['data'] = filterSafeData($data);
}
echo json_encode($response);
exit();
}
function filterSafeData($data) {
// Remove sensitive fields from response
$sensitiveFields = ['webhook_url', 'ip_address', 'user_agent', 'http_code', 'error'];
if (is_array($data)) {
foreach ($sensitiveFields as $field) {
unset($data[$field]);
}
}
return $data;
}
function getClientIP() {
$ipKeys = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'];
foreach ($ipKeys as $key) {
if (array_key_exists($key, $_SERVER)) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
}
return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
}
function sanitizeInput($input) {
if (is_array($input)) {
return array_map('sanitizeInput', $input);
}
return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}
function validateCSRFToken($token) {
// Implement CSRF validation if needed
return true;
}
function checkRateLimit($ip) {
$rateLimitFile = __DIR__ . '/rate_limits.json';
$limits = [];
if (file_exists($rateLimitFile)) {
$limits = json_decode(file_get_contents($rateLimitFile), true) ?: [];
}
$now = time();
$windowStart = $now - RATE_LIMIT_WINDOW;
// Clean old entries
$limits = array_filter($limits, function($entry) use ($windowStart) {
return $entry['time'] > $windowStart;
});
// Count requests from this IP
$ipRequests = array_filter($limits, function($entry) use ($ip) {
return $entry['ip'] === $ip;
});
if (count($ipRequests) >= RATE_LIMIT_REQUESTS) {
return false;
}
// Add new request
$limits[] = ['ip' => $ip, 'time' => $now];
file_put_contents($rateLimitFile, json_encode($limits));
return true;
}
// ==========================================
// WEBHOOK FUNCTIONS
// ==========================================
function sendToWebhook($data, $webhookUrl = null) {
$url = $webhookUrl ?? WEBHOOK_URL;
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'User-Agent: Profice-Web-API/2.0'
],
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => !DEBUG_MODE, // Disable for debugging
CURLOPT_FOLLOWLOCATION => true
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
error_log("Webhook Error: " . $error);
return ['success' => false, 'error' => $error, 'response' => $response];
}
return [
'success' => $httpCode >= 200 && $httpCode < 300,
'http_code' => $httpCode,
'response' => $response,
'error' => $error
];
}
// ==========================================
// TRACKING FUNCTIONS - SERVER SIDE
// ==========================================
function getTrackingConfig() {
// Return tracking configuration for client
// IDs are loaded from server, not exposed in JS
return [
'analytics_enabled' => !empty(GA_MEASUREMENT_ID) && GA_MEASUREMENT_ID !== 'G-XXXXXXXXXX',
'gtm_enabled' => !empty(GTM_CONTAINER_ID) && GTM_CONTAINER_ID !== 'GTM-XXXXXXX',
'fb_enabled' => !empty(FB_PIXEL_ID),
'gads_enabled' => !empty(GADS_CONVERSION_ID) && GADS_CONVERSION_ID !== 'AW-XXXXXXXXXX',
'linkedin_enabled' => !empty(LINKEDIN_PARTNER_ID)
];
}
function loadTrackingScripts($preferences) {
$scripts = [];
// Google Analytics
if ($preferences['analytics'] && !empty(GA_MEASUREMENT_ID) && GA_MEASUREMENT_ID !== 'G-XXXXXXXXXX') {
$scripts['ga'] = [
'type' => 'analytics',
'src' => 'https://www.googletagmanager.com/gtag/js?id=' . GA_MEASUREMENT_ID,
'config' => [
'id' => GA_MEASUREMENT_ID
]
];
}
// Google Tag Manager
if ($preferences['analytics'] && !empty(GTM_CONTAINER_ID) && GTM_CONTAINER_ID !== 'GTM-XXXXXXX') {
$scripts['gtm'] = [
'type' => 'gtm',
'src' => 'https://www.googletagmanager.com/gtm.js?id=' . GTM_CONTAINER_ID,
'config' => [
'id' => GTM_CONTAINER_ID
]
];
}
// Facebook Pixel
if ($preferences['marketing'] && !empty(FB_PIXEL_ID)) {
$scripts['fb'] = [
'type' => 'pixel',
'src' => 'https://connect.facebook.net/en_US/fbevents.js',
'config' => [
'pixel_id' => FB_PIXEL_ID
]
];
}
// Google Ads
if ($preferences['marketing'] && !empty(GADS_CONVERSION_ID) && GADS_CONVERSION_ID !== 'AW-XXXXXXXXXX') {
$scripts['gads'] = [
'type' => 'conversion',
'src' => 'https://www.googletagmanager.com/gtag/js?id=' . GADS_CONVERSION_ID,
'config' => [
'conversion_id' => GADS_CONVERSION_ID,
'conversion_label' => GADS_CONVERSION_LABEL
]
];
}
// LinkedIn
if ($preferences['marketing'] && !empty(LINKEDIN_PARTNER_ID)) {
$scripts['linkedin'] = [
'type' => 'insight',
'src' => 'https://snap.licdn.com/li.lms-analytics/insight.min.js',
'config' => [
'partner_id' => LINKEDIN_PARTNER_ID
]
];
}
return $scripts;
}
function sendEventToGA($data) {
if (empty(GA_MEASUREMENT_ID) || GA_MEASUREMENT_ID === 'G-XXXXXXXXXX') {
return false;
}
$postData = [
'client_id' => $data['client_id'] ?? uniqid(),
'user_id' => $data['user_id'] ?? null,
'events' => [
[
'name' => $data['event_name'],
'params' => $data['params'] ?? []
]
]
];
$url = 'https://www.google-analytics.com/mp/collect';
$url .= '?measurement_id=' . GA_MEASUREMENT_ID;
$url .= '&api_secret=' . GA_API_SECRET;
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($postData),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpCode >= 200 && $httpCode < 300;
}
function sendEventToFB($data) {
if (empty(FB_PIXEL_ID) || empty(FB_ACCESS_TOKEN)) {
return false;
}
$postData = [
'data' => [
[
'event_name' => $data['event_name'],
'event_time' => time(),
'action_source' => 'website',
'user_data' => $data['user_data'] ?? [],
'custom_data' => $data['custom_data'] ?? []
]
]
];
$url = 'https://graph.facebook.com/v18.0/' . FB_PIXEL_ID . '/events';
$url .= '?access_token=' . FB_ACCESS_TOKEN;
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($postData),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpCode >= 200 && $httpCode < 300;
}
// ==========================================
// STORAGE FUNCTIONS
// ==========================================
function storeLead($data) {
$leadFile = __DIR__ . '/data/leads.json';
$dir = dirname($leadFile);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$leads = [];
if (file_exists($leadFile)) {
$leads = json_decode(file_get_contents($leadFile), true) ?: [];
}
$lead = [
'id' => uniqid('lead_', true),
'datum' => date('d.m.Y'),
'dienstleistung' => $data['service'] ?? 'Allgemein',
'status' => 'open',
'statusText' => 'Offen',
'description' => $data['description'] ?? '',
'name' => $data['name'] ?? '',
'contact' => $data['contact'] ?? '',
'organisation' => $data['organisation'] ?? '',
'timestamp' => date('c'),
'ip_address' => getClientIP()
];
array_unshift($leads, $lead);
$leads = array_slice($leads, 0, 100);
file_put_contents($leadFile, json_encode($leads, JSON_PRETTY_PRINT));
return $lead['id'];
}
function storeCookieConsent($data) {
$consentFile = __DIR__ . '/data/cookie_consent.json';
$dir = dirname($consentFile);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
$consents = [];
if (file_exists($consentFile)) {
$consents = json_decode(file_get_contents($consentFile), true) ?: [];
}
$consent = [
'id' => uniqid('consent_', true),
'timestamp' => date('c'),
'preferences' => $data['preferences'] ?? [],
'ip_address' => getClientIP(),
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? ''
];
array_unshift($consents, $consent);
$consents = array_slice($consents, 0, 1000);
file_put_contents($consentFile, json_encode($consents, JSON_PRETTY_PRINT));
return $consent['id'];
}
function getCookieConsent() {
$consentFile = __DIR__ . '/data/cookie_consent.json';
if (!file_exists($consentFile)) {
return null;
}
$consents = json_decode(file_get_contents($consentFile), true) ?: [];
return $consents[0] ?? null;
}
// ==========================================
// REQUEST HANDLERS
// ==========================================
function handleContactForm($data) {
$required = ['name', 'contact'];
foreach ($required as $field) {
if (empty($data[$field])) {
sendResponse(false, "Pflichtfeld fehlt: {$field}", null, 400);
}
}
$formData = [
'name' => sanitizeInput($data['name']),
'organisation' => sanitizeInput($data['organisation'] ?? ''),
'contact' => sanitizeInput($data['contact']),
'service' => sanitizeInput($data['service'] ?? ''),
'budget' => sanitizeInput($data['budget'] ?? ''),
'description' => sanitizeInput($data['description'] ?? ''),
'timestamp' => date('c'),
'source' => 'contact_form',
'form_type' => 'offer',
'ip_address' => getClientIP()
];
// Store lead locally first
$leadId = storeLead($formData);
// Send to webhook
$webhookResult = sendToWebhook($formData);
// Always return success to user, but include webhook info in debug mode
$debugData = DEBUG_MODE ? [
'lead_id' => $leadId,
'webhook_result' => $webhookResult,
'webhook_url' => WEBHOOK_URL,
'form_data' => $formData
] : null;
if ($webhookResult['success']) {
sendResponse(true, 'Formular erfolgreich gesendet', $debugData);
} else {
// Still return success to user but log the webhook error
error_log('Webhook failed but form was stored locally: ' . json_encode($webhookResult));
sendResponse(true, 'Formular erfolgreich gesendet (Webhook-Fehler protokolliert)', $debugData);
}
}
function handleLoginForm($data) {
$required = ['email', 'password'];
foreach ($required as $field) {
if (empty($data[$field])) {
sendResponse(false, "Pflichtfeld fehlt: {$field}", null, 400);
}
}
// Add your login logic here
sendResponse(true, 'Login erfolgreich');
}
function handleRegisterForm($data) {
$required = ['name', 'email', 'password'];
foreach ($required as $field) {
if (empty($data[$field])) {
sendResponse(false, "Pflichtfeld fehlt: {$field}", null, 400);
}
}
// Add your registration logic here
sendResponse(true, 'Registrierung erfolgreich');
}
function handleLeadForm($data) {
// Handle lead form submissions
$leadId = storeLead($data);
sendResponse(true, 'Lead gespeichert', ['lead_id' => $leadId]);
}
function handleCookieConsent($data) {
$preferences = $data['preferences'] ?? [];
$consentId = storeCookieConsent(['preferences' => $preferences]);
// Load tracking scripts based on preferences
$scripts = loadTrackingScripts($preferences);
sendResponse(true, 'Cookie-Einstellungen gespeichert', [
'consent_id' => $consentId,
'scripts' => $scripts
]);
}
function handleGetCookieConsent($data) {
$consent = getCookieConsent();
if ($consent) {
sendResponse(true, 'Cookie-Einstellungen gefunden', $consent);
} else {
sendResponse(false, 'Keine Cookie-Einstellungen gefunden', null, 404);
}
}
function handleGetTrackingConfig($data) {
$config = getTrackingConfig();
sendResponse(true, 'Tracking-Konfiguration', $config);
}
function handleTrackEvent($data) {
$eventName = $data['event_name'] ?? '';
$eventData = $data['event_data'] ?? [];
// Send to Google Analytics
$gaSuccess = sendEventToGA([
'event_name' => $eventName,
'params' => $eventData
]);
// Send to Facebook
$fbSuccess = sendEventToFB([
'event_name' => $eventName,
'custom_data' => $eventData
]);
sendResponse(true, 'Event gesendet', [
'ga_success' => $gaSuccess,
'fb_success' => $fbSuccess
]);
}
// ==========================================
// MAIN REQUEST HANDLER
// ==========================================
// Validate request method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
sendResponse(false, 'Nur POST-Anfragen erlaubt', null, 405);
}
// Rate limiting
$clientIP = getClientIP();
if (!checkRateLimit($clientIP)) {
sendResponse(false, 'Zu viele Anfragen. Bitte später erneut versuchen.', null, 429);
}
// Get JSON input
$jsonInput = file_get_contents('php://input');
$data = json_decode($jsonInput, true);
if (!$data) {
$data = $_POST;
}
if (!$data || empty($data)) {
sendResponse(false, 'Keine Daten empfangen', null, 400);
}
$requestType = $data['type'] ?? 'contact';
try {
switch ($requestType) {
case 'contact':
handleContactForm($data);
break;
case 'login':
handleLoginForm($data);
break;
case 'register':
handleRegisterForm($data);
break;
case 'lead':
handleLeadForm($data);
break;
case 'cookie_consent':
handleCookieConsent($data);
break;
case 'get_cookie_consent':
handleGetCookieConsent($data);
break;
case 'get_tracking_config':
handleGetTrackingConfig($data);
break;
case 'track_event':
handleTrackEvent($data);
break;
default:
sendResponse(false, 'Ungültiger Anfragetyp', null, 400);
}
} catch (Exception $e) {
error_log('API Error: ' . $e->getMessage());
error_log('Stack trace: ' . $e->getTraceAsString());
sendResponse(false, 'Interner Serverfehler', null, 500);
}
?>

View File

@@ -0,0 +1,423 @@
/**
* Cookie Consent Management System
* All sensitive data (tracking IDs, URLs) are loaded from server-side PHP
* Includes fallback for local file access (no server)
*
* @version 2.1.0
*/
document.addEventListener('DOMContentLoaded', function() {
// ==========================================
// CONFIGURATION
// ==========================================
const cookieCategories = ['necessary', 'analytics', 'marketing'];
const API_ENDPOINT = 'scripts/add/send.php';
// Detect if running from file:// protocol (no server)
const isLocalFile = window.location.protocol === 'file:';
let consentState = {
hasConsented: false,
preferences: {}
};
let previousPreferences = {};
let trackingScripts = {};
// ==========================================
// DATALAYER INTEGRATION
// ==========================================
window.dataLayer = window.dataLayer || [];
function pushConsentToDataLayer(preferences) {
window.dataLayer.push({
'event': 'consent_update',
'consent': {
'analytics_storage': preferences.analytics ? 'granted' : 'denied',
'ad_storage': preferences.marketing ? 'granted' : 'denied',
'functionality_storage': preferences.necessary ? 'granted' : 'denied',
'personalization_storage': preferences.marketing ? 'granted' : 'denied',
'security_storage': 'granted'
}
});
}
function setDefaultConsent() {
window.dataLayer.push({
'event': 'consent_default',
'consent': {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'functionality_storage': 'granted',
'personalization_storage': 'denied',
'security_storage': 'granted',
'wait_for_update': 500
}
});
}
// ==========================================
// STORAGE (API + LOCALSTORAGE FALLBACK)
// ==========================================
async function saveConsentToStorage(preferences) {
// Always save to localStorage as backup
const consentData = {
hasConsented: true,
preferences: preferences,
timestamp: new Date().toISOString()
};
localStorage.setItem('cookieConsent', JSON.stringify(consentData));
// Try API if not local file
if (!isLocalFile) {
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'cookie_consent', preferences })
});
const result = await response.json();
if (result.success && result.data && result.data.scripts) {
trackingScripts = result.data.scripts;
}
return result.success;
} catch (e) {
// API failed, localStorage already saved
return false;
}
}
return true;
}
async function getConsentFromStorage() {
// Try localStorage first (faster)
const localConsent = localStorage.getItem('cookieConsent');
if (localConsent) {
try {
return JSON.parse(localConsent);
} catch (e) {
localStorage.removeItem('cookieConsent');
}
}
// Try API if not local file
if (!isLocalFile) {
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type: 'get_cookie_consent' })
});
const result = await response.json();
if (result.success && result.data) {
if (result.data.scripts) {
trackingScripts = result.data.scripts;
}
// Cache in localStorage
localStorage.setItem('cookieConsent', JSON.stringify(result.data));
return result.data;
}
} catch (e) {
// API unavailable
}
}
return null;
}
// ==========================================
// SCRIPT LOADING
// ==========================================
function loadTrackingScripts() {
if (!trackingScripts || Object.keys(trackingScripts).length === 0) return;
if (trackingScripts.ga && consentState.preferences.analytics) {
loadGoogleAnalytics(trackingScripts.ga);
}
if (trackingScripts.gtm && consentState.preferences.analytics) {
loadGTM(trackingScripts.gtm);
}
if (trackingScripts.fb && consentState.preferences.marketing) {
loadFacebookPixel(trackingScripts.fb);
}
if (trackingScripts.gads && consentState.preferences.marketing) {
loadGoogleAds(trackingScripts.gads);
}
if (trackingScripts.linkedin && consentState.preferences.marketing) {
loadLinkedIn(trackingScripts.linkedin);
}
}
function loadScript(src, callback) {
const script = document.createElement('script');
script.src = src;
script.async = true;
if (callback) script.onload = callback;
document.head.appendChild(script);
}
function loadGoogleAnalytics(config) {
if (!config.src || !config.config || !config.config.id) return;
loadScript(config.src, function() {
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
window.gtag = gtag;
gtag('js', new Date());
gtag('config', config.config.id);
});
}
function loadGTM(config) {
if (!config.id) return;
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer',config.id);
}
function loadFacebookPixel(config) {
if (!config.id) return;
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', config.id);
fbq('track', 'PageView');
}
function loadGoogleAds(config) {
if (!config.id) return;
loadScript('https://www.googletagmanager.com/gtag/js?id=' + config.id, function() {
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', config.id);
});
}
function loadLinkedIn(config) {
if (!config.id) return;
window._linkedin_partner_id = config.id;
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(config.id);
loadScript('https://snap.licdn.com/li.lms-analytics/insight.min.js');
}
// ==========================================
// COOKIE DELETION
// ==========================================
const cookiePatterns = {
analytics: ['_ga', '_gid', '_gat', '__utma', '__utmb', '__utmc', '__utmz'],
marketing: ['_fbp', '_fbc', 'fr', '_gcl_au', '_gcl_aw', 'IDE', 'DSID', 'NID']
};
function deleteCookie(name) {
const paths = ['/', window.location.pathname];
const domains = ['', window.location.hostname, '.' + window.location.hostname];
paths.forEach(path => {
domains.forEach(domain => {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}${domain ? '; domain=' + domain : ''}`;
});
});
}
function deleteCookiesForCategory(category) {
const patterns = cookiePatterns[category] || [];
const allCookies = document.cookie.split(';');
allCookies.forEach(cookie => {
const cookieName = cookie.split('=')[0].trim();
patterns.forEach(pattern => {
if (cookieName.startsWith(pattern)) {
deleteCookie(cookieName);
}
});
});
}
function handlePreferenceChanges(newPreferences) {
Object.keys(cookiePatterns).forEach(category => {
if (previousPreferences[category] === true && newPreferences[category] === false) {
deleteCookiesForCategory(category);
window.dataLayer.push({ 'event': 'consent_revoked', 'consent_category': category });
}
});
previousPreferences = { ...newPreferences };
}
// ==========================================
// DOM ELEMENTS
// ==========================================
const cookieBanner = document.getElementById('cookieBanner');
const cookieModal = document.getElementById('cookieModal');
const acceptAllBtn = document.getElementById('cookieAcceptAll');
const rejectAllBtn = document.getElementById('cookieRejectAll');
const settingsBtn = document.getElementById('cookieSettings');
const modalCloseBtn = document.getElementById('cookieModalClose');
const savePreferencesBtn = document.getElementById('cookieSavePreferences');
// ==========================================
// CORE FUNCTIONS
// ==========================================
async function initCookieConsent() {
setDefaultConsent();
const savedConsent = await getConsentFromStorage();
if (savedConsent && savedConsent.hasConsented) {
consentState = {
hasConsented: true,
preferences: savedConsent.preferences || {}
};
previousPreferences = { ...consentState.preferences };
applyConsentPreferences();
return;
}
// Show banner after short delay
setTimeout(() => {
if (cookieBanner) cookieBanner.classList.add('show');
}, 500);
}
function applyConsentPreferences() {
pushConsentToDataLayer(consentState.preferences);
loadTrackingScripts();
window.dispatchEvent(new CustomEvent('cookieConsentUpdated', { detail: consentState.preferences }));
}
async function saveConsent(preferences) {
handlePreferenceChanges(preferences);
await saveConsentToStorage(preferences);
consentState = {
hasConsented: true,
preferences: preferences,
timestamp: new Date().toISOString()
};
applyConsentPreferences();
}
function hideBanner() {
if (cookieBanner) cookieBanner.classList.remove('show');
}
function showSettingsModal() {
if (cookieModal) {
cookieModal.classList.add('show');
populateSettingsModal();
}
}
function hideSettingsModal() {
if (cookieModal) cookieModal.classList.remove('show');
}
function populateSettingsModal() {
cookieCategories.forEach(key => {
const toggle = document.getElementById(`cookie-toggle-${key}`);
if (!toggle) return;
const isEnabled = consentState.preferences[key] || false;
const isRequired = key === 'necessary';
if (isRequired) {
toggle.classList.add('active', 'disabled');
toggle.setAttribute('aria-checked', 'true');
toggle.setAttribute('aria-disabled', 'true');
} else {
toggle.classList.toggle('active', isEnabled);
toggle.setAttribute('aria-checked', isEnabled ? 'true' : 'false');
toggle.onclick = () => {
toggle.classList.toggle('active');
toggle.setAttribute('aria-checked', toggle.classList.contains('active') ? 'true' : 'false');
};
}
});
}
function getModalPreferences() {
const preferences = {};
cookieCategories.forEach(key => {
const toggle = document.getElementById(`cookie-toggle-${key}`);
preferences[key] = key === 'necessary' ? true : (toggle ? toggle.classList.contains('active') : false);
});
return preferences;
}
// ==========================================
// EVENT LISTENERS
// ==========================================
if (acceptAllBtn) {
acceptAllBtn.addEventListener('click', () => {
const preferences = {};
cookieCategories.forEach(key => preferences[key] = true);
saveConsent(preferences);
hideBanner();
});
}
if (rejectAllBtn) {
rejectAllBtn.addEventListener('click', () => {
saveConsent({ necessary: true, analytics: false, marketing: false });
hideBanner();
});
}
if (settingsBtn) {
settingsBtn.addEventListener('click', showSettingsModal);
}
if (modalCloseBtn) {
modalCloseBtn.addEventListener('click', hideSettingsModal);
}
if (savePreferencesBtn) {
savePreferencesBtn.addEventListener('click', () => {
saveConsent(getModalPreferences());
hideSettingsModal();
hideBanner();
});
}
if (cookieModal) {
cookieModal.addEventListener('click', (e) => {
if (e.target === cookieModal) hideSettingsModal();
});
}
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && cookieModal && cookieModal.classList.contains('show')) {
hideSettingsModal();
}
});
// ==========================================
// PUBLIC API
// ==========================================
window.CookieConsent = {
getConsent: () => consentState,
hasConsent: (category) => consentState.preferences[category] === true,
updateConsent: saveConsent,
showSettings: showSettingsModal
};
// ==========================================
// INITIALIZE
// ==========================================
initCookieConsent();
});

View File

@@ -0,0 +1,210 @@
// cursor.js
document.addEventListener("DOMContentLoaded", function () {
if (window.matchMedia("(pointer: coarse)").matches) return;
// --- SETTINGS ---
const CONFIG = {
tentacleCount: 8,
triggerDist: 10,
maxLength: 300,
connectionDist: 150,
thickness: 1,
color: "rgba(20, 20, 20, 1)",
prediction: 3.5
};
const toggleBtn = document.getElementById('cursorToggle');
const body = document.body;
// Default to system cursor (disabled custom cursor)
let isCursorDisabled = localStorage.getItem('venomCursorDisabled') !== 'false';
function updateCursorState() {
if (isCursorDisabled) {
// System cursor (default) - show spidy icon
body.classList.add('system-cursor');
if (toggleBtn) {
toggleBtn.classList.remove('active');
const icon = toggleBtn.querySelector('.cursor-icon');
if (icon) {
// Check if we're on a page in the sites/ folder
const currentPath = window.location.pathname;
const isInSitesFolder = currentPath.includes('/sites/');
const imagePath = isInSitesFolder ? '../images/additional/spidy.png' : 'images/additional/spidy.png';
icon.src = imagePath;
}
}
} else {
// Custom cursor (secondary) - show cursor icon
body.classList.remove('system-cursor');
if (toggleBtn) {
toggleBtn.classList.add('active');
const icon = toggleBtn.querySelector('.cursor-icon');
if (icon) {
// Check if we're on a page in the sites/ folder
const currentPath = window.location.pathname;
const isInSitesFolder = currentPath.includes('/sites/');
const imagePath = isInSitesFolder ? '../images/additional/cursor.png' : 'images/additional/cursor.png';
icon.src = imagePath;
}
}
}
}
updateCursorState();
if (toggleBtn) {
toggleBtn.addEventListener('click', () => {
isCursorDisabled = !isCursorDisabled;
localStorage.setItem('venomCursorDisabled', isCursorDisabled);
updateCursorState();
});
}
const canvas = document.createElement("canvas");
canvas.id = "venom-cursor";
document.body.appendChild(canvas);
const ctx = canvas.getContext("2d");
const width = window.innerWidth;
const height = window.innerHeight;
canvas.width = width;
canvas.height = height;
const tentacles = [];
const mouse = { x: 0, y: 0 };
const oldMouse = { x: 0, y: 0 };
document.addEventListener("mousemove", (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
class Tentacle {
constructor(mx, my, targetX, targetY) {
this.dead = false;
this.anchor = { x: targetX, y: targetY };
this.currentDist = 0; // For calculating connection opacity
}
update(currentMouse) {
const dx = currentMouse.x - this.anchor.x;
const dy = currentMouse.y - this.anchor.y;
this.currentDist = Math.sqrt(dx*dx + dy*dy);
if (this.currentDist > CONFIG.maxLength) {
this.dead = true;
}
}
draw(ctx, currentMouse) {
if (this.dead) return;
// Tension (0..1)
const tension = Math.min(this.currentDist / CONFIG.maxLength, 1);
const dynamicThickness = CONFIG.thickness * (1 - tension * 0.9);
// Draw main line (Cursor -> Anchor)
ctx.beginPath();
ctx.moveTo(currentMouse.x, currentMouse.y);
ctx.lineTo(this.anchor.x, this.anchor.y);
ctx.lineWidth = Math.max(0.2, dynamicThickness);
ctx.strokeStyle = CONFIG.color;
ctx.lineCap = "butt";
ctx.stroke();
// Draw anchor point
ctx.beginPath();
ctx.arc(this.anchor.x, this.anchor.y, 1.5 * (1 - tension), 0, Math.PI * 2);
ctx.fillStyle = CONFIG.color;
ctx.fill();
}
}
function render() {
ctx.clearRect(0, 0, width, height);
// 1. Create new tentacles on movement
const distMoved = Math.hypot(mouse.x - oldMouse.x, mouse.y - oldMouse.y);
if (distMoved > CONFIG.triggerDist) {
const vx = mouse.x - oldMouse.x;
const vy = mouse.y - oldMouse.y;
// "Spread" of shots increased slightly for better geometry
const targetX = mouse.x + vx * CONFIG.prediction + (Math.random() - 0.5) * 60;
const targetY = mouse.y + vy * CONFIG.prediction + (Math.random() - 0.5) * 60;
tentacles.push(new Tentacle(mouse.x, mouse.y, targetX, targetY));
oldMouse.x = mouse.x;
oldMouse.y = mouse.y;
}
// Remove old ones (FIFO)
if (tentacles.length > CONFIG.tentacleCount) {
tentacles.shift();
}
// 2. Draw main tentacles
for (let i = tentacles.length - 1; i >= 0; i--) {
const t = tentacles[i];
t.update(mouse);
if (t.dead) {
tentacles.splice(i, 1);
} else {
t.draw(ctx, mouse);
}
}
// 3. DRAW CONNECTIONS BETWEEN ANCHORS (New logic)
// Iterate through all pairs of active tentacles
ctx.beginPath(); // Begin common path for optimization
ctx.lineWidth = 0.5; // Connections are always thin
for (let i = 0; i < tentacles.length; i++) {
for (let j = i + 1; j < tentacles.length; j++) {
const t1 = tentacles[i];
const t2 = tentacles[j];
// Calculate distance between ends of two tentacles
const dx = t1.anchor.x - t2.anchor.x;
const dy = t1.anchor.y - t2.anchor.y;
const dist = Math.sqrt(dx*dx + dy*dy);
// If they are close to each other — connect
if (dist < CONFIG.connectionDist) {
// Opacity depends on how far apart they are
// And how much the tentacles themselves are stretched
const alpha = (1 - dist / CONFIG.connectionDist) * 0.6;
ctx.beginPath(); // New path for each to control opacity
ctx.strokeStyle = `rgba(20, 20, 20, ${alpha})`;
ctx.moveTo(t1.anchor.x, t1.anchor.y);
ctx.lineTo(t2.anchor.x, t2.anchor.y);
ctx.stroke();
}
}
}
// 4. Cursor (Rhombus)
ctx.beginPath();
ctx.fillStyle = CONFIG.color;
ctx.moveTo(mouse.x, mouse.y - 5);
ctx.lineTo(mouse.x + 5, mouse.y);
ctx.lineTo(mouse.x, mouse.y + 5);
ctx.lineTo(mouse.x - 5, mouse.y);
ctx.fill();
requestAnimationFrame(render);
}
render();
});

View File

@@ -0,0 +1,75 @@
// leads.js
// ==========================================
// 1. MENU TOGGLE
// ==========================================
const menuToggle = document.getElementById('menuToggle');
const slideMenu = document.getElementById('slideMenu');
const overlay = document.getElementById('overlay');
if (menuToggle && slideMenu && overlay) {
function toggleMenu() {
menuToggle.classList.toggle('active');
slideMenu.classList.toggle('active');
overlay.classList.toggle('active');
}
menuToggle.addEventListener('click', toggleMenu);
overlay.addEventListener('click', toggleMenu);
}
// ==========================================
// 2. LEADS TABLE LOGIC
// ==========================================
function getLeads() {
const storedLeads = localStorage.getItem('myLeads');
if (storedLeads) {
return JSON.parse(storedLeads);
} else {
return [];
}
}
function populateLeadsTable() {
const tableBody = document.getElementById('leadsTableBody');
const leadsData = getLeads();
if (!tableBody) return;
if (leadsData.length === 0) {
tableBody.innerHTML = `
<tr>
<td colspan="4" class="empty-state">
<p>Keine Anfragen vorhanden</p>
</td>
</tr>
`;
return;
}
tableBody.innerHTML = leadsData.map(lead => `
<tr>
<td>${lead.datum}</td>
<td>${lead.dienstleistung}</td>
<td>
<span class="status-badge ${lead.status}">${lead.statusText}</span>
</td>
<td>
<a href="#" class="action-btn" data-id="${lead.id}">Details ansehen</a>
</td>
</tr>
`).join('');
document.querySelectorAll('.action-btn').forEach(btn => {
btn.addEventListener('click', function(e) {
e.preventDefault();
const leadId = this.getAttribute('data-id');
// Redirect to lead details page
window.location.href = `lead-details.html?id=${leadId}`;
});
});
}
document.addEventListener('DOMContentLoaded', populateLeadsTable);

View File

@@ -0,0 +1,217 @@
// login.js
document.addEventListener("DOMContentLoaded", function() {
const loginForm = document.getElementById('loginForm');
const loginBtn = document.getElementById('loginSubmit');
const successMessage = document.getElementById('successMessage');
const errorMessage = document.getElementById('errorMessage');
const errorText = document.getElementById('errorText');
const registerBtn = document.getElementById('registerBtn');
// Register button functionality
if (registerBtn) {
registerBtn.addEventListener('click', function(e) {
e.preventDefault();
window.location.href = 'register.html';
});
}
// Check if user is already logged in
checkExistingSession();
// Login form submission
if (loginForm) {
loginForm.addEventListener('submit', async function(e) {
e.preventDefault();
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
const remember = document.getElementById('remember').checked;
// Simple validation
if (!email || !password) {
showError('Bitte füllen Sie alle Felder aus.');
return;
}
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
showError('Bitte geben Sie eine gültige E-Mail-Adresse ein.');
return;
}
// Show loading state
setLoadingState(true);
hideMessages();
// Send login data to PHP API
const loginData = {
type: 'login',
email: email,
password: password,
remember: remember
};
try {
const response = await fetch('../scripts/add/send.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(loginData)
});
const result = await response.json();
if (result.success) {
// Store session (for demo purposes - in real app, this would come from server)
const sessionData = {
user: { email: email },
loginTime: new Date().toISOString(),
remember: remember
};
if (remember) {
localStorage.setItem('userSession', JSON.stringify(sessionData));
} else {
sessionStorage.setItem('userSession', JSON.stringify(sessionData));
}
// Show success message
showSuccess('Anmeldung erfolgreich! Sie werden weitergeleitet...');
// Redirect after delay
setTimeout(() => {
window.location.href = '../index.html';
}, 2000);
} else {
showError('Anmeldung fehlgeschlagen: ' + result.message);
}
} catch (error) {
console.error('Login error:', error);
showError('Netzwerkfehler bei der Anmeldung. Bitte versuchen Sie es später erneut.');
}
setLoadingState(false);
});
}
// Loading state management
function setLoadingState(loading) {
if (loginBtn) {
const btnText = loginBtn.querySelector('.btn-text');
const btnLoading = loginBtn.querySelector('.btn-loading');
if (loading) {
loginBtn.disabled = true;
if (btnText) btnText.style.display = 'none';
if (btnLoading) btnLoading.style.display = 'inline-block';
} else {
loginBtn.disabled = false;
if (btnText) btnText.style.display = 'inline-block';
if (btnLoading) btnLoading.style.display = 'none';
}
}
}
// Message display functions
function showSuccess(message) {
if (successMessage) {
const messageElement = successMessage.querySelector('p');
if (messageElement) {
messageElement.textContent = message;
}
successMessage.classList.add('show');
}
}
function showError(message) {
if (errorMessage && errorText) {
errorText.textContent = message;
errorMessage.classList.add('show');
// Hide after 5 seconds
setTimeout(() => {
errorMessage.classList.remove('show');
}, 5000);
}
}
function hideMessages() {
if (successMessage) successMessage.classList.remove('show');
if (errorMessage) errorMessage.classList.remove('show');
}
});
// Check existing session - DISABLED auto-redirect
function checkExistingSession() {
const sessionData = localStorage.getItem('userSession') || sessionStorage.getItem('userSession');
if (sessionData) {
try {
const session = JSON.parse(sessionData);
const loginTime = new Date(session.loginTime);
const now = new Date();
const sessionAge = (now - loginTime) / (1000 * 60 * 60); // hours
// Auto-logout after 24 hours
if (sessionAge < 24) {
// User is still logged in - just log it, don't redirect
console.log('User already logged in');
// DISABLED: window.location.href = '../index.html';
} else {
// Session expired, remove it
console.log('Session expired, removing...');
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
}
} catch (error) {
console.error('Session parsing error:', error);
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
}
}
}
// Logout function (can be called from other pages)
function logout() {
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
window.location.href = 'sites/login.html';
}
// Get current user (can be called from other pages)
function getCurrentUser() {
const sessionData = localStorage.getItem('userSession') || sessionStorage.getItem('userSession');
if (sessionData) {
try {
const session = JSON.parse(sessionData);
const loginTime = new Date(session.loginTime);
const now = new Date();
const sessionAge = (now - loginTime) / (1000 * 60 * 60); // hours
if (sessionAge < 24) {
return session.user;
} else {
// Session expired
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
return null;
}
} catch (error) {
console.error('Session parsing error:', error);
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
return null;
}
}
return null;
}
// Check if user is logged in (can be called from other pages)
function isLoggedIn() {
return getCurrentUser() !== null;
}

View File

@@ -0,0 +1,272 @@
// register.js
document.addEventListener("DOMContentLoaded", function() {
const registerForm = document.getElementById('registerForm');
const registerBtn = document.getElementById('registerSubmit');
const successMessage = document.getElementById('successMessage');
const errorMessage = document.getElementById('errorMessage');
const errorText = document.getElementById('errorText');
const passwordInput = document.getElementById('password');
const confirmPasswordInput = document.getElementById('confirmPassword');
const passwordStrength = document.getElementById('passwordStrength');
// Check if user is already logged in
checkExistingSession();
// Password strength checker
if (passwordInput && passwordStrength) {
passwordInput.addEventListener('input', function() {
const password = this.value;
const strength = checkPasswordStrength(password);
updatePasswordStrength(strength);
});
}
// Password confirmation checker
if (confirmPasswordInput && passwordInput) {
confirmPasswordInput.addEventListener('input', function() {
const password = passwordInput.value;
const confirmPassword = this.value;
if (confirmPassword && password !== confirmPassword) {
this.setCustomValidity('Passwörter stimmen nicht überein');
} else {
this.setCustomValidity('');
}
});
}
// Registration form submission
if (registerForm) {
registerForm.addEventListener('submit', async function(e) {
e.preventDefault();
// Get form data
const formData = {
type: 'register',
name: `${document.getElementById('firstName').value} ${document.getElementById('lastName').value}`,
email: document.getElementById('email').value,
phone: document.getElementById('phone').value,
company: document.getElementById('company').value,
password: passwordInput.value,
confirmPassword: confirmPasswordInput.value,
terms: document.getElementById('terms').checked,
newsletter: document.getElementById('newsletter').checked,
registrationTime: new Date().toISOString()
};
// Validation
const validation = validateRegistrationForm(formData);
if (!validation.valid) {
showError(validation.message);
return;
}
// Show loading state
setLoadingState(true);
hideMessages();
// Send registration data to PHP API
try {
const response = await fetch('../scripts/add/send.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
});
const result = await response.json();
if (result.success) {
// Store user data (for demo purposes)
const userData = {
firstName: document.getElementById('firstName').value,
lastName: document.getElementById('lastName').value,
email: formData.email,
phone: formData.phone,
company: formData.company,
registrationTime: formData.registrationTime,
newsletter: formData.newsletter
};
// Store in localStorage (for demo purposes)
localStorage.setItem('userData', JSON.stringify(userData));
localStorage.setItem('userRegistered', 'true');
// Show success message
showSuccess('Registrierung erfolgreich! Sie werden weitergeleitet...');
// Redirect after delay
setTimeout(() => {
window.location.href = '../index.html';
}, 2000);
} else {
showError('Registrierung fehlgeschlagen: ' + result.message);
}
} catch (error) {
console.error('Registration error:', error);
showError('Netzwerkfehler bei der Registrierung. Bitte versuchen Sie es später erneut.');
}
setLoadingState(false);
});
}
// Password strength checker function
function checkPasswordStrength(password) {
let strength = 0;
// Length check
if (password.length >= 8) strength++;
if (password.length >= 12) strength++;
// Character variety checks
if (/[a-z]/.test(password)) strength++; // lowercase
if (/[A-Z]/.test(password)) strength++; // uppercase
if (/[0-9]/.test(password)) strength++; // numbers
if (/[^a-zA-Z0-9]/.test(password)) strength++; // special characters
return strength;
}
// Update password strength indicator
function updatePasswordStrength(strength) {
const strengthBar = passwordStrength.querySelector('.strength-bar');
const strengthText = passwordStrength.querySelector('.strength-text');
// Remove all strength classes
passwordStrength.classList.remove('strength-weak', 'strength-medium', 'strength-strong');
if (strength <= 2) {
passwordStrength.classList.add('strength-weak');
strengthText.textContent = 'Schwach';
} else if (strength <= 4) {
passwordStrength.classList.add('strength-medium');
strengthText.textContent = 'Mittel';
} else {
passwordStrength.classList.add('strength-strong');
strengthText.textContent = 'Stark';
}
}
// Form validation
function validateRegistrationForm(data) {
// Required fields check
if (!data.firstName || !data.lastName || !data.email || !data.password) {
return { valid: false, message: 'Bitte füllen Sie alle Pflichtfelder aus.' };
}
// Name validation
if (data.firstName.length < 2 || data.lastName.length < 2) {
return { valid: false, message: 'Vorname und Nachname müssen mindestens 2 Zeichen lang sein.' };
}
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(data.email)) {
return { valid: false, message: 'Bitte geben Sie eine gültige E-Mail-Adresse ein.' };
}
// Password validation
if (data.password.length < 8) {
return { valid: false, message: 'Das Passwort muss mindestens 8 Zeichen lang sein.' };
}
// Password confirmation
if (data.password !== data.confirmPassword) {
return { valid: false, message: 'Die Passwörter stimmen nicht überein.' };
}
// Terms acceptance
if (!data.terms) {
return { valid: false, message: 'Sie müssen die Nutzungsbedingungen akzeptieren.' };
}
// Phone validation (if provided)
if (data.phone) {
const phoneRegex = /^[\d\s\-\+\(\)]+$/;
if (!phoneRegex.test(data.phone)) {
return { valid: false, message: 'Bitte geben Sie eine gültige Telefonnummer ein.' };
}
}
return { valid: true, message: 'Validierung erfolgreich' };
}
// Loading state management
function setLoadingState(loading) {
if (registerBtn) {
const btnText = registerBtn.querySelector('.btn-text');
const btnLoading = registerBtn.querySelector('.btn-loading');
if (loading) {
registerBtn.disabled = true;
if (btnText) btnText.style.display = 'none';
if (btnLoading) btnLoading.style.display = 'inline-block';
} else {
registerBtn.disabled = false;
if (btnText) btnText.style.display = 'inline-block';
if (btnLoading) btnLoading.style.display = 'none';
}
}
}
// Message display functions
function showSuccess(message) {
if (successMessage) {
const messageElement = successMessage.querySelector('p');
if (messageElement) {
messageElement.textContent = message;
}
successMessage.classList.add('show');
}
}
function showError(message) {
if (errorMessage && errorText) {
errorText.textContent = message;
errorMessage.classList.add('show');
// Hide after 5 seconds
setTimeout(() => {
errorMessage.classList.remove('show');
}, 5000);
}
}
function hideMessages() {
if (successMessage) successMessage.classList.remove('show');
if (errorMessage) errorMessage.classList.remove('show');
}
});
// Check existing session (same as login.js) - DISABLED auto-redirect
function checkExistingSession() {
const sessionData = localStorage.getItem('userSession') || sessionStorage.getItem('userSession');
if (sessionData) {
try {
const session = JSON.parse(sessionData);
const loginTime = new Date(session.loginTime);
const now = new Date();
const sessionAge = (now - loginTime) / (1000 * 60 * 60); // hours
// Auto-logout after 24 hours
if (sessionAge < 24) {
// User is still logged in - just log it, don't redirect
console.log('User already logged in');
// DISABLED: window.location.href = '../index.html';
} else {
// Session expired, remove it
console.log('Session expired, removing...');
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
}
} catch (error) {
console.error('Session parsing error:', error);
localStorage.removeItem('userSession');
sessionStorage.removeItem('userSession');
}
}
}

View File

@@ -0,0 +1,151 @@
/**
* Main Script - Profice Website
* All API calls go through server-side PHP
* Includes fallback for local file access (no server)
*
* @version 2.1.0
*/
document.addEventListener("DOMContentLoaded", function() {
const API_ENDPOINT = 'scripts/add/send.php';
const isLocalFile = window.location.protocol === 'file:';
// ==========================================
// 1. SMOOTH SCROLLING
// ==========================================
function initSmoothScrolling() {
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', function(e) {
const targetId = this.getAttribute('href');
if (targetId === '#') return;
const targetElement = document.querySelector(targetId);
if (targetElement) {
e.preventDefault();
const header = document.querySelector('.top-banner');
const headerHeight = header ? header.offsetHeight : 90;
window.scrollTo({
top: targetElement.offsetTop - headerHeight - 20,
behavior: 'smooth'
});
history.pushState(null, null, targetId);
}
});
});
}
initSmoothScrolling();
// ==========================================
// 2. MENU TOGGLE
// ==========================================
const menuToggle = document.getElementById('menuToggle');
const slideMenu = document.getElementById('slideMenu');
const overlay = document.getElementById('overlay');
if (menuToggle && slideMenu && overlay) {
const toggleMenu = () => {
menuToggle.classList.toggle('active');
slideMenu.classList.toggle('active');
overlay.classList.toggle('active');
};
menuToggle.addEventListener('click', toggleMenu);
overlay.addEventListener('click', toggleMenu);
}
// ==========================================
// 3. LOGIN BUTTON
// ==========================================
const loginBtn = document.getElementById('loginBtn');
if (loginBtn) {
const currentPath = window.location.pathname;
let loginPath = 'sites/login.html';
if (currentPath.includes('/sites/')) {
loginPath = currentPath.includes('login.html') ? 'register.html' : 'login.html';
}
loginBtn.onclick = (e) => {
e.preventDefault();
window.location.href = loginPath;
};
}
// ==========================================
// 4. FORM SUBMISSION
// ==========================================
const contactForm = document.getElementById('contactForm');
const successMessage = document.getElementById('successMessage');
if (contactForm) {
contactForm.addEventListener('submit', async function(e) {
e.preventDefault();
const getValue = (id) => {
const el = document.getElementById(id);
return el ? el.value : '';
};
const serviceSelect = document.getElementById('service');
const selectedServiceText = serviceSelect ?
serviceSelect.options[serviceSelect.selectedIndex].text : 'Dienstleistung';
const formData = {
type: 'contact',
name: getValue('name'),
organisation: getValue('organisation'),
contact: getValue('contact'),
service: getValue('service'),
budget: getValue('budget'),
description: getValue('description')
};
// Always store locally for dashboard
try {
const localLead = {
id: Date.now(),
datum: new Date().toLocaleDateString('de-DE'),
dienstleistung: selectedServiceText,
status: 'open',
statusText: 'Offen',
description: formData.description
};
const existingLeads = JSON.parse(localStorage.getItem('myLeads') || '[]');
existingLeads.unshift(localLead);
localStorage.setItem('myLeads', JSON.stringify(existingLeads.slice(0, 100)));
} catch (err) {}
// Send to API if not local file
if (!isLocalFile) {
try {
const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});
const result = await response.json();
if (!result.success) {
alert('Fehler beim Senden: ' + (result.message || 'Unbekannter Fehler'));
return;
}
} catch (error) {
alert('Netzwerkfehler beim Senden des Formulars');
return;
}
}
// Show success
contactForm.style.display = 'none';
if (successMessage) successMessage.classList.add('show');
contactForm.reset();
});
}
});

View File

@@ -0,0 +1,83 @@
// scroll-header.js
document.addEventListener("DOMContentLoaded", function() {
const topBanner = document.querySelector('.top-banner');
const slideMenu = document.querySelector('.slide-menu');
if (!topBanner) return;
// Scroll threshold to trigger the shrink effect
const scrollThreshold = 50;
let isScrolled = false;
let isTransitioning = false;
let lastScrollY = 0;
let scrollDirection = 'down';
function updateHeaderState(scrolled) {
if (isTransitioning) return;
if (scrolled && !isScrolled) {
isTransitioning = true;
topBanner.classList.add('scrolled');
isScrolled = true;
if (slideMenu) {
slideMenu.style.top = '80px';
}
// Reset transition flag after animation completes
setTimeout(() => {
isTransitioning = false;
}, 250);
} else if (!scrolled && isScrolled) {
isTransitioning = true;
topBanner.classList.remove('scrolled');
isScrolled = false;
if (slideMenu) {
slideMenu.style.top = '110px';
}
// Reset transition flag after animation completes
setTimeout(() => {
isTransitioning = false;
}, 250);
}
}
function handleScroll() {
const currentScrollY = window.pageYOffset || document.documentElement.scrollTop;
// Detect scroll direction
if (currentScrollY > lastScrollY) {
scrollDirection = 'down';
} else if (currentScrollY < lastScrollY) {
scrollDirection = 'up';
}
// Only update when crossing threshold in the right direction
if (scrollDirection === 'down' && currentScrollY > scrollThreshold && !isScrolled) {
updateHeaderState(true);
} else if (scrollDirection === 'up' && currentScrollY <= scrollThreshold && isScrolled) {
updateHeaderState(false);
}
lastScrollY = currentScrollY;
}
// Use requestAnimationFrame for smooth scroll handling
let ticking = false;
function requestTick() {
if (!ticking) {
requestAnimationFrame(handleScroll);
ticking = true;
setTimeout(() => { ticking = false; }, 16); // ~60fps
}
}
// Optimized scroll event listener
window.addEventListener('scroll', requestTick, { passive: true, capture: false });
// Initial check
handleScroll();
});

View File

@@ -0,0 +1,213 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice - Automatisierung</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/service.css">
<link rel="stylesheet" href="../style/cursor.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menu">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Home</a>
<a href="../index.html#enterprise" class="nav-link">Enterprise</a>
<a href="../index.html#pricing" class="nav-link">Pricing</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Toggle Cursor" title="Toggle Custom Cursor">
<img src="../images/additional/cursor.png" alt="Default Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Log in" title="Log in">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Log in
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html" class="active">Kontakt & Anfrage</a>
<a href="leads.html">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content">
<div class="service-container">
<!-- Service Header -->
<div class="service-header">
<div class="service-icon">⚙️</div>
<h1 class="service-title">Automatisierung</h1>
<p class="service-subtitle">Sparen Sie Zeit und Ressourcen durch intelligente Workflow-Automatisierungen</p>
</div>
<!-- Service Description -->
<section class="service-section">
<h2 class="section-title">Unsere Automatisierungslösungen</h2>
<p class="section-text">
Wir automatisieren Ihre Geschäftsprozesse, um Effizienz zu steigern und menschliche Fehler zu reduzieren.
Von einfachen wiederkehrenden Aufgaben bis zu komplexen Workflow-Integrationen - wir finden die optimale Lösung.
</p>
</section>
<!-- Service Features -->
<section class="service-section">
<h2 class="section-title">Was wir automatisieren können</h2>
<div class="features-grid">
<div class="feature-item">
<div class="feature-icon">📧</div>
<h3>E-Mail-Automatisierung</h3>
<p>Automatische Antwortverwaltung und E-Mail-Kampagnen</p>
</div>
<div class="feature-item">
<div class="feature-icon">📄</div>
<h3>Datenverarbeitung</h3>
<p>Automatische Datenmigration und -bereinigung</p>
</div>
<div class="feature-item">
<div class="feature-icon">📋</div>
<h3>Report-Generierung</h3>
<p>Automatische Erstellung von Berichten und Analysen</p>
</div>
<div class="feature-item">
<div class="feature-icon">🔄</div>
<h3>Workflow-Integration</h3>
<p>Verbindung verschiedener Systeme für nahtlose Prozesse</p>
</div>
<div class="feature-item">
<div class="feature-icon">📊</div>
<h3>Monitoring</h3>
<p>Automatische Systemüberwachung und Alarmierung</p>
</div>
<div class="feature-item">
<div class="feature-icon">🎯</div>
<h3>Task-Management</h3>
<p>Intelligente Aufgabenverteilung und -verfolgung</p>
</div>
</div>
</section>
<!-- Process -->
<section class="service-section">
<h2 class="section-title">Unser Automatisierungsprozess</h2>
<div class="process-timeline">
<div class="process-item">
<div class="process-number">1</div>
<div class="process-content">
<h3>Prozessanalyse</h3>
<p>Identifizierung von Automatisierungspotenzialen</p>
</div>
</div>
<div class="process-item">
<div class="process-number">2</div>
<div class="process-content">
<h3>Lösungsdesign</h3>
<p>Entwicklung maßgeschneiderter Automatisierungslösungen</p>
</div>
</div>
<div class="process-item">
<div class="process-number">3</div>
<div class="process-content">
<h3>Implementierung</h3>
<p>Setup und Konfiguration der Automatisierungstools</p>
</div>
</div>
<div class="process-item">
<div class="process-number">4</div>
<div class="process-content">
<h3>Testing</h3>
<p>Gewissenhafte Tests vor der Live-Schaltung</p>
</div>
</div>
<div class="process-item">
<div class="process-number">5</div>
<div class="process-content">
<h3>Monitoring</h3>
<p>Laufende Überwachung und Optimierung</p>
</div>
</div>
</div>
</section>
<!-- Technologies -->
<section class="section">
<h2 class="section-title">Automatisierungstechnologien</h2>
<div class="tech-grid">
<div class="tech-item">Zapier</div>
</div>
</section>
<!-- Benefits -->
<section class="service-section">
<h2 class="section-title">Ihre Vorteile</h2>
<div class="benefits-grid">
<div class="benefit-item">
<div class="benefit-icon">⏰️</div>
<h3>Zeitersparnis</h3>
<p>Bis zu 80% Zeitersparnis bei wiederkehrenden Aufgaben</p>
</div>
<div class="benefit-item">
<div class="benefit-icon">🎯</div>
<h3>Qualitätssteigerung</h3>
<p>Reduzierung menschlicher Fehler und konsistente Ergebnisse</p>
</div>
<div class="benefit-item">
<div class="benefit-icon">💰</div>
<h3>Kostensenkung</h3>
<p>Optimierung von Ressourcen und Betriebskosten</p>
</div>
<div class="benefit-item">
<div class="benefit-icon">📈</div>
<h3>Skalierbarkeit</div>
<p>Einfache Handhabung wachsender Geschäftsanforderungen</p>
</div>
<div class="benefit-item">
<div class="benefit-icon">😊</div>
<h3>Mitarbeiterzufriedenheit</h3>
<p>Fokus auf kreative und strategische Aufgaben</p>
</div>
</div>
</section>
<!-- CTA Section -->
<section class="service-section">
<h2 class="section-title">Bereit für mehr Effizienz?</h2>
<p class="section-text">Lassen Sie uns Ihre Prozesse analysieren und Potenziale identifizieren.</p>
<div class="cta-buttons">
<a href="offers.html?service=automatisation" class="cta-btn primary">Automatisierungs-Analyse</a>
<a href="offers.html" class="cta-btn secondary">Mehr erfahren</a>
</div>
</section>
</div>
</main>
<script src="../scripts/script.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
</body>
</html>

View File

@@ -0,0 +1,217 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice - KI Integration</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/service.css">
<link rel="stylesheet" href="../style/cursor.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menu">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Home</a>
<a href="../index.html#enterprise" class="nav-link">Enterprise</a>
<a href="../index.html#pricing" class="nav-link">Pricing</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Toggle Cursor" title="Toggle Custom Cursor">
<img src="../images/additional/cursor.png" alt="Default Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Log in" title="Log in">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Log in
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html" class="active">Kontakt & Anfrage</a>
<a href="leads.html">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content">
<div class="service-container">
<!-- Service Header -->
<div class="service-header">
<div class="service-icon">🤖</div>
<h1 class="service-title">KI Integration</h1>
<p class="service-subtitle">Nutzen Sie die Kraft künstlicher Intelligenz, um Ihre Daten besser zu verstehen und Prozesse zu optimieren</p>
</div>
<!-- Service Description -->
<section class="service-section">
<h2 class="section-title">Unsere KI-Dienstleistungen</h2>
<p class="section-text">
Wir integrieren künstliche Intelligenz in Ihre Geschäftsprozesse, um Effizienz zu steigern und neue Möglichkeiten zu erschließen.
Von der Datenanalyse über automatisierte Prozesse bis zu intelligenten Chatbots - wir machen KI für Sie nutzbar.
</p>
</section>
<!-- Service Features -->
<section class="service-section">
<h2 class="section-title">Was wir bieten</h2>
<div class="features-grid">
<div class="feature-item">
<div class="feature-icon">📊</div>
<h3>Datenanalyse</h3>
<p>Intelligente Auswertung Ihrer Geschäftsdaten für bessere Entscheidungen</p>
</div>
<div class="feature-item">
<div class="feature-icon">🤖</div>
<h3>Chatbots</h3>
<p>24/7 Kundenbetreuung und automatisierte Kommunikation</p>
</div>
<div class="feature-item">
<div class="feature-icon">⚙️</div>
<h3>Prozessautomatisierung</h3>
<p>Automatisierung wiederkehrender Aufgaben zur Effizienzsteigerung</p>
</div>
<div class="feature-item">
<div class="feature-icon">🔍</div>
<h3>Bilderkennung</h3>
<p>Automatische Analyse von Bildern und Dokumenten</p>
</div>
<div class="feature-item">
<div class="feature-icon">📈</div>
<h3>Vorhersagemodelle</h3>
<p>Prognosen für Trends und Geschäftsentwicklungen</p>
</div>
<div class="feature-item">
<div class="feature-icon">🎯</div>
<h3>Personalisierung</h3>
<p>Individuelle KI-Lösungen für Ihre spezifischen Bedürfnisse</p>
</div>
</div>
</section>
<!-- Process -->
<section class="service-section">
<h2 class="section-title">Unser KI-Integrationsprozess</h2>
<div class="process-timeline">
<div class="process-item">
<div class="process-number">1</div>
<div class="process-content">
<h3>Analyse & Potenzial</h3>
<p>Identifizierung von KI-Einsatzmöglichkeiten in Ihrem Unternehmen</p>
</div>
</div>
<div class="process-item">
<div class="process-number">2</div>
<div class="process-content">
<h3>Datenstrategie</h3>
<p>Planung der Datenerfassung und -verarbeitung</p>
</div>
</div>
<div class="process-item">
<div class="process-number">3</div>
<div class="process-content">
<h3>Modellentwicklung</h3>
<p>Training oder Auswahl passender KI-Modelle</p>
</div>
</div>
<div class="process-item">
<div class="process-number">4</div>
<div class="process-content">
<h3>Integration</h3>
<p>Nahtlose Anbindung an Ihre bestehenden Systeme</p>
</div>
</div>
<div class="process-item">
<div class="process-number">5</div>
<div class="process-content">
<h3>Optimierung</h3>
<p>Kontinuierliche Verbesserung der KI-Modelle</p>
</div>
</div>
</div>
</section>
<!-- Technologies -->
<section class="service-section">
<h2 class="section-title">KI-Technologien</h2>
<div class="tech-grid">
<div class="tech-item">TensorFlow</div>
<div class="tech-item">PyTorch</div>
<div class="tech-item">Scikit-learn</div>
<div class="tech-item">OpenAI API</div>
<div class="tech-item">Google Cloud AI</div>
<div class="tech-item">Azure ML</div>
<div class="tech-item">AWS SageMaker</div>
<div class="tech-item">Hugging Face</div>
<div class="tech-item">LangChain</div>
<div class="tech-item">Dialogflow</div>
</div>
</section>
<!-- Use Cases -->
<section class="service-section">
<h2 class="section-title">Anwendungsfälle</h2>
<div class="use-cases-grid">
<div class="use-case-item">
<h3>Kundenservice</h3>
<p>Intelligente Chatbots für 24/7 Unterstützung</p>
</div>
<div class="use-case-item">
<h3>Vertrieb</h3>
<p>Predictive Lead Scoring und Verkaufsoptimierung</p>
</div>
<div class="use-case-item">
<h3>Marketing</h3>
<p>Personalisierte Kampagnen und Content-Optimierung</p>
</div>
<div class="use-case-item">
<h3>Finanzen</h3>
<p>Betrugsprüfung und Risikoanalyse</p>
</div>
<div class="use-case-item">
<h3>Produktion</h3>
<p>Qualitätssicherung und Predictive Maintenance</p>
</div>
</div>
</section>
<!-- CTA Section -->
<section class="service-section">
<h2 class="section-title">Bereit für KI in Ihrem Unternehmen?</h2>
<p class="section-text">Lassen Sie uns die Potenziale für Ihr Unternehmen analysieren.</p>
<div class="cta-buttons">
<a href="offers.html?service=ki-integration" class="cta-btn primary">KI-Analyse anfordern</a>
<a href="offers.html" class="cta-btn secondary">Mehr erfahren</a>
</div>
</section>
</div>
</main>
<script src="../scripts/script.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice - Leads Dashboard</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/leads.css">
<link rel="stylesheet" href="../style/cursor.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menü">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Startseite</a>
<a href="../index.html#enterprise" class="nav-link">Unternehmen</a>
<a href="../index.html#pricing" class="nav-link">Preise</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Cursor umschalten" title="Benutzerdefinierten Cursor umschalten">
<img src="../images/additional/cursor.png" alt="Standard Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Anmelden" title="Anmelden">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Anmelden
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html">Kontakt & Anfrage</a>
<a href="leads.html" class="active">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content leads-content">
<!-- Leads Widget -->
<div class="dashboard-container">
<h2 class="dashboard-title">Meine Anfragen</h2>
<p class="dashboard-subtitle">Übersicht Ihrer aktuellen Projektanfragen</p>
<div class="leads-table-wrapper">
<table class="leads-table" id="leadsTable">
<thead>
<tr>
<th>Datum</th>
<th>Dienstleistung</th>
<th>Status</th>
<th>Aktion</th>
</tr>
</thead>
<tbody id="leadsTableBody">
<!-- Populated by leads.js -->
</tbody>
</table>
</div>
</div>
<!-- Other Offers Section -->
<div class="dashboard-container offers-section">
<h2 class="dashboard-title">Andere Angebote von uns</h2>
<p class="dashboard-subtitle">Entdecken Sie weitere Dienstleistungen</p>
<div class="offers-grid">
<div class="offer-card">
<div class="offer-icon">🔍</div>
<h3 class="offer-title">SEO Optimierung</h3>
<p class="offer-description">Verbessern Sie Ihre Sichtbarkeit in Suchmaschinen und erreichen Sie mehr Kunden online.</p>
<a href="details.html?service=seo-optimierung" class="offer-btn">Details ansehen</a>
</div>
<div class="offer-card">
<div class="offer-icon">☁️</div>
<h3 class="offer-title">Cloud Migration</h3>
<p class="offer-description">Modernisieren Sie Ihre IT-Infrastruktur mit sicheren und skalierbaren Cloud-Lösungen.</p>
<a href="details.html?service=cloud-migration" class="offer-btn">Details ansehen</a>
</div>
<div class="offer-card">
<div class="offer-icon">📊</div>
<h3 class="offer-title">Datenanalyse</h3>
<p class="offer-description">Gewinnen Sie wertvolle Einblicke aus Ihren Daten mit unseren Analyse-Lösungen.</p>
<a href="details.html?service=datenanalyse" class="offer-btn">Details ansehen</a>
</div>
</div>
</div>
</main>
<script src="../scripts/leads.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
</body>
</html>

View File

@@ -0,0 +1,138 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice - Anmeldung</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/login.css">
<link rel="stylesheet" href="../style/cursor.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menü">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Startseite</a>
<a href="../index.html#enterprise" class="nav-link">Unternehmen</a>
<a href="../index.html#pricing" class="nav-link">Preise</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Cursor umschalten" title="Benutzerdefinierten Cursor umschalten">
<img src="../images/additional/cursor.png" alt="Standard Cursor" class="cursor-icon">
</button>
<button id="registerBtn" class="login-btn register" aria-label="Registrieren" title="Registrieren">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
<circle cx="8.5" cy="7" r="4"></circle>
<line x1="20" y1="8" x2="20" y2="14"></line>
<line x1="23" y1="11" x2="17" y2="11"></line>
</svg>
Registrieren
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html">Kontakt & Anfrage</a>
<a href="leads.html">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content login-content">
<div class="login-container">
<div class="login-header">
<div class="login-icon">🔐</div>
<h1 class="login-title">Willkommen zurück</h1>
<p class="login-subtitle">Melden Sie sich an, um auf Ihr Konto zuzugreifen</p>
</div>
<form id="loginForm" class="login-form">
<div class="form-group">
<label for="email">E-Mail</label>
<input type="email" id="email" name="email" required placeholder="ihre@email.de">
</div>
<div class="form-group">
<label for="password">Passwort</label>
<input type="password" id="password" name="password" required placeholder="Passwort">
</div>
<div class="form-options">
<label class="checkbox-label">
<input type="checkbox" id="remember" name="remember">
<span class="checkbox-custom"></span>
Angemeldet bleiben
</label>
<a href="#" class="forgot-password">Passwort vergessen?</a>
</div>
<button type="submit" class="login-btn-submit" id="loginSubmit">
<span class="btn-text">Anmelden</span>
<span class="btn-loading" style="display: none;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12a9 9 0 1 1-6.219-8.56"></path>
<polyline points="22 6 12 16 2 6"></polyline>
</svg>
</span>
</button>
</form>
<div class="login-divider">
<span>oder</span>
</div>
<div class="social-login">
<button type="button" class="social-btn google-btn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c-.82 2.33-2.85 4.08-5.92 4.08-.57 0-1.11-.08-1.63-.24V14.6c.52.16 1.06.24 1.63.24 3.07 0 5.52-2.51 5.52-5.52 0-.1 0-.2-.01-.3-.57-2.53-2.11-4.52-4.52-4.52zM12 23c-1.61 0-3.09-.59-4.23-1.57l.01-.02V18.6l-.01.02c1.14-.98 2.62-1.57 4.23-1.57 3.07 0 5.52 2.51 5.52 5.52 0 .1 0 .2-.01.3z"/>
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.46l-2.85 2.22c-.81-.62-1.79-1.11-2.85-1.36-.52-.16-1.06-.24-1.63-.24-3.07 0-5.52 2.51-5.52 5.52 0 .1 0 .2.01.3.57 2.53 2.11 4.52 4.52 4.52z"/>
</svg>
Mit Google anmelden
</button>
</div>
<div class="login-footer">
<p>Noch kein Konto? <a href="register.html">Jetzt registrieren</a></p>
</div>
<div class="success-message" id="successMessage">
<div class="success-icon"></div>
<h3>Erfolgreich angemeldet!</h3>
<p>Sie werden weitergeleitet...</p>
</div>
<div class="error-message" id="errorMessage">
<div class="error-icon"></div>
<h3>Anmeldung fehlgeschlagen</h3>
<p id="errorText">Bitte überprüfen Sie Ihre Anmeldedaten.</p>
</div>
</div>
</main>
<script src="../scripts/script.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
<script src="../scripts/login.js"></script>
</body>
</html>

View File

@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/cursor.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menü">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Startseite</a>
<a href="../index.html#enterprise" class="nav-link">Unternehmen</a>
<a href="../index.html#pricing" class="nav-link">Preise</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Cursor umschalten" title="Benutzerdefinierten Cursor umschalten">
<img src="../images/additional/cursor.png" alt="Standard Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Anmelden" title="Anmelden">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Anmelden
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html" class="active">Kontakt & Anfrage</a>
<a href="leads.html">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content">
<div class="form-container">
<h2 class="form-title">Kontaktieren Sie uns</h2>
<form id="contactForm">
<div class="form-group">
<label for="name">Name *</label>
<input type="text" id="name" name="name" required placeholder="Ihr vollständiger Name">
</div>
<div class="form-group">
<label for="organisation">Organisation</label>
<input type="text" id="organisation" name="organisation" placeholder="Firmenname (optional)">
</div>
<div class="form-group">
<label for="contact">E-Mail oder Telefonnummer *</label>
<input type="text" id="contact" name="contact" required placeholder="email@beispiel.de oder +49 123 456789">
</div>
<div class="form-group">
<label for="service">Gewünschte Dienstleistung *</label>
<select id="service" name="service" required>
<option value="" disabled selected>Bitte wählen...</option>
<option value="website">Website</option>
<option value="ki-integration">KI Integration</option>
<option value="automatisation">Automatisation</option>
<option value="unabhaengige-wahl">Unabhängige Wahl</option>
</select>
</div>
<div class="form-group">
<label for="budget">Budget (€)</label>
<input type="text" id="budget" name="budget" placeholder="z.B. 5000 - 10000">
</div>
<div class="form-group">
<label for="description">Beschreibung *</label>
<textarea id="description" name="description" required placeholder="Beschreiben Sie Ihr Projekt oder Ihre Anfrage..."></textarea>
</div>
<button type="submit" class="submit-btn">Anfrage senden</button>
</form>
<div class="success-message" id="successMessage">
<h3>Vielen Dank!</h3>
<p>Ihre Anfrage wurde erfolgreich gesendet. Wir melden uns bald bei Ihnen.</p>
</div>
</div>
</main>
<script src="../scripts/script.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
</body>
</html>

View File

@@ -0,0 +1,174 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registrierung - Profice</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/cursor.css">
<link rel="stylesheet" href="../style/login.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menü">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Startseite</a>
<a href="../index.html#enterprise" class="nav-link">Unternehmen</a>
<a href="../index.html#pricing" class="nav-link">Preise</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Cursor umschalten" title="Benutzerdefinierten Cursor umschalten">
<img src="../images/additional/cursor.png" alt="Standard Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Anmelden" title="Anmelden">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Anmelden
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html">Kontakt & Anfrage</a>
<a href="leads.html">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content login-content">
<div class="login-container">
<div class="login-header">
<div class="login-icon">👤</div>
<h1 class="login-title">Konto erstellen</h1>
<p class="login-subtitle">Registrieren Sie sich, um auf alle Funktionen zuzugreifen</p>
</div>
<form id="registerForm" class="login-form">
<div class="form-row">
<div class="form-group">
<label for="firstName">Vorname *</label>
<input type="text" id="firstName" name="firstName" required placeholder="Max">
</div>
<div class="form-group">
<label for="lastName">Nachname *</label>
<input type="text" id="lastName" name="lastName" required placeholder="Mustermann">
</div>
</div>
<div class="form-group">
<label for="email">E-Mail *</label>
<input type="email" id="email" name="email" required placeholder="ihre@email.de">
</div>
<div class="form-group">
<label for="phone">Telefonnummer</label>
<input type="tel" id="phone" name="phone" placeholder="+49 123 456789">
</div>
<div class="form-group">
<label for="company">Unternehmen</label>
<input type="text" id="company" name="company" placeholder="Firmenname (optional)">
</div>
<div class="form-group">
<label for="password">Passwort *</label>
<input type="password" id="password" name="password" required placeholder="Mindestens 8 Zeichen">
<div class="password-strength" id="passwordStrength">
<div class="strength-bar"></div>
<span class="strength-text">Passwortstärke</span>
</div>
</div>
<div class="form-group">
<label for="confirmPassword">Passwort bestätigen *</label>
<input type="password" id="confirmPassword" name="confirmPassword" required placeholder="Passwort wiederholen">
</div>
<div class="form-options">
<label class="checkbox-label">
<input type="checkbox" id="terms" name="terms" required>
<span class="checkbox-custom"></span>
Ich stimme den <a href="#" class="terms-link">Nutzungsbedingungen</a> und <a href="#" class="terms-link">Datenschutzrichtlinien</a> zu *
</label>
</div>
<div class="form-options">
<label class="checkbox-label">
<input type="checkbox" id="newsletter" name="newsletter">
<span class="checkbox-custom"></span>
Ich möchte den Newsletter erhalten
</label>
</div>
<button type="submit" class="login-btn-submit" id="registerSubmit">
<span class="btn-text">Konto erstellen</span>
<span class="btn-loading" style="display: none;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12a9 9 0 1 1-6.219-8.56"></path>
<polyline points="22 6 12 16 2 6"></polyline>
</svg>
</span>
</button>
</form>
<div class="login-divider">
<span>oder</span>
</div>
<div class="social-login">
<button type="button" class="social-btn google-btn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c-.82 2.33-2.85 4.08-5.92 4.08-.57 0-1.11-.08-1.63-.24V14.6c.52.16 1.06.24 1.63.24 3.07 0 5.52-2.51 5.52-5.52 0-.1 0-.2-.01-.3-.57-2.53-2.11-4.52-4.52-4.52zM12 23c-1.61 0-3.09-.59-4.23-1.57l.01-.02V18.6l-.01.02c1.14-.98 2.62-1.57 4.23-1.57 3.07 0 5.52 2.51 5.52 5.52 0 .1 0 .2-.01.3z"/>
<path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
<path d="M12 5.38c1.62 0 3.06.56 4.21 1.46l-2.85 2.22c-.81-.62-1.79-1.11-2.85-1.36-.52-.16-1.06-.24-1.63-.24-3.07 0-5.52 2.51-5.52 5.52 0 .1 0 .2.01.3.57 2.53 2.11 4.52 4.52 4.52z"/>
</svg>
Mit Google registrieren
</button>
</div>
<div class="login-footer">
<p>Bereits ein Konto? <a href="login.html">Jetzt anmelden</a></p>
</div>
<div class="success-message" id="successMessage">
<div class="success-icon"></div>
<h3>Registrierung erfolgreich!</h3>
<p>Ihr Konto wurde erstellt. Sie werden weitergeleitet...</p>
</div>
<div class="error-message" id="errorMessage">
<div class="error-icon"></div>
<h3>Registrierung fehlgeschlagen</h3>
<p id="errorText">Bitte überprüfen Sie Ihre Eingaben.</p>
</div>
</div>
</main>
<script src="../scripts/script.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
<script src="../scripts/register.js"></script>
</body>
</html>

View File

@@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profice - Website Entwicklung</title>
<link rel="stylesheet" href="../style/design.css">
<link rel="stylesheet" href="../style/service.css">
<link rel="stylesheet" href="../style/cursor.css">
</head>
<body>
<!-- Top Banner -->
<header class="top-banner dark-theme">
<div class="top-banner-left">
<div class="banner-left">
<button class="menu-toggle" id="menuToggle" aria-label="Menu">
<span></span>
<span></span>
<span></span>
</button>
<a href="../index.html" class="logo-link">
<img src="../images/logo/logo-01-complete.png" alt="Profice Logo" class="logo">
</a>
</div>
</div>
<div class="top-banner-center">
<nav class="main-nav">
<a href="../index.html#hero-section" class="nav-link">Home</a>
<a href="../index.html#enterprise" class="nav-link">Enterprise</a>
<a href="../index.html#pricing" class="nav-link">Pricing</a>
<a href="../index.html#services" class="nav-link">Lösungen</a>
</nav>
</div>
<div class="top-banner-right">
<button id="cursorToggle" aria-label="Toggle Cursor" title="Toggle Custom Cursor">
<img src="../images/additional/cursor.png" alt="Default Cursor" class="cursor-icon">
</button>
<button id="loginBtn" class="login-btn" aria-label="Log in" title="Log in">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
<polyline points="10 17 15 12 10 7"></polyline>
<line x1="15" y1="12" x2="3" y2="12"></line>
</svg>
Log in
</button>
</div>
</header>
<!-- Slide Menu -->
<nav class="slide-menu" id="slideMenu">
<a href="../index.html">Startseite</a>
<a href="offers.html" class="active">Kontakt & Anfrage</a>
<a href="leads.html">Leads Dashboard</a>
</nav>
<!-- Overlay -->
<div class="overlay" id="overlay"></div>
<!-- Main Content -->
<main class="main-content">
<div class="service-container">
<!-- Service Header -->
<div class="service-header">
<div class="service-icon">🌐</div>
<h1 class="service-title">Website Entwicklung</h1>
<p class="service-subtitle">Moderne, responsive Webseiten, die konvertieren und Ihre Marke perfekt repräsentieren</p>
</div>
<!-- Service Description -->
<section class="service-section">
<h2 class="section-title">Unsere Webentwicklungsdienstleistungen</h2>
<p class="section-text">
Wir entwickeln maßgeschneiderte Websites, die nicht nur gut aussehen, sondern auch Ergebnisse liefern.
Von der Konzeption über das Design bis zur Implementierung und Wartung begleiten wir Sie durch den gesamten Prozess.
</p>
</section>
<!-- Service Features -->
<section class="service-section">
<h2 class="section-title">Was wir bieten</h2>
<div class="features-grid">
<div class="feature-item">
<div class="feature-icon">🎨</div>
<h3>Responsive Design</h3>
<p>Perfekte Darstellung auf allen Geräten - von Desktop bis Mobile</p>
</div>
<div class="feature-item">
<div class="feature-icon"></div>
<h3>Performance-Optimierung</h3>
<p>Schnelle Ladezeiten und beste Nutzererfahrung</p>
</div>
<div class="feature-item">
<div class="feature-icon">🔒</div>
<h3>SEO-Freundlich</h3>
<p>Technische Grundlagen für gute Suchmaschinenplatzierungen</p>
</div>
<div class="feature-item">
<div class="feature-icon">🔧</div>
<h3>CMS-Integration</h3>
<p>Einfache Content-Verwaltung für Ihre Mitarbeiter</p>
</div>
<div class="feature-item">
<div class="feature-icon">🛡️</div>
<h3>Sicherheit</h3>
<p>Schutz vor Bedrohungen und sichere Datenverarbeitung</p>
</div>
<div class="feature-item">
<div class="feature-icon">📊</div>
<h3>Analytics & Tracking</h3>
<p>Detaillierte Auswertung Ihrer Website-Performance</p>
</div>
</div>
</section>
<!-- Process -->
<section class="service-section">
<h2 class="section-title">Unser Prozess</h2>
<div class="process-timeline">
<div class="process-item">
<div class="process-number">1</div>
<div class="process-content">
<h3>Analyse & Konzeption</h3>
<p>Wir verstehen Ihre Ziele und entwickeln eine passende Strategie</p>
</div>
</div>
<div class="process-item">
<div class="process-number">2</div>
<div class="process-content">
<h3>Design & Prototyping</h3>
<p>Visuelle Konzepte und interaktive Prototypen</p>
</div>
</div>
<div class="process-item">
<div class="process-number">3</div>
<div class="process-content">
<h3>Entwicklung</h3>
<p>Saubere, performante Code-Implementierung</p>
</div>
</div>
<div class="process-item">
<div class="process-number">4</div>
<div class="process-content">
<h3>Testing & Launch</h3>
<p>Gewissenhafte Tests und erfolgreicher Start</p>
</div>
</div>
<div class="process-item">
<div class="process-number">5</div>
<div class="process-content">
<h3>Support & Wartung</h3>
<p>Laufende Optimierung und technische Unterstützung</p>
</div>
</div>
</div>
</section>
<!-- Technologies -->
<section class="service-section">
<h2 class="section-title">Technologien</h2>
<div class="tech-grid">
<div class="tech-item">HTML5</div>
<div class="tech-item">CSS3</div>
<div class="tech-item">JavaScript</div>
<div class="tech-item">React</div>
<div class="tech-item">Vue.js</div>
<div class="item">Angular</div>
<div class="tech-item">Node.js</div>
<div class="tech-item">PHP</div>
<div class="tech-item">WordPress</div>
<div class="tech-item">Shopify</div>
<div class="tech-item">WooCommerce</div>
</div>
</section>
<!-- CTA Section -->
<section class="service-section">
<h2 class="section-title">Bereit für Ihre neue Website?</h2>
<p class="section-text">Lassen Sie uns Ihr Projekt an und wir erstellen ein maßgeschneidertes Angebot.</p>
<div class="cta-buttons">
<a href="offers.html?service=website" class="cta-btn primary">Projekt starten</a>
<a href="offers.html" class="cta-btn secondary">Mehr erfahren</a>
</div>
</section>
</div>
</main>
<script src="../scripts/script.js"></script>
<script src="../scripts/cursor.js"></script>
<script src="../scripts/scroll-header.js"></script>
</body>
</html>

View File

@@ -0,0 +1,307 @@
/* Cookie Consent System - Matches Profice Design System */
/* Cookie Banner */
.cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--primary-light);
border-top: 1px solid var(--primary-mid);
padding: 20px 40px;
z-index: 10000;
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
transform: translateY(100%);
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.cookie-banner.show {
transform: translateY(0);
}
.cookie-banner-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
gap: 30px;
}
.cookie-text {
flex: 1;
color: var(--primary-dark);
font-size: 14px;
line-height: 1.5;
}
.cookie-text h3 {
margin: 0 0 8px 0;
font-size: 16px;
font-weight: 600;
color: var(--primary-dark);
}
.cookie-text p {
margin: 0;
opacity: 0.8;
}
.cookie-text a {
color: var(--accent-teal);
text-decoration: none;
font-weight: 500;
}
.cookie-text a:hover {
text-decoration: underline;
}
.cookie-buttons {
display: flex;
gap: 12px;
align-items: center;
}
.cookie-btn {
padding: 10px 20px;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;
}
.cookie-btn-primary {
background: var(--primary-dark);
color: var(--primary-light);
}
.cookie-btn-primary:hover {
background: var(--primary-mid);
transform: translateY(-1px);
}
.cookie-btn-secondary {
background: transparent;
color: var(--primary-dark);
border: 2px solid var(--primary-mid);
}
.cookie-btn-secondary:hover {
background: var(--primary-mid);
color: var(--primary-light);
}
.cookie-btn-settings {
background: transparent;
color: var(--accent-teal);
border: none;
text-decoration: underline;
font-size: 14px;
padding: 5px 0;
}
.cookie-btn-settings:hover {
color: var(--primary-dark);
}
/* Cookie Settings Modal */
.cookie-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 10001;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.cookie-modal.show {
opacity: 1;
visibility: visible;
}
.cookie-modal-content {
background: var(--primary-light);
border-radius: 12px;
padding: 30px;
max-width: 600px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
transform: scale(0.9);
transition: transform 0.3s ease;
}
.cookie-modal.show .cookie-modal-content {
transform: scale(1);
}
.cookie-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid var(--primary-mid);
}
.cookie-modal-title {
font-size: 20px;
font-weight: 600;
color: var(--primary-dark);
margin: 0;
}
.cookie-modal-close {
background: none;
border: none;
font-size: 24px;
color: var(--primary-mid);
cursor: pointer;
padding: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.3s ease;
}
.cookie-modal-close:hover {
background: var(--primary-mid);
color: var(--primary-light);
}
.cookie-option {
margin-bottom: 20px;
padding: 15px;
border: 1px solid var(--primary-mid);
border-radius: 8px;
background: rgba(255, 255, 255, 0.5);
}
.cookie-option-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.cookie-option-title {
font-weight: 600;
color: var(--primary-dark);
margin: 0;
}
.cookie-option-description {
color: var(--primary-mid);
font-size: 14px;
line-height: 1.4;
margin: 0;
}
.cookie-toggle {
position: relative;
width: 50px;
height: 26px;
background: var(--primary-mid);
border-radius: 13px;
cursor: pointer;
transition: background 0.3s ease;
}
.cookie-toggle.active {
background: var(--accent-teal);
}
.cookie-toggle-slider {
position: absolute;
top: 3px;
left: 3px;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
transition: transform 0.3s ease;
}
.cookie-toggle.active .cookie-toggle-slider {
transform: translateX(24px);
}
.cookie-toggle.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.cookie-modal-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 25px;
padding-top: 20px;
border-top: 1px solid var(--primary-mid);
}
/* Responsive Design */
@media (max-width: 768px) {
.cookie-banner {
padding: 15px 20px;
}
.cookie-banner-content {
flex-direction: column;
gap: 20px;
text-align: center;
}
.cookie-buttons {
flex-direction: column;
width: 100%;
gap: 10px;
}
.cookie-btn {
width: 100%;
text-align: center;
}
.cookie-modal-content {
padding: 20px;
margin: 20px;
}
.cookie-modal-footer {
flex-direction: column;
}
.cookie-btn {
width: 100%;
}
}
@media (max-width: 480px) {
.cookie-text h3 {
font-size: 14px;
}
.cookie-text p {
font-size: 13px;
}
.cookie-modal-content {
padding: 15px;
}
}

View File

@@ -0,0 +1,98 @@
/* cursor.css */
/* Default: System cursor (not custom) */
body,
html,
a,
button,
input,
textarea,
select,
.menu-toggle,
label {
cursor: auto !important;
}
/* Custom cursor only when enabled */
body:not(.system-cursor),
body:not(.system-cursor) a,
body:not(.system-cursor) button,
body:not(.system-cursor) input,
body:not(.system-cursor) textarea,
body:not(.system-cursor) select,
body:not(.system-cursor) .menu-toggle,
body:not(.system-cursor) label {
cursor: none !important;
}
#venom-cursor {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 9999;
mix-blend-mode: normal;
display: none; /* Hidden by default */
}
/* Show custom cursor only when not system cursor */
body:not(.system-cursor) #venom-cursor {
display: block;
}
@media (pointer: coarse) {
body, html, a, button, input, textarea, select {
cursor: auto !important;
}
#venom-cursor {
display: none;
}
}
body.system-cursor,
body.system-cursor * {
cursor: auto !important;
}
body.system-cursor #venom-cursor {
display: none !important;
opacity: 0;
pointer-events: none;
}
#cursorToggle {
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 2px solid var(--primary-dark);
color: var(--primary-dark);
width: 45px;
height: 45px;
border-radius: 12px;
cursor: auto; /* Use system cursor for toggle button */
transition: all 0.3s ease;
font-size: 20px;
}
#cursorToggle:hover {
background: var(--primary-dark);
color: var(--primary-light);
}
body:not(.system-cursor) #cursorToggle {
cursor: none; /* Use custom cursor when custom is enabled */
}
.top-banner.dark-theme #cursorToggle {
border-color: var(--primary-light);
color: var(--primary-light);
}
.top-banner.dark-theme #cursorToggle:hover {
background: var(--primary-light);
color: var(--primary-dark);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,151 @@
/* Details Page Styles */
.service-header {
text-align: center;
margin-bottom: 40px;
padding-bottom: 30px;
border-bottom: 2px solid var(--accent-teal);
}
.service-icon-large {
font-size: 64px;
margin-bottom: 20px;
display: block;
}
.service-title-large {
font-size: 36px;
color: var(--primary-dark);
margin-bottom: 15px;
font-weight: 600;
}
.service-description-large {
font-size: 18px;
color: var(--primary-mid);
line-height: 1.6;
max-width: 600px;
margin: 0 auto;
}
.service-content {
margin-top: 40px;
}
.service-section {
margin-bottom: 40px;
padding: 30px;
background: var(--primary-light);
border-radius: 16px;
box-shadow: 0 4px 20px rgba(79, 71, 71, 0.1);
}
.section-title {
font-size: 24px;
color: var(--primary-dark);
margin-bottom: 20px;
font-weight: 600;
}
.section-text {
font-size: 16px;
line-height: 1.6;
color: var(--primary-mid);
margin-bottom: 20px;
}
.feature-list,
.benefit-list {
list-style: none;
padding: 0;
margin: 0;
}
.feature-list li,
.benefit-list li {
padding: 12px 0;
border-bottom: 1px solid rgba(119, 119, 100, 0.1);
color: var(--primary-dark);
font-size: 16px;
position: relative;
padding-left: 30px;
}
.feature-list li:before,
.benefit-list li:before {
content: "✓";
position: absolute;
left: 0;
color: var(--accent-teal);
font-weight: bold;
font-size: 18px;
}
.feature-list li:last-child,
.benefit-list li:last-child {
border-bottom: none;
}
.cta-buttons {
display: flex;
gap: 20px;
justify-content: center;
margin-top: 30px;
flex-wrap: wrap;
}
.back-button-container {
text-align: center;
margin-top: 40px;
padding-top: 30px;
border-top: 1px solid rgba(119, 119, 100, 0.2);
}
.error-message {
text-align: center;
padding: 40px;
}
.error-message h2 {
color: var(--primary-dark);
margin-bottom: 15px;
}
.error-message p {
color: var(--primary-mid);
margin-bottom: 25px;
}
/* Responsive Design */
@media (max-width: 768px) {
.service-icon-large {
font-size: 48px;
}
.service-title-large {
font-size: 28px;
}
.service-description-large {
font-size: 16px;
}
.service-section {
padding: 20px;
margin-bottom: 25px;
}
.section-title {
font-size: 20px;
}
.cta-buttons {
flex-direction: column;
align-items: center;
}
.cta-btn {
width: 100%;
max-width: 300px;
}
}

View File

@@ -0,0 +1,408 @@
/* Lead Details Page Styles */
.lead-details-container {
max-width: 900px;
margin: 0 auto;
padding: 120px 20px 20px 20px;
}
.lead-header {
text-align: center;
margin-bottom: 50px;
padding-bottom: 30px;
border-bottom: 3px solid var(--accent-teal);
}
.lead-icon {
font-size: 72px;
margin-bottom: 20px;
display: block;
}
.lead-title {
font-size: 42px;
color: var(--primary-dark);
margin-bottom: 15px;
font-weight: 600;
}
.lead-subtitle {
font-size: 20px;
color: var(--primary-mid);
line-height: 1.6;
max-width: 600px;
margin: 0 auto;
}
.lead-details-card {
background: white;
border-radius: 20px;
box-shadow: 0 8px 30px rgba(79, 71, 71, 0.1);
overflow: hidden;
}
.detail-section {
padding: 40px;
border-bottom: 1px solid rgba(119, 119, 100, 0.1);
}
.detail-section:last-child {
border-bottom: none;
}
.section-title {
font-size: 24px;
color: var(--primary-dark);
margin-bottom: 20px;
font-weight: 600;
}
/* Status Styles */
.status-container {
display: flex;
align-items: center;
gap: 20px;
flex-wrap: wrap;
}
.status-badge {
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: 500;
display: inline-block;
}
.status-new {
background: #e3f2fd;
color: #1976d2;
}
.status-in-progress {
background: #fff3e0;
color: #f57c00;
}
.status-completed {
background: #e8f5e8;
color: #2e7d32;
}
.status-cancelled {
background: #ffebee;
color: #c62828;
}
.status-info {
color: var(--primary-mid);
font-size: 14px;
}
/* Info Grid */
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 25px;
}
.info-item {
background: var(--primary-light);
padding: 20px;
border-radius: 12px;
border-left: 4px solid var(--accent-teal);
}
.info-label {
font-size: 14px;
color: var(--primary-mid);
margin-bottom: 8px;
font-weight: 500;
}
.info-value {
font-size: 18px;
color: var(--primary-dark);
font-weight: 500;
}
/* Service Info */
.service-info {
display: flex;
align-items: center;
gap: 20px;
background: var(--primary-light);
padding: 30px;
border-radius: 16px;
}
.service-icon {
font-size: 48px;
flex-shrink: 0;
}
.service-details {
flex: 1;
}
.service-title {
font-size: 24px;
color: var(--accent-teal);
margin-bottom: 10px;
}
.service-description {
color: var(--primary-mid);
line-height: 1.5;
}
/* Description Box */
.description-box {
background: var(--primary-light);
padding: 30px;
border-radius: 16px;
border-left: 4px solid var(--accent-teal);
}
.description-text {
color: var(--primary-dark);
line-height: 1.6;
font-size: 16px;
white-space: pre-wrap;
}
/* Timeline */
.timeline {
position: relative;
padding-left: 30px;
}
.timeline::before {
content: '';
position: absolute;
left: 15px;
top: 0;
bottom: 0;
width: 2px;
background: rgba(119, 119, 100, 0.2);
}
.timeline-item {
position: relative;
margin-bottom: 30px;
padding-left: 30px;
}
.timeline-item:last-child {
margin-bottom: 0;
}
.timeline-dot {
position: absolute;
left: -22px;
top: 5px;
width: 12px;
height: 12px;
border-radius: 50%;
background: rgba(119, 119, 100, 0.3);
border: 2px solid white;
}
.timeline-item.active .timeline-dot {
background: var(--accent-teal);
box-shadow: 0 0 0 4px rgba(38, 166, 154, 0.2);
}
.timeline-content h4 {
color: var(--primary-dark);
margin-bottom: 5px;
font-size: 18px;
}
.timeline-content p {
color: var(--primary-mid);
font-size: 14px;
}
/* Action Buttons */
.action-buttons {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.action-btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.action-btn.primary {
background: var(--accent-teal);
color: white;
}
.action-btn.primary:hover {
background: #1e8e82;
transform: translateY(-2px);
}
.action-btn.secondary {
background: var(--primary-light);
color: var(--primary-dark);
border: 1px solid rgba(119, 119, 100, 0.2);
}
.action-btn.secondary:hover {
background: var(--primary-mid);
color: white;
transform: translateY(-2px);
}
/* Navigation Buttons */
.navigation-buttons {
display: flex;
gap: 20px;
justify-content: center;
margin-top: 40px;
flex-wrap: wrap;
}
.cta-btn {
padding: 16px 32px;
border-radius: 30px;
font-size: 18px;
font-weight: 600;
text-decoration: none;
transition: all 0.3s ease;
display: inline-block;
}
.cta-btn.primary {
background: var(--accent-teal);
color: white;
border: 2px solid var(--accent-teal);
}
.cta-btn.primary:hover {
background: white;
color: var(--accent-teal);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(38, 166, 154, 0.3);
}
.cta-btn.secondary {
background: transparent;
color: var(--primary-dark);
border: 2px solid var(--primary-dark);
}
.cta-btn.secondary:hover {
background: var(--primary-dark);
color: white;
transform: translateY(-2px);
}
/* Error Message */
.error-message {
text-align: center;
padding: 60px 20px;
background: white;
border-radius: 20px;
box-shadow: 0 8px 30px rgba(79, 71, 71, 0.1);
}
.error-message h2 {
color: var(--primary-dark);
margin-bottom: 15px;
}
.error-message p {
color: var(--primary-mid);
margin-bottom: 25px;
}
/* Responsive Design */
@media (max-width: 768px) {
.lead-details-container {
padding: 100px 15px 20px 15px;
}
.lead-icon {
font-size: 56px;
}
.lead-title {
font-size: 32px;
}
.lead-subtitle {
font-size: 18px;
}
.detail-section {
padding: 30px 20px;
}
.section-title {
font-size: 20px;
}
.info-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.service-info {
flex-direction: column;
text-align: center;
}
.service-icon {
font-size: 64px;
}
.status-container {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.action-buttons,
.navigation-buttons {
flex-direction: column;
align-items: center;
}
.action-btn,
.cta-btn {
width: 100%;
max-width: 300px;
}
}
/* Print Styles */
@media print {
.top-banner,
.slide-menu,
.overlay,
.navigation-buttons,
.action-buttons {
display: none !important;
}
.lead-details-container {
padding: 20px;
}
.lead-details-card {
box-shadow: none;
border: 1px solid #ddd;
}
}

View File

@@ -0,0 +1,219 @@
/* Leads Dashboard Styles */
.leads-content {
max-width: 900px;
}
.dashboard-container {
background: white;
padding: 40px;
border-radius: 24px;
box-shadow: 0 15px 50px rgba(79, 71, 71, 0.1);
margin-bottom: 30px;
}
.dashboard-title {
color: var(--primary-dark);
font-size: 28px;
margin-bottom: 8px;
font-weight: 600;
}
.dashboard-subtitle {
color: var(--primary-mid);
font-size: 15px;
margin-bottom: 30px;
}
/* Leads Table */
.leads-table-wrapper {
overflow-x: auto;
border-radius: 16px;
border: 1px solid rgba(119, 119, 100, 0.15);
}
.leads-table {
width: 100%;
border-collapse: collapse;
min-width: 500px;
}
.leads-table thead {
background: var(--primary-light);
}
.leads-table th {
padding: 16px 20px;
text-align: left;
font-weight: 600;
color: var(--primary-dark);
font-size: 14px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.leads-table td {
padding: 18px 20px;
border-top: 1px solid rgba(119, 119, 100, 0.1);
color: var(--primary-dark);
font-size: 15px;
}
.leads-table tbody tr {
transition: background 0.2s ease;
}
.leads-table tbody tr:hover {
background: rgba(235, 235, 222, 0.5);
}
/* Status Badges */
.status-badge {
display: inline-block;
padding: 6px 14px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.status-badge.completed {
background: rgba(102, 187, 106, 0.15);
color: var(--accent-green);
}
.status-badge.in-progress {
background: rgba(245, 124, 0, 0.15);
color: var(--accent-orange);
}
.status-badge.open {
background: rgba(119, 119, 100, 0.15);
color: var(--primary-mid);
}
/* Action Button */
.action-btn {
padding: 8px 16px;
background: transparent;
border: 2px solid var(--accent-teal);
color: var(--accent-teal);
border-radius: 20px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;
}
.action-btn:hover {
background: var(--accent-teal);
color: white;
}
/* Offers Section */
.offers-section {
margin-top: 30px;
}
.offers-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 24px;
}
.offer-card {
background: var(--primary-light);
border-radius: 20px;
padding: 30px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
}
.offer-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(79, 71, 71, 0.15);
background: white;
}
.offer-icon {
font-size: 40px;
margin-bottom: 16px;
}
.offer-title {
color: var(--primary-dark);
font-size: 20px;
font-weight: 600;
margin-bottom: 12px;
}
.offer-description {
color: var(--primary-mid);
font-size: 14px;
line-height: 1.6;
margin-bottom: 20px;
}
.offer-btn {
display: inline-block;
padding: 10px 24px;
background: var(--accent-teal);
color: white;
text-decoration: none;
border-radius: 25px;
font-size: 14px;
font-weight: 600;
transition: all 0.3s ease;
}
.offer-btn:hover {
background: #1e8e82;
box-shadow: 0 5px 20px rgba(38, 166, 154, 0.3);
}
/* Active menu link */
.slide-menu a.active {
background: var(--primary-light);
border-left-color: var(--accent-teal);
color: var(--accent-teal);
}
/* Empty state */
.empty-state {
text-align: center;
padding: 40px;
color: var(--primary-mid);
}
.empty-state p {
font-size: 16px;
}
/* Responsive */
@media (max-width: 600px) {
.dashboard-container {
padding: 25px;
}
.dashboard-title {
font-size: 22px;
}
.leads-table th,
.leads-table td {
padding: 12px 14px;
font-size: 13px;
}
.offer-card {
padding: 20px;
}
.offers-grid {
grid-template-columns: 1fr;
}
}

View File

@@ -0,0 +1,547 @@
/* Login Page Styles */
.login-content {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 120px 20px 20px 20px;
background: linear-gradient(135deg, var(--primary-light) 0%, white 100%);
}
.login-container {
width: 100%;
max-width: 450px;
background: white;
border-radius: 24px;
box-shadow: 0 20px 60px rgba(79, 71, 71, 0.15);
padding: 50px 40px;
position: relative;
overflow: hidden;
}
.login-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, var(--accent-teal), var(--accent-green));
}
.login-header {
text-align: center;
margin-bottom: 40px;
}
.login-icon {
font-size: 64px;
margin-bottom: 20px;
display: block;
}
.login-title {
font-size: 32px;
color: var(--primary-dark);
margin-bottom: 10px;
font-weight: 600;
}
.login-subtitle {
color: var(--primary-mid);
font-size: 16px;
line-height: 1.5;
}
.login-form {
margin-bottom: 30px;
}
.login-form .form-group {
position: relative;
margin-bottom: 25px;
}
.login-form .form-group label {
display: block;
margin-bottom: 8px;
color: var(--primary-dark);
font-weight: 500;
font-size: 14px;
}
.login-form .form-group input {
width: 100%;
padding: 14px 45px 14px 18px;
border: 2px solid rgba(119, 119, 100, 0.2);
border-radius: 12px;
font-size: 16px;
transition: all 0.3s ease;
background: var(--primary-light);
color: var(--primary-dark);
outline: none;
}
.login-form .form-group input:focus {
border-color: var(--accent-teal);
background: white;
box-shadow: 0 0 0 4px rgba(38, 166, 154, 0.15);
}
.input-icon {
position: absolute;
right: 18px;
top: 50%;
transform: translateY(-50%);
font-size: 20px;
color: var(--primary-mid);
pointer-events: none;
}
.password-toggle {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--primary-mid);
cursor: pointer;
padding: 4px;
border-radius: 4px;
transition: all 0.3s ease;
}
.password-toggle:hover {
background: rgba(119, 119, 100, 0.1);
color: var(--primary-dark);
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
font-size: 14px;
}
.checkbox-label {
display: flex;
align-items: center;
cursor: pointer;
color: var(--primary-dark);
}
.checkbox-label input[type="checkbox"] {
display: none;
}
.checkbox-custom {
width: 18px;
height: 18px;
border: 2px solid rgba(119, 119, 100, 0.3);
border-radius: 4px;
margin-right: 8px;
position: relative;
transition: all 0.3s ease;
}
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
background: var(--accent-teal);
border-color: var(--accent-teal);
}
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 12px;
font-weight: bold;
}
.forgot-password {
color: var(--accent-teal);
text-decoration: none;
font-weight: 500;
transition: color 0.3s ease;
}
.forgot-password:hover {
color: var(--primary-dark);
}
.login-btn-submit {
width: 100%;
padding: 16px;
background: var(--accent-teal);
color: white;
border: none;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.login-btn-submit:hover:not(:disabled) {
background: #1e8e82;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(38, 166, 154, 0.3);
}
.login-btn-submit:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.btn-loading svg {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.login-divider {
text-align: center;
margin: 30px 0;
position: relative;
}
.login-divider::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
background: rgba(119, 119, 100, 0.2);
}
.login-divider span {
background: white;
padding: 0 20px;
color: var(--primary-mid);
font-size: 14px;
position: relative;
}
.social-login {
margin-bottom: 30px;
}
.social-btn {
width: 100%;
padding: 14px;
border: 2px solid rgba(119, 119, 100, 0.2);
border-radius: 12px;
background: white;
color: var(--primary-dark);
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
.social-btn:hover {
border-color: var(--primary-mid);
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(79, 71, 71, 0.1);
}
.google-btn:hover {
border-color: #4285f4;
background: #f8f9fa;
}
.login-footer {
text-align: center;
font-size: 14px;
color: var(--primary-mid);
}
.login-footer a {
color: var(--accent-teal);
text-decoration: none;
font-weight: 500;
transition: color 0.3s ease;
}
.login-footer a:hover {
color: var(--primary-dark);
}
/* Messages */
.success-message,
.error-message {
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 20px;
text-align: center;
transform: translateY(-100%);
transition: transform 0.3s ease;
z-index: 10;
}
.success-message.show,
.error-message.show {
transform: translateY(0);
}
.success-message {
background: linear-gradient(135deg, #e8f5e8, #d4edda);
color: #2e7d32;
}
.error-message {
background: linear-gradient(135deg, #ffebee, #f8d7da);
color: #c62828;
}
.success-icon,
.error-icon {
font-size: 48px;
margin-bottom: 10px;
display: block;
}
.success-message h3,
.error-message h3 {
margin-bottom: 5px;
font-size: 18px;
}
.success-message p,
.error-message p {
margin: 0;
font-size: 14px;
}
/* Login Button Styles */
.login-btn {
background: transparent;
border: 2px solid var(--primary-dark);
color: var(--primary-dark);
padding: 8px 16px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
text-decoration: none;
}
.login-btn:hover {
background: var(--primary-dark);
color: white;
transform: translateY(-2px);
}
.register-btn {
background: transparent;
border: 2px solid var(--primary-dark);
color: var(--primary-dark);
padding: 8px 16px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.register-btn:hover {
background: var(--primary-dark);
color: white;
transform: translateY(-2px);
}
/* Register Button (White version) */
.login-btn.register {
background: transparent;
border: 2px solid white;
color: white;
padding: 8px 16px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
text-decoration: none;
}
.login-btn.register:hover {
background: white;
color: var(--primary-dark);
transform: translateY(-2px);
}
/* Ensure login button is white on register page */
body .login-btn {
background: transparent !important;
border: 2px solid white !important;
color: white !important;
}
body .login-btn:hover {
background: white !important;
color: var(--primary-dark) !important;
}
/* Form Row for Two Columns */
.form-row {
display: flex;
gap: 15px;
margin-bottom: 24px;
}
.form-row .form-group {
flex: 1;
margin-bottom: 0;
}
/* Password Strength Indicator */
.password-strength {
margin-top: 8px;
display: flex;
align-items: center;
gap: 10px;
}
.strength-bar {
flex: 1;
height: 4px;
background: #e0e0e0;
border-radius: 2px;
overflow: hidden;
}
.strength-bar::before {
content: '';
display: block;
height: 100%;
width: 0%;
transition: width 0.3s ease, background-color 0.3s ease;
background: #f44336;
}
.strength-text {
font-size: 12px;
color: var(--primary-mid);
}
/* Password Strength Levels */
.strength-weak .strength-bar::before {
width: 33%;
background: #f44336;
}
.strength-medium .strength-bar::before {
width: 66%;
background: #ff9800;
}
.strength-strong .strength-bar::before {
width: 100%;
background: #4caf50;
}
.strength-weak .strength-text {
color: #f44336;
}
.strength-medium .strength-text {
color: #ff9800;
}
.strength-strong .strength-text {
color: #4caf50;
}
/* Terms Links */
.terms-link {
color: var(--accent-teal);
text-decoration: none;
font-weight: 500;
}
.terms-link:hover {
text-decoration: underline;
}
/* Responsive Design */
@media (max-width: 768px) {
.login-content {
padding: 100px 15px 20px 15px;
}
.login-container {
padding: 40px 30px;
margin: 0 10px;
}
.login-icon {
font-size: 56px;
}
.login-title {
font-size: 28px;
}
.login-subtitle {
font-size: 14px;
}
.form-options {
flex-direction: column;
align-items: flex-start;
gap: 15px;
}
.social-btn {
font-size: 14px;
}
}
@media (max-width: 480px) {
.login-container {
padding: 30px 20px;
}
.login-title {
font-size: 24px;
}
.login-form .form-group input {
font-size: 16px;
padding: 12px 40px 12px 15px;
}
.input-icon,
.password-toggle {
right: 15px;
}
}

View File

@@ -0,0 +1,339 @@
/* Service Page Styles */
.service-container {
max-width: 900px;
margin: 0 auto;
padding: 120px 20px 20px 20px;
}
.service-header {
text-align: center;
margin-bottom: 60px;
padding-bottom: 40px;
border-bottom: 3px solid var(--accent-teal);
}
.service-icon {
font-size: 72px;
margin-bottom: 20px;
display: block;
}
.service-title {
font-size: 42px;
color: var(--primary-dark);
margin-bottom: 15px;
font-weight: 600;
}
.service-subtitle {
font-size: 20px;
color: var(--primary-mid);
line-height: 1.6;
max-width: 600px;
margin: 0 auto;
}
.service-section {
margin-bottom: 50px;
padding: 40px;
background: white;
border-radius: 20px;
box-shadow: 0 8px 30px rgba(79, 71, 71, 0.1);
}
.section-title {
font-size: 28px;
color: var(--primary-dark);
margin-bottom: 20px;
font-weight: 600;
}
.section-text {
font-size: 18px;
line-height: 1.6;
color: var(--primary-mid);
margin-bottom: 30px;
}
/* Features Grid */
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
margin-top: 30px;
}
.feature-item {
background: var(--primary-light);
padding: 30px;
border-radius: 16px;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.feature-item:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(79, 71, 71, 0.15);
}
.feature-icon {
font-size: 48px;
margin-bottom: 15px;
display: block;
}
.feature-item h3 {
color: var(--accent-teal);
margin-bottom: 10px;
font-size: 20px;
}
.feature-item p {
color: var(--primary-mid);
line-height: 1.5;
}
/* Process Timeline */
.process-timeline {
max-width: 800px;
margin: 40px auto 0;
position: relative;
}
.process-item {
display: flex;
align-items: flex-start;
margin-bottom: 40px;
position: relative;
}
.process-number {
width: 50px;
height: 50px;
background: var(--accent-teal);
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
flex-shrink: 0;
margin-right: 20px;
}
.process-content {
flex: 1;
}
.process-content h3 {
color: var(--primary-dark);
margin-bottom: 8px;
font-size: 20px;
}
.process-content p {
color: var(--primary-mid);
line-height: 1.5;
}
/* Tech Grid */
.tech-grid {
display: flex;
flex-wrap: wrap;
gap: 15px;
justify-content: center;
margin: 30px 0;
}
.tech-item {
background: var(--primary-dark);
color: white;
padding: 12px 20px;
border-radius: 25px;
font-size: 14px;
font-weight: 500;
transition: transform 0.2s ease;
}
.tech-item:hover {
transform: translateY(-2px);
background: var(--accent-teal);
}
/* Benefits Grid */
.benefits-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 25px;
margin-top: 30px;
}
.benefit-item {
background: linear-gradient(135deg, var(--accent-teal), var(--accent-green));
color: white;
padding: 30px;
border-radius: 16px;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.benefit-item:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(38, 166, 154, 0.3);
}
.benefit-icon {
font-size: 48px;
margin-bottom: 15px;
display: block;
}
.benefit-item h3 {
margin-bottom: 10px;
font-size: 20px;
}
.benefit-item p {
line-height: 1.5;
}
/* Use Cases Grid */
.use-cases-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 25px;
margin-top: 30px;
}
.use-case-item {
background: var(--primary-light);
padding: 25px;
border-radius: 12px;
border-left: 4px solid var(--accent-teal);
transition: transform 0.3s ease;
}
.use-case-item:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(79, 71, 71, 0.1);
}
.use-case-item h3 {
color: var(--accent-teal);
margin-bottom: 10px;
font-size: 18px;
}
.use-case-item p {
color: var(--primary-mid);
line-height: 1.5;
}
/* CTA Buttons */
.cta-buttons {
display: flex;
gap: 20px;
justify-content: center;
margin-top: 40px;
flex-wrap: wrap;
}
.cta-btn {
padding: 16px 32px;
border-radius: 30px;
font-size: 18px;
font-weight: 600;
text-decoration: none;
transition: all 0.3s ease;
display: inline-block;
}
.cta-btn.primary {
background: var(--accent-teal);
color: white;
border: 2px solid var(--accent-teal);
}
.cta-btn.primary:hover {
background: white;
color: var(--accent-teal);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(38, 166, 154, 0.3);
}
.cta-btn.secondary {
background: transparent;
color: var(--primary-dark);
border: 2px solid var(--primary-dark);
}
.cta-btn.secondary:hover {
background: var(--primary-dark);
color: white;
transform: translateY(-2px);
}
/* Responsive Design */
@media (max-width: 768px) {
.service-container {
padding: 100px 15px 20px 15px;
}
.service-icon {
font-size: 56px;
}
.service-title {
font-size: 32px;
}
.service-subtitle {
font-size: 18px;
}
.service-section {
padding: 30px 20px;
margin-bottom: 30px;
}
.section-title {
font-size: 24px;
}
.section-text {
font-size: 16px;
}
.features-grid,
.benefits-grid,
.use-cases-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.process-item {
flex-direction: column;
text-align: center;
margin-bottom: 30px;
}
.process-number {
margin: 0 auto 15px;
}
.process-content {
text-align: center;
}
.cta-buttons {
flex-direction: column;
align-items: center;
}
.cta-btn {
width: 100%;
max-width: 300px;
}
}

BIN
Profice WebSite.zip Normal file

Binary file not shown.

View File

@@ -1,11 +0,0 @@
{
"permissions": {
"allow": [
"Bash(for f:*)",
"Bash(do grep:*)",
"Bash(echo \"ALREADY: $f\")",
"Bash(echo \"NEEDS: $f\")",
"Bash(done)"
]
}
}

View File

@@ -1,47 +1 @@
# Security - Disable directory listing
Options -Indexes
# Flowise chat proxy — rewrites /api/v1/prediction/* to PHP proxy (hides real Flowise URL)
RewriteEngine On
RewriteRule ^api/v1/prediction/(.*)$ scripts/add/flowise-proxy.php [L,QSA,NC]
# Enable compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/json
</IfModule>
# Set caching headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/ico "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType text/html "access plus 1 hour"
</IfModule>
# Security headers
<IfModule mod_headers.c>
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
# Force HTTPS (uncomment if you have SSL certificate)
# RewriteEngine On
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Options -Indexes

View File

@@ -1,89 +0,0 @@
# Profice Website - Server Deployment Guide
## 🚀 Ready for Production
Your website has been prepared for server hosting with the following optimizations:
### ✅ Completed Setup
#### 1. **Webhook Configuration Updated**
- ✅ Switched to production webhook URLs
- ✅ Debug mode disabled for security
- ✅ Using correct N8N webhook IDs
#### 2. **Server Security & Performance (.htaccess)**
- ✅ Directory listing disabled
- ✅ GZIP compression enabled
- ✅ Browser caching configured
- ✅ Security headers set
- ✅ PHP error display disabled
- ✅ HTTPS redirect ready (uncomment when SSL is active)
#### 3. **Character Encoding Fixed**
- ✅ All German special characters corrected
- ✅ UTF-8 encoding properly configured
#### 4. **File Structure Clean**
- ✅ Test files removed
- ✅ Production-ready configuration
## 📁 Files to Upload
Upload the entire `Profice WebSite` folder to your server:
```
Profice WebSite/
├── .htaccess # Server configuration
├── index.html # Homepage
├── sites/ # Subpages
│ ├── offers.html
│ ├── leads.html
│ ├── website.html
│ ├── ki-integration.html
│ └── automatisation.html
├── scripts/ # Backend functionality
│ └── add/
│ └── send.php # Webhook handler
├── style/ # CSS files
├── images/ # Image assets
└── components/ # Reusable components
```
## 🔧 Server Requirements
### Minimum Requirements:
- ✅ PHP 7.4+ (recommended 8.0+)
- ✅ Apache server with .htaccess support
- ✅ cURL extension enabled
- ✅ JSON extension enabled
### Optional (for better performance):
- SSL certificate (HTTPS)
- GZIP compression support
- Expires module for caching
## 🌐 After Upload
1. **Test the contact form** - Submit a test request
2. **Check webhook delivery** - Verify N8N receives requests
3. **Test all pages** - Ensure proper navigation
4. **Enable HTTPS** (if available) - Uncomment lines 50-53 in .htaccess
## 🔒 Security Notes
- All sensitive data (webhooks, tokens) are stored in `send.php`
- Debug mode is disabled in production
- Security headers are configured
- Directory listing is disabled
## 📞 Support
If you encounter issues:
1. Check server error logs
2. Verify PHP extensions (cURL, JSON)
3. Test webhook URLs manually
4. Ensure file permissions are correct (755 for folders, 644 for files)
---
**Your website is now ready for production deployment! 🎉**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Some files were not shown because too many files have changed in this diff Show More