Commit 01c6d240 authored by Hendrik Garske's avatar Hendrik Garske

Initial commit

parents
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
.env.local
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
image: node:20
stages:
- build
- test
variables:
NEXT_TELEMETRY_DISABLED: 1
cache:
paths:
- node_modules/
- .next/cache
before_script:
- npm ci
build:
stage: build
script:
- npm run build
artifacts:
paths:
- .next/
expire_in: 1 week
only:
- main
- merge_requests
test:
stage: test
script:
- npm run lint
only:
- main
- merge_requests
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat openssl
WORKDIR /app
# Copy package files
COPY package.json package-lock.json* ./
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Build Next.js
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy necessary files from builder
COPY --from=builder /app/public ./public
# Copy standalone build
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]
# WG Easy - WireGuard VPN Management
> WireGuard VPN Management Interface mit CoreX Design
⚠️ **Privates Repository** - Nur für interne Nutzung.
[![Next.js](https://img.shields.io/badge/Next.js-16.1.1-black)](https://nextjs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue)](https://www.typescriptlang.org/)
[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED)](https://www.docker.com/)
## 🎯 Überblick
WG Easy ist eine moderne Webanwendung zur Verwaltung von WireGuard VPN-Servern und -Clients.
## ✨ Features
- 🔐 **Client-Verwaltung**: Erstellen und verwalten Sie VPN-Clients
- 📊 **Dashboard**: Übersicht über aktive Verbindungen und Traffic
- 🎨 **Modernes Design**: CoreX Design System
- 🌓 **Dark Mode**: Automatischer Dark/Light Mode
- 📱 **Responsive**: Optimiert für alle Geräte
## 🛠 Tech Stack
- **Framework**: [Next.js 16.1.1](https://nextjs.org/) (App Router)
- **Sprache**: [TypeScript 5.0](https://www.typescriptlang.org/)
- **Styling**: [Tailwind CSS v4](https://tailwindcss.com/)
- **UI Components**:
- [Radix UI](https://www.radix-ui.com/)
- [Lucide Icons](https://lucide.dev/)
- **Theme**: [next-themes](https://github.com/pacocoursey/next-themes)
## 📦 Voraussetzungen
- **Linux** (Ubuntu/Debian empfohlen) oder Docker
- **Node.js**: Version 20 oder höher
- **npm** oder **yarn** oder **pnpm**
- **Git** (für Clone)
- **Docker & Docker Compose** (optional)
## 🚀 Installation
### 1. Repository klonen
```bash
git clone <repository-url>
cd wg-easy
```
### 2. Dependencies installieren
```bash
npm install
```
### 3. Development Server starten
```bash
npm run dev
```
Die Anwendung läuft jetzt auf [http://localhost:3000](http://localhost:3000)
## 🐳 Docker Setup
### Dockerfile
Das Projekt enthält ein optimiertes Multi-Stage Dockerfile für Production-Builds.
### Build & Run
```bash
# Build
docker build -t wg-easy .
# Run
docker run -p 3000:3000 wg-easy
```
## 🚢 Deployment
### GitLab CI/CD
Das Projekt verwendet GitLab CI/CD für automatische Builds und Tests.
**Pipeline Stages:**
1. **Build**: Kompiliert TypeScript und erstellt Production Build
2. **Test**: Führt ESLint aus
### CapRover
Das Projekt enthält eine `captain-definition` Datei für CapRover Deployment.
## 📝 Scripts
- `npm run dev` - Development Server starten
- `npm run build` - Production Build erstellen
- `npm run start` - Production Server starten
- `npm run lint` - ESLint ausführen
## 📝 Lizenz
**Proprietär**
Dieses Repository ist **privat** und nur für interne Nutzung bestimmt.
---
**Version**: 0.1.0
**Letzte Aktualisierung**: Dezember 2024
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-jetbrains);
--font-mono: var(--font-jetbrains);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
html {
scroll-behavior: smooth;
}
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<rect width="100" height="100" fill="#000000"/>
<text x="50" y="70" font-family="Arial, sans-serif" font-size="60" font-weight="bold" fill="#ffffff" text-anchor="middle">CX</text>
</svg>
import type { Metadata } from "next";
import { JetBrains_Mono } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
const jetbrainsMono = JetBrains_Mono({
subsets: ["latin"],
weight: ["300", "400", "500", "600", "700"],
variable: "--font-jetbrains",
});
export const metadata: Metadata = {
title: {
default: "WG Easy - WireGuard VPN Management",
template: "%s | WG Easy",
},
description: "WireGuard VPN Management Interface",
robots: {
index: false,
follow: false,
},
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="de" suppressHydrationWarning>
<head>
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
</head>
<body className={`${jetbrainsMono.variable} font-sans antialiased`}>
<ThemeProvider
attribute="class"
defaultTheme="dark"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}
"use client"
import { Logo } from "@/components/Logo"
import { ThemeToggle } from "@/components/theme-toggle"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Shield, Users, Network, Download } from "lucide-react"
import Link from "next/link"
export default function Dashboard() {
return (
<div className="min-h-screen bg-background">
{/* Header */}
<header className="border-b bg-card">
<div className="container mx-auto flex h-16 items-center justify-between px-4">
<Logo className="h-8" />
<div className="flex items-center gap-4">
<span className="text-sm text-muted-foreground">WireGuard VPN Management</span>
<ThemeToggle />
</div>
</div>
</header>
{/* Main Content */}
<main className="container mx-auto px-4 py-8">
<div className="mb-8">
<h1 className="text-3xl font-bold">WireGuard VPN Management</h1>
<p className="text-muted-foreground mt-2">
Verwalten Sie Ihre WireGuard VPN-Konfigurationen
</p>
</div>
{/* Stats Cards */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4 mb-8">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Aktive Clients</CardTitle>
<Users className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">0</div>
<p className="text-xs text-muted-foreground">Verbundene Clients</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Server Status</CardTitle>
<Shield className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">Online</div>
<p className="text-xs text-muted-foreground">Server läuft</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Gesamt Traffic</CardTitle>
<Network className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">0 MB</div>
<p className="text-xs text-muted-foreground">Upload/Download</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Downloads</CardTitle>
<Download className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">0</div>
<p className="text-xs text-muted-foreground">Konfigurationen</p>
</CardContent>
</Card>
</div>
{/* Quick Actions */}
<Card>
<CardHeader>
<CardTitle>Schnellzugriff</CardTitle>
<CardDescription>Häufig verwendete Funktionen</CardDescription>
</CardHeader>
<CardContent className="flex flex-wrap gap-4">
<Button>
Neuer Client hinzufügen
</Button>
<Button variant="outline">
Server konfigurieren
</Button>
<Button variant="outline">
Logs anzeigen
</Button>
</CardContent>
</Card>
</main>
</div>
)
}
{
"schemaVersion": 2,
"dockerfilePath": "./Dockerfile"
}
import Image from "next/image"
export function Logo({ className = "h-5 md:h-6 w-auto" }: { className?: string }) {
return (
<div className={className}>
<Image
src="/logo.png"
alt="CoreX Management"
width={200}
height={40}
className="h-full w-auto object-contain dark:invert-0 invert"
priority
/>
</div>
)
}
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
type ThemeProviderProps = Parameters<typeof NextThemesProvider>[0]
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
"use client"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
export function ThemeToggle() {
const { theme, setTheme } = useTheme()
return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
className="relative"
>
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
)
}
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
icon: "size-9",
"icon-sm": "size-8",
"icon-lg": "size-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot : "button"
return (
<Comp
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
)
}
export { Button, buttonVariants }
import * as React from "react"
import { cn } from "@/lib/utils"
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className
)}
{...props}
/>
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
import * as React from "react"
import { cn } from "@/lib/utils"
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
<input
type={type}
data-slot="input"
className={cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className
)}
{...props}
/>
)
}
export { Input }
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label }
import * as React from "react"
import { cn } from "@/lib/utils"
type SelectProps = React.SelectHTMLAttributes<HTMLSelectElement>
const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
({ className, children, ...props }, ref) => {
return (
<select
className={cn(
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
{...props}
>
{children}
</select>
)
}
)
Select.displayName = "Select"
export { Select }
import * as React from "react"
import { cn } from "@/lib/utils"
const Textarea = React.forwardRef<
HTMLTextAreaElement,
React.ComponentProps<"textarea">
>(({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
{...props}
/>
)
})
Textarea.displayName = "Textarea"
export { Textarea }
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
]),
]);
export default eslintConfig;
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: 'standalone',
};
export default nextConfig;
This diff is collapsed.
{
"name": "wg-easy",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-slot": "^1.2.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.562.0",
"next": "16.1.1",
"next-themes": "^0.4.6",
"react": "19.2.3",
"react-dom": "19.2.3",
"tailwind-merge": "^3.4.0",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.1.1",
"tailwindcss": "^4",
"typescript": "^5"
}
}
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0F172A;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1E293B;stop-opacity:1" />
</linearGradient>
<linearGradient id="xGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1.5" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background with gradient -->
<rect width="64" height="64" rx="12" fill="url(#bgGradient)"/>
<!-- X with gradient and glow -->
<g transform="translate(14, 14)">
<path d="M 4 4 L 32 32 M 32 4 L 4 32"
stroke="url(#xGradient)"
stroke-width="5"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="700" fill="#000000" letter-spacing="0.02em">Core</text>
<!-- X -->
<g transform="translate(115, 8)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="160" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="300" fill="#000000" letter-spacing="0.02em">Management</text>
</svg>
<svg width="200" height="100" viewBox="0 0 200 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1.5" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core + X -->
<g transform="translate(20, 20)">
<text x="0" y="40" font-family="'JetBrains Mono', monospace" font-size="46" font-weight="700" fill="currentColor" letter-spacing="0.02em">Core</text>
<!-- X -->
<g transform="translate(110, 5)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
</g>
<!-- Management -->
<text x="20" y="80" font-family="'JetBrains Mono', monospace" font-size="16" font-weight="300" fill="currentColor" letter-spacing="0.15em" opacity="0.8">MANAGEMENT</text>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;600;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Core -->
<text x="0" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="700" fill="currentColor" letter-spacing="0.02em">Core</text>
<!-- X (Blue Gradient) - Modern Design -->
<g transform="translate(115, 8)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Glow Effect -->
<defs>
<filter id="glow">
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Management -->
<text x="160" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="300" fill="currentColor" letter-spacing="0.02em">Management</text>
</svg>
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background Circle with gradient -->
<circle cx="50" cy="50" r="48" fill="url(#blueGradient)" opacity="0.1"/>
<!-- X with gradient and glow -->
<g transform="translate(25, 25)">
<path d="M 8 8 L 42 42 M 42 8 L 8 42"
stroke="url(#blueGradient)"
stroke-width="8"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&amp;display=swap');
</style>
<linearGradient id="xGradient" x1="0" y1="0" x2="32" y2="40" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#60A5FA"/>
<stop offset="50%" stop-color="#3B82F6"/>
<stop offset="100%" stop-color="#2563EB"/>
</linearGradient>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="700"
fill="#0F172A"
letter-spacing="0">
Core
</text>
<!-- X (Perfekt zentriert) -->
<g transform="translate(126, 8)">
<path d="M 4 4 L 32 40 M 32 4 L 4 40"
stroke="url(#xGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="178" y="40"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="400"
fill="#4B5563"
letter-spacing="0">
Management
</text>
</svg>
<svg width="360" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&amp;display=swap');
</style>
<!-- Verlauf für das X -->
<linearGradient id="xGradient" x1="0" y1="0" x2="32" y2="40" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#60A5FA"/>
<stop offset="50%" stop-color="#3B82F6"/>
<stop offset="100%" stop-color="#2563EB"/>
</linearGradient>
<!-- Glow -->
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="700"
fill="#FFFFFF"
letter-spacing="0">
Core
</text>
<!-- X (Perfekt zentriert) -->
<g transform="translate(126, 8)">
<path d="M 4 4 L 32 40 M 32 4 L 4 40"
stroke="url(#xGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="178" y="40"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="400"
fill="#E5E7EB"
letter-spacing="0">
Management
</text>
</svg>
<svg width="280" height="50" viewBox="0 0 280 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&amp;display=swap');
</style>
<linearGradient id="xGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#60A5FA;stop-opacity:1" />
<stop offset="50%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- CORE -->
<text x="0" y="35" font-family="'Space Grotesk', sans-serif" font-size="36" font-weight="700" fill="currentColor" letter-spacing="-0.5">CORE</text>
<!-- X (Blau mit Glow) -->
<g transform="translate(95, 5)">
<path d="M 3 3 L 27 37 M 27 3 L 3 37"
stroke="url(#xGradient)"
stroke-width="5.5"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- MANAGEMENT -->
<text x="135" y="35" font-family="'Space Grotesk', sans-serif" font-size="36" font-weight="500" fill="currentColor" letter-spacing="-0.3" opacity="0.9">MANAGEMENT</text>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="700" fill="#FFFFFF" letter-spacing="0.02em">Core</text>
<!-- X -->
<g transform="translate(115, 8)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="160" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="300" fill="#FFFFFF" letter-spacing="0.02em">Management</text>
</svg>
<svg width="1200" height="630" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;600;700&amp;display=swap');
</style>
<!-- Gradients -->
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0F172A;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1E293B;stop-opacity:1" />
</linearGradient>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<radialGradient id="glow1" cx="30%" cy="40%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0" />
</radialGradient>
<radialGradient id="glow2" cx="70%" cy="60%">
<stop offset="0%" style="stop-color:#2563EB;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:0" />
</radialGradient>
<filter id="textGlow">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect width="1200" height="630" fill="url(#bgGradient)"/>
<!-- Glows -->
<ellipse cx="360" cy="252" rx="400" ry="400" fill="url(#glow1)"/>
<ellipse cx="840" cy="378" rx="400" ry="400" fill="url(#glow2)"/>
<!-- Grid Pattern -->
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(255,255,255,0.03)" stroke-width="1"/>
</pattern>
</defs>
<rect width="1200" height="630" fill="url(#grid)"/>
<!-- Logo -->
<g transform="translate(240, 220)">
<!-- Core -->
<text x="0" y="70" font-family="'JetBrains Mono', monospace" font-size="85" font-weight="700" fill="#FFFFFF" letter-spacing="0.02em">Core</text>
<!-- X with gradient -->
<g transform="translate(250, 5)">
<path d="M 5 5 L 55 75 M 55 5 L 5 75"
stroke="url(#blueGradient)"
stroke-width="12"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#textGlow)"/>
</g>
<!-- Management -->
<text x="350" y="70" font-family="'JetBrains Mono', monospace" font-size="85" font-weight="300" fill="#FFFFFF" letter-spacing="0.02em">Management</text>
</g>
<!-- Tagline -->
<text x="600" y="420" font-family="'JetBrains Mono', monospace" font-size="28" font-weight="400" fill="#94A3B8" text-anchor="middle" letter-spacing="0.02em">IT-Dienstleistung &amp; Support für moderne Unternehmen</text>
<!-- URL -->
<text x="600" y="530" font-family="'JetBrains Mono', monospace" font-size="26" font-weight="600" fill="url(#blueGradient)" text-anchor="middle" letter-spacing="0.05em">corexmanagement.de</text>
</svg>
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1.5" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- X with gradient and glow -->
<path d="M 8 8 L 42 42 M 42 8 L 8 42"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<rect width="100" height="100" fill="#000000"/>
<text x="50" y="70" font-family="Arial, sans-serif" font-size="60" font-weight="bold" fill="#ffffff" text-anchor="middle">CX</text>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="700" fill="#000000" letter-spacing="0.02em">Core</text>
<!-- X -->
<g transform="translate(115, 8)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="160" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="300" fill="#000000" letter-spacing="0.02em">Management</text>
</svg>
<svg width="200" height="100" viewBox="0 0 200 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1.5" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core + X -->
<g transform="translate(20, 20)">
<text x="0" y="40" font-family="'JetBrains Mono', monospace" font-size="46" font-weight="700" fill="currentColor" letter-spacing="0.02em">Core</text>
<!-- X -->
<g transform="translate(110, 5)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
</g>
<!-- Management -->
<text x="20" y="80" font-family="'JetBrains Mono', monospace" font-size="16" font-weight="300" fill="currentColor" letter-spacing="0.15em" opacity="0.8">MANAGEMENT</text>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;600;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Core -->
<text x="0" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="700" fill="currentColor" letter-spacing="0.02em">Core</text>
<!-- X (Blue Gradient) - Modern Design -->
<g transform="translate(115, 8)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Glow Effect -->
<defs>
<filter id="glow">
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Management -->
<text x="160" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="300" fill="currentColor" letter-spacing="0.02em">Management</text>
</svg>
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background Circle with gradient -->
<circle cx="50" cy="50" r="48" fill="url(#blueGradient)" opacity="0.1"/>
<!-- X with gradient and glow -->
<g transform="translate(25, 25)">
<path d="M 8 8 L 42 42 M 42 8 L 8 42"
stroke="url(#blueGradient)"
stroke-width="8"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&amp;display=swap');
</style>
<linearGradient id="xGradient" x1="0" y1="0" x2="32" y2="40" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#60A5FA"/>
<stop offset="50%" stop-color="#3B82F6"/>
<stop offset="100%" stop-color="#2563EB"/>
</linearGradient>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="700"
fill="#0F172A"
letter-spacing="0">
Core
</text>
<!-- X (Perfekt zentriert) -->
<g transform="translate(126, 8)">
<path d="M 4 4 L 32 40 M 32 4 L 4 40"
stroke="url(#xGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="178" y="40"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="400"
fill="#4B5563"
letter-spacing="0">
Management
</text>
</svg>
<svg width="360" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&amp;display=swap');
</style>
<!-- Verlauf für das X -->
<linearGradient id="xGradient" x1="0" y1="0" x2="32" y2="40" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#60A5FA"/>
<stop offset="50%" stop-color="#3B82F6"/>
<stop offset="100%" stop-color="#2563EB"/>
</linearGradient>
<!-- Glow -->
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="700"
fill="#FFFFFF"
letter-spacing="0">
Core
</text>
<!-- X (Perfekt zentriert) -->
<g transform="translate(126, 8)">
<path d="M 4 4 L 32 40 M 32 4 L 4 40"
stroke="url(#xGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="178" y="40"
font-family="'JetBrains Mono', monospace"
font-size="42"
font-weight="400"
fill="#E5E7EB"
letter-spacing="0">
Management
</text>
</svg>
<svg width="280" height="50" viewBox="0 0 280 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&amp;display=swap');
</style>
<linearGradient id="xGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#60A5FA;stop-opacity:1" />
<stop offset="50%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- CORE -->
<text x="0" y="35" font-family="'Space Grotesk', sans-serif" font-size="36" font-weight="700" fill="currentColor" letter-spacing="-0.5">CORE</text>
<!-- X (Blau mit Glow) -->
<g transform="translate(95, 5)">
<path d="M 3 3 L 27 37 M 27 3 L 3 37"
stroke="url(#xGradient)"
stroke-width="5.5"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- MANAGEMENT -->
<text x="135" y="35" font-family="'Space Grotesk', sans-serif" font-size="36" font-weight="500" fill="currentColor" letter-spacing="-0.3" opacity="0.9">MANAGEMENT</text>
</svg>
<svg width="420" height="60" viewBox="0 0 420 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;700&amp;display=swap');
</style>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Core -->
<text x="0" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="700" fill="#FFFFFF" letter-spacing="0.02em">Core</text>
<!-- X -->
<g transform="translate(115, 8)">
<path d="M 2 2 L 28 38 M 28 2 L 2 38"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</g>
<!-- Management -->
<text x="160" y="42" font-family="'JetBrains Mono', monospace" font-size="40" font-weight="300" fill="#FFFFFF" letter-spacing="0.02em">Management</text>
</svg>
<svg width="1200" height="630" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;600;700&amp;display=swap');
</style>
<!-- Gradients -->
<linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#0F172A;stop-opacity:1" />
<stop offset="100%" style="stop-color:#1E293B;stop-opacity:1" />
</linearGradient>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<radialGradient id="glow1" cx="30%" cy="40%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0" />
</radialGradient>
<radialGradient id="glow2" cx="70%" cy="60%">
<stop offset="0%" style="stop-color:#2563EB;stop-opacity:0.3" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:0" />
</radialGradient>
<filter id="textGlow">
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Background -->
<rect width="1200" height="630" fill="url(#bgGradient)"/>
<!-- Glows -->
<ellipse cx="360" cy="252" rx="400" ry="400" fill="url(#glow1)"/>
<ellipse cx="840" cy="378" rx="400" ry="400" fill="url(#glow2)"/>
<!-- Grid Pattern -->
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(255,255,255,0.03)" stroke-width="1"/>
</pattern>
</defs>
<rect width="1200" height="630" fill="url(#grid)"/>
<!-- Logo -->
<g transform="translate(240, 220)">
<!-- Core -->
<text x="0" y="70" font-family="'JetBrains Mono', monospace" font-size="85" font-weight="700" fill="#FFFFFF" letter-spacing="0.02em">Core</text>
<!-- X with gradient -->
<g transform="translate(250, 5)">
<path d="M 5 5 L 55 75 M 55 5 L 5 75"
stroke="url(#blueGradient)"
stroke-width="12"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#textGlow)"/>
</g>
<!-- Management -->
<text x="350" y="70" font-family="'JetBrains Mono', monospace" font-size="85" font-weight="300" fill="#FFFFFF" letter-spacing="0.02em">Management</text>
</g>
<!-- Tagline -->
<text x="600" y="420" font-family="'JetBrains Mono', monospace" font-size="28" font-weight="400" fill="#94A3B8" text-anchor="middle" letter-spacing="0.02em">IT-Dienstleistung &amp; Support für moderne Unternehmen</text>
<!-- URL -->
<text x="600" y="530" font-family="'JetBrains Mono', monospace" font-size="26" font-weight="600" fill="url(#blueGradient)" text-anchor="middle" letter-spacing="0.05em">corexmanagement.de</text>
</svg>
<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="blueGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#3B82F6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#2563EB;stop-opacity:1" />
</linearGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="1.5" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- X with gradient and glow -->
<path d="M 8 8 L 42 42 M 42 8 L 8 42"
stroke="url(#blueGradient)"
stroke-width="6"
stroke-linecap="round"
stroke-linejoin="round"
filter="url(#glow)"/>
</svg>
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules"]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment