Merge branch 'dev' into 'production'

Merge dev into production

See merge request rheinsw/website!27
This commit is contained in:
2025-04-13 20:12:11 +00:00
parent f9d2552b90
commit 40f266f8da
79 changed files with 3477 additions and 288 deletions

View File

@@ -1,4 +1,4 @@
image: node:20@sha256:735b1ba7e4550c415f98568efbf527e3f75828ac4f10692e490ca78e11d89f6e
image: node:22@sha256:f6b9c31ace05502dd98ef777aaa20464362435dcc5e312b0e213121dcf7d8b95
workflow:
rules:
@@ -17,7 +17,7 @@ cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
policy: pull
- .next/cache/
variables:
NEXT_PUBLIC_ENV: "production"

View File

@@ -1,5 +1,5 @@
# Use lightweight Node.js 20 base image
FROM node:20-alpine as builder
FROM node:20-alpine@sha256:9bef0ef1e268f60627da9ba7d7605e8831d5b56ad07487d24d1aa386336d1944 as builder
# Set working directory
WORKDIR /app
@@ -8,7 +8,7 @@ WORKDIR /app
COPY package.json package-lock.json ./
# Install dependencies
RUN npm install
RUN npm ci
# Copy entire project
COPY . .
@@ -17,7 +17,7 @@ COPY . .
RUN npm run build
# Use a minimal base image for running the app
FROM node:20-alpine
FROM node:20-alpine@sha256:9bef0ef1e268f60627da9ba7d7605e8831d5b56ad07487d24d1aa386336d1944
WORKDIR /app

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

35
app/(root)/layout.tsx Normal file
View File

@@ -0,0 +1,35 @@
import type {Metadata} from "next";
import "../globals.css";
import Nav from "@/components/Navbar/Nav";
import Footer from "@/components/Footer/Footer";
import {ThemeProvider} from "@/components/provider/ThemeProvider";
import React from "react";
import {cookies} from "next/headers";
export const metadata: Metadata = {
title: "Rhein Software",
description: "Rhein Software Development",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cookieStore = await cookies();
const theme = cookieStore.get("theme")?.value === "dark" ? "dark" : "light";
return (
<html lang="de" data-theme={theme}>
<head/>
<body className="antialiased" style={{backgroundColor: "var(--primary-bg)"}}>
<ThemeProvider>
<Nav/>
{children}
<Footer/>
</ThemeProvider>
</body>
</html>
);
}

12
app/(root)/page.tsx Normal file
View File

@@ -0,0 +1,12 @@
import React from 'react';
import Home from "@/components/Home/Home";
const HomePage = () => {
return (
<div>
<Home />
</div>
);
};
export default HomePage;

35
app/contact/layout.tsx Normal file
View File

@@ -0,0 +1,35 @@
import type {Metadata} from "next";
import "../globals.css";
import Nav from "@/components/Navbar/Nav";
import Footer from "@/components/Footer/Footer";
import {ThemeProvider} from "@/components/provider/ThemeProvider";
import React from "react";
import {cookies} from "next/headers";
export const metadata: Metadata = {
title: "Rhein Software",
description: "Rhein Software Development",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cookieStore = await cookies();
const theme = cookieStore.get("theme")?.value === "dark" ? "dark" : "light";
return (
<html lang="de" data-theme={theme}>
<head/>
<body className="antialiased" style={{backgroundColor: "var(--primary-bg)"}}>
<ThemeProvider>
<Nav/>
{children}
<Footer/>
</ThemeProvider>
</body>
</html>
);
}

12
app/contact/page.tsx Normal file
View File

@@ -0,0 +1,12 @@
import React from 'react';
import Contact from "@/components/Contact/Contact";
const ContactPage = () => {
return (
<div>
<Contact/>
</div>
);
};
export default ContactPage;

View File

@@ -1,26 +1,48 @@
@import "tailwindcss";
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
@layer utilities {
.nav__link {
@apply relative text-base font-medium w-fit block after:block after:content-[''] after:absolute after:h-[3px] after:bg-pink-600 after:w-full after:scale-x-0 after:hover:scale-x-100 after:transition after:duration-300 after:origin-right;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
/* Global theme transition */
.transition-theme {
transition: background-color 0.7s ease, color 0.7s ease;
}
/* Light mode */
/* Light mode */
[data-theme="light"] {
--primary-bg: #FAFAFA; /* Soft off-white background */
--secondary-bg: #F5F5F7; /* Gentle off-white for subtle separation */
--primary-text: #2E2E2E; /* Dark grey text for clear readability */
--secondary-text: #595959; /* Medium grey for less prominent text */
--nav-bg: #F8F8F8; /* Light grey navigation background */
--footer-bg: #E0E0E0; /* Slightly darker grey for footer contrast */
}
/* Dark mode */
[data-theme="dark"] {
--primary-bg: #2C2C2C; /* Modern dark grey background */
--secondary-bg: #333333; /* A touch lighter grey for section differentiation */
--primary-text: #E0E0E0; /* Light grey text for optimal readability */
--secondary-text: #B0B0B0; /* Medium grey for secondary text elements */
--nav-bg: #272727; /* Subtle variation for the navigation area */
--footer-bg: #242424; /* Deep grey footer to add visual depth */
}
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-6px);
}
}
.animate-float {
animation: float 3.5s ease-in-out infinite;
}

View File

@@ -1,34 +0,0 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}

View File

@@ -0,0 +1,12 @@
import React from 'react';
import ImprintComp from "@/components/Legal/ImprintComp";
const ImprintPage = () => {
return (
<div>
<ImprintComp />
</div>
);
};
export default ImprintPage;

35
app/legal/layout.tsx Normal file
View File

@@ -0,0 +1,35 @@
import type {Metadata} from "next";
import "../globals.css";
import Nav from "@/components/Navbar/Nav";
import Footer from "@/components/Footer/Footer";
import {ThemeProvider} from "@/components/provider/ThemeProvider";
import React from "react";
import {cookies} from "next/headers";
export const metadata: Metadata = {
title: "Rhein Software",
description: "Rhein Software Development",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cookieStore = await cookies();
const theme = cookieStore.get("theme")?.value === "dark" ? "dark" : "light";
return (
<html lang="de" data-theme={theme}>
<head/>
<body className="antialiased" style={{backgroundColor: "var(--primary-bg)"}}>
<ThemeProvider>
<Nav/>
{children}
<Footer/>
</ThemeProvider>
</body>
</html>
);
}

10
app/legal/page.tsx Normal file
View File

@@ -0,0 +1,10 @@
import React from 'react';
const LegalPage = () => {
return (
<div>
</div>
);
};
export default LegalPage;

View File

@@ -0,0 +1,12 @@
import React from 'react';
import PrivacyComp from "@/components/Legal/PrivacyComp";
const PrivacyPage = () => {
return (
<div>
<PrivacyComp />
</div>
);
};
export default PrivacyPage;

View File

@@ -0,0 +1,12 @@
import React from 'react';
import RevocationComp from "@/components/Legal/RevocationComp";
const RevocationPage = () => {
return (
<div>
<RevocationComp />
</div>
);
};
export default RevocationPage;

View File

@@ -0,0 +1,12 @@
import React from 'react';
import TermsOfUseComp from "@/components/Legal/TermsOfUseComp";
const TermsOfUsePage = () => {
return (
<div>
<TermsOfUseComp/>
</div>
);
};
export default TermsOfUsePage;

View File

@@ -1,103 +0,0 @@
import Image from "next/image";
export default function Home() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}-From Feature Branch
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
</div>
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
}

35
app/services/layout.tsx Normal file
View File

@@ -0,0 +1,35 @@
import type {Metadata} from "next";
import "../globals.css";
import Nav from "@/components/Navbar/Nav";
import Footer from "@/components/Footer/Footer";
import {ThemeProvider} from "@/components/provider/ThemeProvider";
import React from "react";
import {cookies} from "next/headers";
export const metadata: Metadata = {
title: "Rhein Software",
description: "Rhein Software Development",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cookieStore = await cookies();
const theme = cookieStore.get("theme")?.value === "dark" ? "dark" : "light";
return (
<html lang="de" data-theme={theme}>
<head/>
<body className="antialiased" style={{backgroundColor: "var(--primary-bg)"}}>
<ThemeProvider>
<Nav/>
{children}
<Footer/>
</ThemeProvider>
</body>
</html>
);
}

12
app/services/page.tsx Normal file
View File

@@ -0,0 +1,12 @@
import React from 'react';
import Contact from "@/components/Contact/Contact";
const ContactPage = () => {
return (
<div>
<Contact/>
</div>
);
};
export default ContactPage;

View File

@@ -0,0 +1,100 @@
"use client";
import React, {useEffect, useContext} from "react";
import AOS from "aos";
import "aos/dist/aos.css";
import SmallHero from "@/components/Helper/SmallHero";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
const Contact = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Kontakt"
subtitle="Hast du Fragen? Wir sind für dich da!"
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</p>
<form className="mt-8 max-w-2xl mx-auto space-y-6">
{/* Name & Email */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{["Dein Name", "Deine E-Mail"].map((label, index) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<label className="block font-semibold">{label}</label>
<input
type={index === 0 ? "text" : "email"}
placeholder={index === 0 ? "Max Mustermann" : "max@example.com"}
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<button
type="submit"
className="px-6 py-3 bg-blue-600 text-white text-lg font-semibold rounded-lg shadow-md hover:bg-blue-700 transition-all"
>
📩 Nachricht senden
</button>
</div>
</form>
</div>
</div>
);
};
export default Contact;

View File

@@ -0,0 +1,97 @@
'use client';
import React from 'react';
import Link from 'next/link';
import {motion} from 'framer-motion';
const Footer = () => {
return (
<motion.footer
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.6, ease: 'easeOut'}}
className="py-10 transition-theme text-white"
style={{
backgroundColor: '#16171f', // modern dark blue-purple tone
}}
>
<div className="w-[90%] mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-8">
{/* Logo and description */}
<div>
<h1 className="text-xl md:text-2xl font-bold text-white">
<span className="text-3xl md:text-4xl text-pink-700">R</span>hein Software
</h1>
</div>
{/* Informationen */}
<div>
<h3 className="text-lg font-semibold text-white">Informationen</h3>
<ul className="mt-4 space-y-4 text-sm font-semibold text-gray-400">
<li>
<Link href="/contact">
<p className="nav_link transition-all duration-300 ease-in-out hover:text-white">
Kontakt
</p>
</Link>
</li>
<li>
<Link href="/contact">
<p className="nav_link transition-all duration-300 ease-in-out hover:text-white">
Zahlung und Versand
</p>
</Link>
</li>
</ul>
</div>
{/* Rechtliches */}
<div>
<h3 className="text-lg font-semibold text-white">Rechtliches</h3>
<ul className="mt-4 space-y-4 text-sm font-semibold text-gray-400">
<li>
<Link href="/legal/terms-of-use">
<p className="nav_link transition-all duration-300 ease-in-out hover:text-white">
AGB
</p>
</Link>
</li>
<li>
<Link href="/legal/revocation">
<p className="nav_link transition-all duration-300 ease-in-out hover:text-white">
Widerruf
</p>
</Link>
</li>
<li>
<Link href="/legal/privacy">
<p className="nav_link transition-all duration-300 ease-in-out hover:text-white">
Datenschutz
</p>
</Link>
</li>
<li>
<Link href="/legal/imprint">
<p className="nav_link transition-all duration-300 ease-in-out hover:text-white">
Impressum
</p>
</Link>
</li>
</ul>
</div>
</div>
{/* Bottom Section */}
<div
className="mt-8 border-t border-gray-600 pt-8 flex flex-col md:flex-row justify-between items-center text-sm text-gray-400">
<p className="text-center md:text-left">
© 2025 Rhein Software Development. All rights reserved.
</p>
</div>
</div>
</motion.footer>
);
};
export default Footer;

View File

@@ -0,0 +1,24 @@
export const SectionDivider1 = () => {
return (
<div
className="w-full h-20 transition-all duration-500 ease-in-out"
style={{
background: `linear-gradient(to bottom, var(--primary-bg), var(--secondary-bg))`
}}
/>
);
};
export const SectionDivider2 = () => {
return (
<div
className="w-full h-20 transition-all duration-500 ease-in-out"
style={{
background: `linear-gradient(to bottom, var(--secondary-bg), var(--primary-bg))`
}}
/>
);
};

View File

@@ -0,0 +1,40 @@
import React from "react";
type SmallHeroProps = {
title: string;
subtitle?: string;
backgroundImage?: string; // Optional background image
};
const SmallHero = ({title, subtitle, backgroundImage}: SmallHeroProps) => {
return (
<div
className="w-full py-20 text-center flex flex-col items-center justify-center bg-cover bg-center"
style={{
backgroundColor: backgroundImage ? "transparent" : "var(--primary-bg)", // Fallback if no image
color: "var(--primary-text)",
backgroundImage: backgroundImage ? `url(${backgroundImage})` : "none",
backgroundSize: "cover",
backgroundPosition: "center",
backgroundBlendMode: "overlay",
transition: "background-color 0.4s ease-in-out, color 0.4s ease-in-out",
}}
>
<h1 className="text-3xl sm:text-4xl font-bold"
data-aos="fade-up"
>
{title}
</h1>
{subtitle &&
<p className="mt-2 text-lg text-[var(--secondary-text)]"
data-aos="fade-up"
data-aos-delay="200"
>
{subtitle}
</p>
}
</div>
);
};
export default SmallHero;

View File

@@ -0,0 +1,18 @@
"use server";
import {cookies} from "next/headers";
// ✅ Get theme from cookies OR detect system preference
export async function getInitialTheme(): Promise<"dark" | "light"> {
const themeCookie = (await cookies()).get("theme")?.value;
if (themeCookie === "dark" || themeCookie === "light") {
return themeCookie;
}
// Detect system preference
const prefersDarkMode =
typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
return prefersDarkMode ? "dark" : "light";
}

View File

@@ -0,0 +1,28 @@
export const themeColors: Record<
"light" | "dark",
{
primaryBg: string;
secondaryBg: string;
primaryText: string;
secondaryText: string;
inputFieldBg: string;
inputBorder: string;
}
> = {
dark: {
primaryBg: "#121212", // Dark gray/black background (closer to true dark mode)
secondaryBg: "#1e1e1e", // Slightly lighter gray for contrast
primaryText: "#e0e0e0", // Light gray for good readability
secondaryText: "#b0b0b0", // Muted gray for subtle contrast
inputFieldBg: "#252525", // Dark but slightly distinguishable from primaryBg
inputBorder: "#3a3a3a", // Slightly lighter gray for a soft contrast
},
light: {
primaryBg: "#f7f6fb",
secondaryBg: "#ffffff",
primaryText: "#1a1a2e",
secondaryText: "#4a4a4a", // Muted text color
inputFieldBg: "#ffffff", // White input field (same as secondaryBg)
inputBorder: "#dcdcdc", // Light gray border for subtle visibility
},
};

View File

@@ -0,0 +1,82 @@
'use client';
import Link from 'next/link';
import {FiArrowRight} from 'react-icons/fi';
import {motion} from 'framer-motion';
const About = () => {
return (
<section className="relative w-full py-24 bg-[var(--secondary-bg)] transition-theme">
<div className="w-full max-w-6xl px-6 md:px-10 mx-auto">
<div className="flex flex-col">
{/* Title */}
<motion.h2
className="text-3xl md:text-4xl font-bold mb-1 text-left"
style={{color: 'var(--primary-text)'}}
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.5}}
>
Über uns
</motion.h2>
<motion.div
className="w-12 h-[2px] mt-2 mb-6 bg-amber-500"
initial={{opacity: 0, x: -20}}
whileInView={{opacity: 1, x: 0}}
viewport={{once: true}}
transition={{duration: 0.4, delay: 0.1}}
/>
{/* Text */}
<div className="p-0">
<motion.p
className="text-base md:text-lg leading-relaxed text-[var(--secondary-text)] max-w-4xl"
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.5, delay: 0.2}}
>
Wir sind Rhein-Software ein Team, das sich auf individuelle Softwarelösungen und digitale
Services spezialisiert hat. Unsere Anwendungen sind technisch solide, skalierbar und
durchdacht gebaut für
langfristigen Erfolg.
</motion.p>
<motion.p
className="mt-6 text-base md:text-lg leading-relaxed text-[var(--secondary-text)] max-w-4xl"
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.5, delay: 0.3}}
>
Von der ersten Idee bis zum Go-Live begleiten wir Unternehmen und Startups mit einem
flexiblen Netzwerk, klarer Kommunikation und einem hohen Anspruch an Qualität. Unsere
Lösungen sind
intuitiv, effizient und genau auf deine Anforderungen zugeschnitten.
</motion.p>
</div>
{/* CTA Button */}
<motion.div
className="mt-10 flex justify-end"
initial={{opacity: 0, y: 10}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.5, delay: 0.5}}
>
<Link href="/about">
<button
className="flex items-center gap-2 bg-blue-700 hover:bg-blue-900 text-white font-semibold px-5 py-2 rounded-full shadow-lg transition-all">
Mehr über uns <FiArrowRight size={18}/>
</button>
</Link>
</motion.div>
</div>
</div>
</section>
);
};
export default About;

View File

@@ -0,0 +1,57 @@
'use client';
import Link from 'next/link';
import { motion } from 'framer-motion';
import { FiArrowRight } from 'react-icons/fi';
const ContactCTA = () => {
return (
<section
className="relative w-full py-24 transition-theme overflow-hidden"
style={{
background: 'linear-gradient(135deg, var(--secondary-bg), var(--primary-bg))',
}}
>
<div className="w-full max-w-4xl px-6 md:px-10 mx-auto text-center">
{/* Headline */}
<motion.h2
className="text-3xl md:text-4xl font-bold text-[var(--primary-text)]"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5 }}
>
Interesse geweckt?
</motion.h2>
{/* Description */}
<motion.p
className="mt-4 text-sm md:text-base text-[var(--secondary-text)] max-w-xl mx-auto"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.2 }}
>
Lass uns über dein Projekt sprechen. Wir freuen uns darauf, deine Ideen in die Realität umzusetzen.
</motion.p>
{/* CTA Button */}
<motion.div
className="mt-8 flex justify-center"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.3 }}
>
<Link href="/contact">
<button className="inline-flex items-center gap-2 px-6 py-3 text-sm md:text-base font-semibold rounded-full bg-blue-700 hover:bg-blue-900 text-white shadow-md transition-all duration-300">
Jetzt Kontakt aufnehmen <FiArrowRight size={18} />
</button>
</Link>
</motion.div>
</div>
</section>
);
};
export default ContactCTA;

View File

@@ -0,0 +1,100 @@
'use client';
import Image from 'next/image';
import {Typewriter} from 'react-simple-typewriter';
import {motion} from 'framer-motion';
const Hero = () => {
return (
<div
className="relative w-full pt-[4vh] md:pt-[12vh] h-screen flex flex-col overflow-hidden"
style={{
backgroundColor: 'var(--primary-bg)',
color: 'white',
}}
>
{/* Background Image */}
<div className="absolute inset-0 z-0">
<Image
src="/images/home_hero.jpg"
alt="Rhein river aerial view"
layout="fill"
objectFit="cover"
className="blur-md scale-105"
priority
/>
<div className="absolute inset-0 bg-black/40"/>
</div>
{/* Main content */}
<div className="relative z-10 flex justify-center flex-col w-[90%] sm:w-[80%] h-full mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-2 items-center gap-12">
{/* Text Content */}
<div>
<motion.h1
className="text-3xl sm:text-4xl md:text-5xl mt-6 mb-6 font-bold text-white"
initial={{opacity: 0, y: 30}}
animate={{opacity: 1, y: 0}}
transition={{duration: 0.6, ease: 'easeOut'}}
>
Rhein-Software Development
</motion.h1>
<motion.p
className="text-lg md:text-xl text-gray-400"
initial={{opacity: 0, y: 30}}
animate={{opacity: 1, y: 0}}
transition={{duration: 0.6, delay: 0.2, ease: 'easeOut'}}
>
Digitale Lösungen für dein Unternehmen.
</motion.p>
<motion.p
className="mt-4 text-lg md:text-xl font-semibold text-white"
initial={{opacity: 0}}
animate={{opacity: 1}}
transition={{delay: 0.9, duration: 0.6}}
>
<Typewriter
words={['Beratung', 'Entwicklung', 'Wartung', 'Fehlerbehebung']}
loop={true}
cursor
cursorStyle="_"
typeSpeed={60}
deleteSpeed={40}
delaySpeed={1500}
/>
</motion.p>
</div>
{/* Floating Image */}
<motion.div
className="hidden lg:block"
initial={{opacity: 0, y: 30}}
animate={{opacity: 1, y: 0}}
transition={{duration: 0.8, ease: 'easeOut', delay: 0.3}}
>
<motion.div
animate={{y: [0, -10, 0]}}
transition={{
duration: 4,
repeat: Infinity,
ease: 'easeInOut',
}}
className="animate-float"
>
<Image
src="/images/hero.png"
alt="hero graphic"
width={700}
height={700}
/>
</motion.div>
</motion.div>
</div>
</div>
</div>
);
};
export default Hero;

27
components/Home/Home.tsx Normal file
View File

@@ -0,0 +1,27 @@
'use client';
import React from "react";
import Hero from "./Hero/Hero";
import About from "@/components/Home/About/About";
import ContactCTA from "@/components/Home/Contact/ContactCTA";
import {SectionDivider1, SectionDivider2} from "@/components/Helper/SectionDivider";
import HomeServices from "@/components/Home/HomeServices";
import TechStack from "@/components/Home/TechStack";
const Home = () => {
return (
<div className="overflow-hidden">
<Hero/>
<SectionDivider1/>
<About/>
<SectionDivider2/>
<HomeServices/>
<SectionDivider1/>
<TechStack/>
<SectionDivider2/>
<ContactCTA/>
</div>
);
};
export default Home;

View File

@@ -0,0 +1,115 @@
'use client';
import {
FiServer,
FiTool,
FiMonitor,
FiZap,
FiArrowRight,
} from 'react-icons/fi';
import {motion} from 'framer-motion';
const services = [
{
title: 'Beratung',
icon: <FiMonitor size={24}/>,
description:
'Strategische und technische Beratung rund um digitale Produkte und Prozesse. Wir analysieren bestehende Systeme, identifizieren Potenziale und helfen dir, die passende Architektur für dein Projekt zu finden.',
},
{
title: 'Entwicklung',
icon: <FiZap size={24}/>,
description:
'Individuelle Softwareentwicklung skalierbar, wartbar, zukunftssicher. Ob Web-App, API oder internes Tool: Wir setzen moderne Technologien ein, um genau die Lösung zu bauen, die du brauchst.',
},
{
title: 'Managed Services',
icon: <FiServer size={24}/>,
description:
'Wir betreuen Infrastruktur, Server und Systeme verlässlich und performant. Unser Team kümmert sich um Hosting, Monitoring, Backups und sorgt für einen reibungslosen Betrieb deiner Plattform.',
},
{
title: 'Fehlerbehebung',
icon: <FiTool size={24}/>,
description:
'Schnelle Hilfe bei Bugs, Performance-Problemen oder Sicherheitslücken. Wir analysieren Probleme, beheben sie gezielt und sorgen dafür, dass dein System wieder stabil läuft langfristig und zuverlässig.',
},
];
const HomeServices = () => {
return (
<section
className="w-full py-24 bg-[var(--primary-bg)] transition-theme"
id="leistungen"
>
<div className="w-full max-w-6xl px-6 md:px-10 mx-auto">
{/* Heading */}
<motion.h2
className="text-3xl md:text-4xl font-bold mb-1 text-left text-[var(--primary-text)]"
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.4}}
>
Leistungen
</motion.h2>
<motion.div
className="w-12 h-[2px] mt-2 mb-10 bg-amber-500"
initial={{opacity: 0, x: -20}}
whileInView={{opacity: 1, x: 0}}
viewport={{once: true}}
transition={{duration: 0.4, delay: 0.1}}
/>
{/* Service Cards */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{services.map((service, index) => (
<motion.div
key={service.title}
className="p-6 rounded-xl border border-[var(--secondary-bg)] bg-[var(--secondary-bg)] shadow-md"
whileHover={{
scale: 1.03,
boxShadow: '0px 10px 20px rgba(0,0,0,0.1)',
}}
initial={{opacity: 0, y: 30}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{
duration: 0.4,
delay: index * 0.1,
ease: 'easeOut',
}}
>
<div className="mb-3 text-blue-600">{service.icon}</div>
<h3 className="text-xl font-semibold mb-2 text-[var(--primary-text)]">
{service.title}
</h3>
<p className="text-sm text-[var(--secondary-text)] leading-relaxed">
{service.description}
</p>
</motion.div>
))}
</div>
{/* Weitere Leistungen */}
<motion.div
className="mt-10 flex justify-end"
initial={{opacity: 0}}
whileInView={{opacity: 1}}
viewport={{once: true}}
transition={{duration: 0.4, delay: 0.3}}
>
<a
href="/services"
className="text-sm font-semibold text-blue-600 hover:underline flex items-center gap-1"
>
Weitere Leistungen <FiArrowRight size={16}/>
</a>
</motion.div>
</div>
</section>
);
};
export default HomeServices;

View File

@@ -0,0 +1,75 @@
import React from "react";
import Image from "next/image";
const FullStack = () => {
return (
<div
className="w-[95%] sm:w-[80%] mx-auto items-center grid grid-cols-1 lg:grid-cols-2 gap-6 mt-8 mb-16 transition-theme">
<div className="p-0"
>
<h1 data-aos="fade-up"
className="mt-4 text-xl sm:text-2xl md:text-3xl font-bold"
style={{color: "var(--primary-text)"}} // Dynamic text color
>
💻 Full-Stack Entwicklung
</h1>
<div data-aos="fade-up"
data-aos-delay="200"
>
<p
className="mt-4 text-sm font-medium leading-[2rem]"
style={{color: "var(--secondary-text)"}} // Secondary text color
>
Wir entwickeln skalierbare Backends, performante Frontends und native Apps genau auf deine
Anforderungen zugeschnitten. Dabei setzen wir auf neueste und modernste Technologien, um
flexible
und zukunftssichere Lösungen zu schaffen.
</p>
{/* Technology Logos Section */}
<h2
className="mt-8 text-lg font-semibold"
style={{color: "var(--primary-text)"}}
>
🔧 Tech Stack
</h2>
<span
className="mt-4 text-sm font-medium leading-[2rem]"
style={{color: "var(--secondary-text)"}}
>
Programmiersprachen und Frameworks, die wir für unsere Lösungen einsetzen.
</span>
<div className="mt-6 flex flex-wrap items-center gap-8">
{/* Tech Stack Logos */}
{[
{src: "/images/flutter_logo.png", label: "Flutter", width: 30, height: 30},
{src: "/images/dart_logo.png", label: "Dart", width: 40, height: 40},
{src: "/images/java_logo.png", label: "Java", width: 40, height: 40},
{src: "/images/nextjs_logo.png", label: "NextJS", width: 40, height: 40},
].map(({src, label, width, height}) => (
<div key={label} className="flex flex-col items-center">
<Image src={src} alt={label} width={width} height={height} className="object-contain"/>
<span
className="text-xs mt-2"
style={{color: "var(--secondary-text)"}} // Match theme
>
{label}
</span>
</div>
))}
</div>
</div>
</div>
<div data-aos="fade-up" data-aos-anchor-placement="top-center" className="justify-self-center">
<Image
src="/images/software_dev.jpg"
alt="image"
width={200}
height={200}
className="object-contain"
/>
</div>
</div>
);
};
export default FullStack;

View File

@@ -0,0 +1,57 @@
import React from "react";
import Image from "next/image";
import {TiChevronRightOutline} from "react-icons/ti";
const ManagedServices = () => {
return (
<div
className="w-[95%] sm:w-[80%] mx-auto items-center grid grid-cols-1 lg:grid-cols-2 gap-6 mt-8 mb-16"
data-aos="fade-up"
data-aos-delay="200"
>
{/* Image Section */}
<div
data-aos="fade-up"
data-aos-anchor-placement="top-center"
className="justify-self-center"
>
<Image
src="/images/software_dev.jpg"
alt="image"
width={200}
height={200}
className="object-contain"
/>
</div>
{/* Text Content */}
<div className="p-0">
<h1
className="mt-4 text-xl sm:text-2xl md:text-3xl font-bold transition-theme"
style={{color: "var(--primary-text)"}}>
Managed Services
</h1>
<p
className="mt-4 text-sm font-medium leading-[2rem] transition-theme"
style={{color: "var(--secondary-text)"}}>
Wir übernehmen das Hosting und Management deiner Server, damit du dich auf dein
Business konzentrieren kannst. Egal ob Cloud-Hosting, dedizierte Server oder hybride Lösungen wir
sorgen für eine sichere, performante und skalierbare Infrastruktur.
</p>
<ul className="mt-7 space-y-2">
{[
"Web- & Cloud-Hosting",
"Mailserver-Management",
"Webserver-Administration",
].map((item, index) => (
<li key={index} className="flex items-center font-semibold transition-theme">
<TiChevronRightOutline className="text-blue-500 mr-2"/>
<span style={{color: "var(--primary-text)"}}>{item}</span>
</li>
))}
</ul>
</div>
</div>
);
};
export default ManagedServices;

View File

@@ -0,0 +1,28 @@
import React from "react";
import FullStack from "@/components/Home/Offer/FullStack";
import ManagedServices from "@/components/Home/Offer/ManagedServices";
const Offer = () => {
return (
<div
className="transition-theme"
style={{
backgroundColor: "var(--primary-bg)", // Using CSS variable
color: "var(--primary-text)", // Ensuring text color follows theme
transition: "background-color 0.5s ease, color 0.5s ease", // Smooth transition
}}>
<div className="pt-24 pb-16">
<h1 className="mt-6 text-2xl md:text-3xl capitalize font-bold text-center"
data-aos="fade-up"
style={{color: "var(--primary-text)"}}
>
Was bieten wir?
</h1>
<FullStack/>
<ManagedServices/>
</div>
</div>
);
};
export default Offer;

View File

@@ -0,0 +1,150 @@
'use client';
import Image from 'next/image';
import {motion} from 'framer-motion';
const techStack = {
row1: [
{
category: 'Programmiersprachen & Frameworks Backend',
items: [
{id: 'java', label: 'Java'},
{id: 'dart', label: 'Dart'},
{id: 'kotlin', label: 'Kotlin'},
{id: 'spring', label: 'Spring'},
],
},
{
category: 'Programmiersprachen & Frameworks Frontend',
items: [
{id: 'html', label: 'HTML'},
{id: 'css', label: 'CSS'},
{id: 'bootstrap', label: 'Bootstrap'},
{id: 'nextjs', label: 'Next.js'},
{id: 'typescript', label: 'TypeScript'},
{id: 'flutter', label: 'Flutter'},
],
},
],
row2: [
{
category: 'Betriebssysteme',
items: [
{id: 'macos', label: 'macOS'},
{id: 'debian', label: 'Debian'},
{id: 'ubuntu', label: 'Ubuntu'},
],
},
{
category: 'Version Control & Collaboration',
items: [
{id: 'gitlab', label: 'GitLab'},
{id: 'outline', label: 'Outline'},
],
},
{
category: 'DevOps & Infrastruktur',
items: [
{id: 'gitlab-ci', label: 'GitLab CI'},
{id: 'docker', label: 'Docker'},
{id: 'proxmox', label: 'Proxmox'},
],
},
],
};
const TechStack = () => {
return (
<section className="w-full py-20 bg-[var(--secondary-bg)] transition-theme">
<div className="w-full max-w-6xl px-6 md:px-10 mx-auto">
<motion.h2
className="text-2xl md:text-3xl font-bold mb-1 text-left text-[var(--primary-text)]"
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.5}}
>
Technologien
</motion.h2>
<motion.div
className="w-12 h-[2px] mt-2 mb-6 bg-amber-500"
initial={{opacity: 0, x: -20}}
whileInView={{opacity: 1, x: 0}}
viewport={{once: true}}
transition={{duration: 0.4, delay: 0.1}}
/>
<motion.p
className="text-sm md:text-base mb-10 text-[var(--secondary-text)]"
initial={{opacity: 0, y: 10}}
whileInView={{opacity: 1, y: 0}}
viewport={{once: true}}
transition={{duration: 0.4, delay: 0.2}}
>
Mit diesen Technologien realisieren wir moderne, leistungsstarke Softwarelösungen.
</motion.p>
{/* Row 1 */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
{techStack.row1.map((group, index) => (
<TechCard key={group.category} group={group} delay={index * 0.2}/>
))}
</div>
{/* Row 2 */}
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
{techStack.row2.map((group, index) => (
<TechCard
key={group.category}
group={group}
delay={index * 0.2 + 0.4}
/>
))}
</div>
</div>
</section>
);
};
const TechCard = ({
group,
delay,
}: {
group: { category: string; items: { id: string; label: string }[] };
delay: number;
}) => (
<motion.div
className="p-4 rounded-lg border border-[var(--primary-bg)] bg-[var(--primary-bg)] shadow-md transition-theme"
initial={{opacity: 0, y: 20}}
whileInView={{opacity: 1, y: 0}}
whileHover={{
scale: 1.03,
boxShadow: '0px 10px 20px rgba(0,0,0,0.1)',
}}
viewport={{once: true}}
transition={{duration: 0.4, delay, ease: 'easeOut'}}
>
<h3 className="text-base font-semibold mb-4 text-[var(--primary-text)]">
{group.category}
</h3>
<div className="grid grid-cols-3 gap-3">
{group.items.map(({id, label}) => (
<div key={id} className="flex flex-col items-center text-center">
<Image
src={`/images/svg/${id}.svg`}
alt={label}
width={32}
height={32}
className="object-contain"
/>
<span className="text-[10px] mt-1 text-[var(--secondary-text)]">
{label}
</span>
</div>
))}
</div>
</motion.div>
);
export default TechStack;

View File

@@ -0,0 +1,99 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const ImprintComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Impressum"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</p>
<form className="mt-8 max-w-2xl mx-auto space-y-6">
{/* Name & Email */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{["Dein Name", "Deine E-Mail"].map((label, index) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<label className="block font-semibold">{label}</label>
<input
type={index === 0 ? "text" : "email"}
placeholder={index === 0 ? "Max Mustermann" : "max@example.com"}
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<button
type="submit"
className="px-6 py-3 bg-blue-600 text-white text-lg font-semibold rounded-lg shadow-md hover:bg-blue-700 transition-all"
>
📩 Nachricht senden
</button>
</div>
</form>
</div>
</div>
);
};
export default ImprintComp;

View File

@@ -0,0 +1,99 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const PrivacyComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Datenschutz"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</p>
<form className="mt-8 max-w-2xl mx-auto space-y-6">
{/* Name & Email */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{["Dein Name", "Deine E-Mail"].map((label, index) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<label className="block font-semibold">{label}</label>
<input
type={index === 0 ? "text" : "email"}
placeholder={index === 0 ? "Max Mustermann" : "max@example.com"}
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<button
type="submit"
className="px-6 py-3 bg-blue-600 text-white text-lg font-semibold rounded-lg shadow-md hover:bg-blue-700 transition-all"
>
📩 Nachricht senden
</button>
</div>
</form>
</div>
</div>
);
};
export default PrivacyComp;

View File

@@ -0,0 +1,98 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const RevocationComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="Widerruf"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</p>
<form className="mt-8 max-w-2xl mx-auto space-y-6">
{/* Name & Email */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{["Dein Name", "Deine E-Mail"].map((label, index) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<label className="block font-semibold">{label}</label>
<input
type={index === 0 ? "text" : "email"}
placeholder={index === 0 ? "Max Mustermann" : "max@example.com"}
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<button
type="submit"
className="px-6 py-3 bg-blue-600 text-white text-lg font-semibold rounded-lg shadow-md hover:bg-blue-700 transition-all"
>
📩 Nachricht senden
</button>
</div>
</form>
</div>
</div>
);};
export default RevocationComp;

View File

@@ -0,0 +1,99 @@
"use client";
import SmallHero from "@/components/Helper/SmallHero";
import React, {useContext, useEffect} from "react";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
import AOS from "aos";
const TermsOfUseComp = () => {
const {theme} = useContext(ThemeContext);
const colors = themeColors[theme];
useEffect(() => {
AOS.init({
duration: 1000,
easing: "ease",
once: true,
anchorPlacement: "top-bottom",
});
}, []);
return (
<div className="overflow-hidden transition-colors duration-500"
style={{backgroundColor: colors.secondaryBg, color: colors.primaryText}}>
{/* Hero Section */}
<div className="mt-[10vh]">
<SmallHero
title="AGB"
subtitle=""
backgroundImage="/images/contact.png"
/>
</div>
{/* Contact Form */}
<div className="mt-16 w-[90%] sm:w-[80%] mx-auto py-12">
<h2 className="text-2xl md:text-3xl font-bold text-center"
data-aos="fade-up"
data-aos-delay="400"
>
Schreib uns eine Nachricht
</h2>
<p data-aos="fade-up" data-aos-delay="600"
className="text-center mt-3 text-[var(--secondary-text)]">
Wir melden uns schnellstmöglich bei dir!
</p>
<form className="mt-8 max-w-2xl mx-auto space-y-6">
{/* Name & Email */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{["Dein Name", "Deine E-Mail"].map((label, index) => (
<div key={index} data-aos="fade-up" data-aos-delay={index * 100}>
<label className="block font-semibold">{label}</label>
<input
type={index === 0 ? "text" : "email"}
placeholder={index === 0 ? "Max Mustermann" : "max@example.com"}
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
))}
</div>
{/* Message */}
<div data-aos="fade-up" data-aos-delay="300">
<label className="block font-semibold">Deine Nachricht</label>
<textarea
rows={4}
placeholder="Schreibe deine Nachricht..."
className="w-full p-3 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 transition"
style={{
backgroundColor: colors.inputFieldBg,
border: `1px solid ${colors.inputBorder}`,
color: colors.primaryText
}}
/>
</div>
{/* Submit Button */}
<div className="text-center" data-aos="fade-up" data-aos-delay="400">
<button
type="submit"
className="px-6 py-3 bg-blue-600 text-white text-lg font-semibold rounded-lg shadow-md hover:bg-blue-700 transition-all"
>
📩 Nachricht senden
</button>
</div>
</form>
</div>
</div>
);
};
export default TermsOfUseComp;

View File

@@ -0,0 +1,114 @@
"use client";
import {usePathname} from "next/navigation";
import {navLinks} from "@/constant/Constant";
import Link from "next/link";
import React, {useContext, useEffect, useState} from "react";
import {HiBars3BottomRight} from "react-icons/hi2";
import {ThemeContext} from "@/components/provider/ThemeProvider";
import {themeColors} from "@/components/Helper/ThemeColors";
type Props = {
openNav: () => void;
};
const Nav = ({openNav}: Props) => {
const [navBg, setNavBg] = useState(false);
const [navHeight, setNavHeight] = useState("h-[10vh]");
const [contentSize, setContentSize] = useState("text-base md:text-lg");
const [buttonSize, setButtonSize] = useState("md:px-6 md:py-2 px-4 py-1 text-sm");
const {theme, toggleTheme} = useContext(ThemeContext);
const colors = themeColors[theme];
const pathname = usePathname();
const navColorClass = theme === "dark" || !navBg ? "text-white" : "text-black";
useEffect(() => {
const handler = () => {
if (window.scrollY >= 90) {
setNavBg(true);
setNavHeight("h-[8vh]");
setContentSize("text-sm md:text-base");
setButtonSize("md:px-5 md:py-1.5 px-3 py-1 text-xs");
} else {
setNavBg(false);
setNavHeight("h-[10vh]");
setContentSize("text-base md:text-lg");
setButtonSize("md:px-6 md:py-2 px-4 py-1 text-sm");
}
};
window.addEventListener("scroll", handler);
return () => window.removeEventListener("scroll", handler);
}, []);
return (
<div
className={`fixed w-full transition-all duration-300 ease-in-out ${navHeight} z-[1000] ${
navBg ? "shadow-md" : ""
}`}
style={{
backgroundColor: navBg ? "var(--nav-bg)" : "transparent",
}}
>
<div
className="flex items-center h-full justify-between w-[90%] xl:w-[80%] mx-auto transition-all duration-300 ease-in-out">
{/* LOGO */}
<h1 className={`${contentSize} font-bold transition-all duration-300 ease-in-out ${navColorClass}`}>
<span className="text-lg md:text-xl text-pink-700">R</span>hein Software
</h1>
{/* Desktop Nav Links */}
<div className="hidden lg:flex items-center space-x-6 transition-all duration-300 ease-in-out">
{navLinks.map((link) => (
<Link href={link.url} key={link.id}>
<p
className={`relative group ${contentSize} uppercase transition-all duration-300 ease-in-out ${
pathname === link.url
? "text-white font-bold"
: "text-gray-300 font-medium"
}`}
>
{link.label}
{pathname !== link.url && (
<span
className="absolute bottom-0 left-0 w-full h-[2px] bg-current transform transition-transform duration-300 origin-right scale-x-0 group-hover:scale-x-100"
/>
)}
</p>
</Link>
))}
</div>
{/* Right Side Buttons */}
<div className="flex items-center space-x-3 transition-all duration-300 ease-in-out">
{/* Contact Button */}
<Link href="/contact">
<button
className={`${buttonSize} text-white font-semibold bg-blue-700 hover:bg-blue-900 transition-all duration-300 ease-in-out rounded-full`}
>
Kontakt
</button>
</Link>
{/* Theme Toggle Button */}
<button
onClick={toggleTheme}
className={`w-7 h-7 flex items-center justify-center rounded-full transition-all duration-300 ease-in-out ${navColorClass}`}
style={{backgroundColor: colors.secondaryBg}}
>
{theme === "dark" ? "🌙" : "☀️"}
</button>
{/* Burger Menu (for mobile) */}
<HiBars3BottomRight
onClick={openNav}
className={`w-6 h-6 cursor-pointer lg:hidden transition-all duration-300 ease-in-out ${navColorClass}`}
/>
</div>
</div>
</div>
);
};
export default Nav;

View File

@@ -0,0 +1,62 @@
import { navLinks } from "@/constant/Constant";
import Link from "next/link";
import React, { useContext } from "react";
import { CgClose } from "react-icons/cg";
import { ThemeContext } from "@/components/provider/ThemeProvider";
import { themeColors } from "@/components/Helper/ThemeColors";
type Props = {
showNav: boolean;
closeNav: () => void;
};
const MobileNav = ({ closeNav, showNav }: Props) => {
const navOpen = showNav ? "translate-y-0 opacity-100" : "-translate-y-20 opacity-0 pointer-events-none";
const { theme, toggleTheme } = useContext(ThemeContext);
const colors = themeColors[theme];
return (
<div className="lg:hidden">
{/* overlay background */}
<div
className={`fixed inset-0 z-[10000] transition-opacity duration-500 ${
showNav ? "opacity-60 bg-black" : "opacity-0 pointer-events-none"
}`}
onClick={closeNav}
/>
{/* nav menu */}
<div
className={`fixed top-0 left-0 w-full z-[10006] transform ${navOpen} transition-all duration-500 ease-in-out text-[var(--primary-text)] shadow-md rounded-b-2xl`}
style={{ backgroundColor: theme === "dark" ? "#2A2A2A" : "#ffffff", color: theme === "dark" ? "#f5f5f5" : "#1a1a1a" }}
>
<div className="flex flex-col items-center justify-center py-8 space-y-4 px-4 relative">
{/* Close icon */}
<CgClose
onClick={closeNav}
className="absolute top-4 right-6 sm:right-8 sm:w-7 sm:h-7 w-6 h-6 cursor-pointer p-1"
style={{ color: colors.primaryText }}
/>
{navLinks.map((link) => (
<Link href={link.url} key={link.id}>
<p className="nav__link uppercase text-[14px] sm:text-[16px] border-b pb-1 border-gray-400 transition-all duration-300 ease-in-out hover:scale-105">
{link.label}
</p>
</Link>
))}
{/* Theme toggle button */}
<button
onClick={toggleTheme}
className="mt-4 w-8 h-8 flex items-center justify-center rounded-full border border-gray-400 transition-all duration-300"
style={{ backgroundColor: colors.secondaryBg, color: colors.primaryText }}
>
{theme === "dark" ? "🌙" : "☀️"}
</button>
</div>
</div>
</div>
);
};
export default MobileNav;

24
components/Navbar/Nav.tsx Normal file
View File

@@ -0,0 +1,24 @@
"use client";
import React, {useState} from "react";
import DesktopNav from "./DesktopNav";
import MobileNav from "./MobileNav";
const Nav = () => {
const [showNav, setShowNav] = useState(false);
const handleNavShow = () => {
setShowNav(true);
};
const handleNavHide = () => {
setShowNav(false);
};
return (
<div>
<DesktopNav openNav={handleNavShow}/>
<MobileNav showNav={showNav} closeNav={handleNavHide}/>
</div>
);
};
export default Nav;

View File

@@ -0,0 +1,54 @@
"use client";
import { createContext, useEffect, useState } from "react";
import Cookies from "js-cookie";
// Define theme options
type ThemeType = "light" | "dark";
export const ThemeContext = createContext<{
theme: ThemeType;
toggleTheme: () => void;
}>({
theme: "light",
toggleTheme: () => {},
});
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
const [theme, setTheme] = useState<ThemeType>("light");
useEffect(() => {
// Get theme from cookies or system preference
const savedTheme = Cookies.get("theme") as ThemeType | undefined;
if (savedTheme === "dark" || savedTheme === "light") {
setTheme(savedTheme);
} else {
// Detect system preference
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
setTheme(prefersDark ? "dark" : "light");
Cookies.set("theme", prefersDark ? "dark" : "light", { expires: 365 });
}
}, []);
// Apply the transition effect when theme changes
useEffect(() => {
document.documentElement.classList.add("transition-theme");
document.documentElement.setAttribute("data-theme", theme);
return () => {
document.documentElement.classList.remove("transition-theme");
};
}, [theme]);
const toggleTheme = () => {
const newTheme: ThemeType = theme === "dark" ? "light" : "dark";
setTheme(newTheme);
Cookies.set("theme", newTheme, { expires: 365 });
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};

17
constant/Constant.ts Normal file
View File

@@ -0,0 +1,17 @@
export const navLinks = [
{
id: 1,
url: '/',
label: 'Home',
},
{
id: 2,
url: '#',
label: 'Über uns',
},
{
id: 3,
url: '/services',
label: 'Leistungen',
}
];

1478
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"name": "website",
"name": "web",
"version": "0.1.0",
"private": true,
"scripts": {
@@ -9,19 +9,28 @@
"lint": "next lint"
},
"dependencies": {
"aos": "^2.3.4",
"framer-motion": "^12.6.5",
"js-cookie": "^3.0.5",
"next": "15.1.7",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"next": "15.2.4"
"react-icons": "^5.4.0",
"react-simple-typewriter": "^5.0.1"
},
"devDependencies": {
"typescript": "^5",
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4.0.17",
"@types/aos": "^3.0.7",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"autoprefixer": "^10.4.21",
"eslint": "^9",
"eslint-config-next": "15.2.4",
"@eslint/eslintrc": "^3"
"eslint-config-next": "15.1.7",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "^5"
}
}

View File

@@ -1,5 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: ["@tailwindcss/postcss"],
plugins: {
tailwindcss: {},
},
};
export default config;

View File

@@ -1 +0,0 @@
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 391 B

View File

@@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
public/images/contact.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

BIN
public/images/dart_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/images/hero.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 KiB

BIN
public/images/home_hero.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
public/images/java_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M0,222.991225 C0,241.223474 14.7785318,256 33.0087747,256 L222.991225,256 C241.223474,256 256,241.221468 256,222.991225 L256,33.0087747 C256,14.7765263 241.221468,0 222.991225,0 L33.0087747,0 C14.7765263,0 0,14.7785318 0,33.0087747 L0,222.991225 Z" fill="#563D7C">
</path>
<path d="M106.157563,113.238095 L106.157563,76.9845938 L138.069328,76.9845938 C141.108559,76.9845938 144.039202,77.2378593 146.861345,77.7443978 C149.683488,78.2509362 152.179961,79.1554557 154.35084,80.4579832 C156.52172,81.7605107 158.258397,83.5695496 159.560924,85.8851541 C160.863452,88.2007585 161.514706,91.1675823 161.514706,94.7857143 C161.514706,101.298352 159.560944,106.001853 155.653361,108.896359 C151.745779,111.790864 146.752832,113.238095 140.67437,113.238095 L106.157563,113.238095 L106.157563,113.238095 Z M72.07493,50.5 L72.07493,205.5 L147.186975,205.5 C154.133788,205.5 160.899594,204.631661 167.484594,202.894958 C174.069594,201.158255 179.93088,198.480877 185.068627,194.862745 C190.206375,191.244613 194.294803,186.577293 197.334034,180.860644 C200.373264,175.143996 201.892857,168.37819 201.892857,160.563025 C201.892857,150.866431 199.541107,142.581033 194.837535,135.706583 C190.133963,128.832132 183.00635,124.020088 173.454482,121.270308 C180.401295,117.941627 185.647508,113.672295 189.193277,108.462185 C192.739047,103.252075 194.511905,96.7395349 194.511905,88.9243697 C194.511905,81.6881057 193.317939,75.6097352 190.929972,70.6890756 C188.542005,65.7684161 185.177193,61.8247114 180.835434,58.8578431 C176.493676,55.8909749 171.283644,53.756309 165.205182,52.4537815 C159.12672,51.151254 152.397096,50.5 145.016106,50.5 L72.07493,50.5 L72.07493,50.5 Z M106.157563,179.015406 L106.157563,136.466387 L143.279412,136.466387 C150.660401,136.466387 156.594049,138.166883 161.080532,141.567927 C165.567016,144.968971 167.810224,150.649353 167.810224,158.609244 C167.810224,162.661552 167.122789,165.990183 165.747899,168.595238 C164.373009,171.200293 162.527789,173.262597 160.212185,174.782213 C157.89658,176.301828 155.219203,177.387252 152.179972,178.038515 C149.140741,178.689779 145.956833,179.015406 142.628151,179.015406 L106.157563,179.015406 L106.157563,179.015406 Z" fill="#FFFFFF">
</path>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 28L4 3H28L26 28L16 31L6 28Z" fill="#1172B8"/>
<path d="M26 5H16V29.5L24 27L26 5Z" fill="#33AADD"/>
<path d="M19.5 17.5H9.5L9 14L17 11.5H9L8.5 8.5H24L23.5 12L17 14.5H23L22 24L16 26L10 24L9.5 19H12.5L13 21.5L16 22.5L19 21.5L19.5 17.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 488 B

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M70.534,69.696 L53.988,53.15 L54.058,172.75 L54.256,178.34 C54.338,180.97 54.826,183.938 55.64,187.014 L186.744,233.244 L219.516,218.724 L219.528,218.684 L70.534,69.696" fill="#00D2B8">
</path>
<path d="M55.64,187.014 L55.648,187.022 C55.64,186.968 55.612,186.908 55.612,186.852 C55.612,186.908 55.62,186.96 55.64,187.014 L55.64,187.014 Z M219.516,218.724 L186.744,233.244 L55.648,187.022 C58.152,196.63 63.696,207.43 69.662,213.336 L112.446,255.876 L207.576,256 L219.528,218.684 L219.516,218.724 L219.516,218.724 Z" fill="#55DDCA">
</path>
<path d="M3.034,130.116 C-1.202,134.638 0.902,143.966 7.722,150.838 L37.14,180.5 L55.64,187.014 C54.826,183.938 54.338,180.97 54.256,178.34 L54.058,172.75 L53.988,53.15 L3.034,130.116 Z" fill="#0081C6">
</path>
<path d="M187.82,54.686 C184.744,53.9 181.794,53.414 179.12,53.33 L173.212,53.126 L53.988,53.142 L219.544,218.684 L219.558,218.684 L234.098,185.88 L187.82,54.686" fill="#0079B3">
</path>
<path d="M187.67,54.654 C187.734,54.668 187.784,54.686 187.826,54.692 L187.82,54.686 C187.784,54.668 187.734,54.668 187.67,54.654 L187.67,54.654 Z M214.118,68.732 C208.11,62.674 197.452,57.168 187.826,54.692 L234.098,185.88 L219.558,218.684 L219.544,218.684 L255.076,207.336 L255.152,109.92 L214.118,68.732 L214.118,68.732 Z" fill="#00A4E4">

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#2396ED" d="M12.342 4.536l.15-.227.262.159.116.083c.28.216.869.768.996 1.684.223-.04.448-.06.673-.06.534 0 .893.124 1.097.227l.105.057.068.045.191.156-.066.2a2.044 2.044 0 01-.47.73c-.29.299-.8.652-1.609.698l-.178.005h-.148c-.37.977-.867 2.078-1.702 3.066a7.081 7.081 0 01-1.74 1.488 7.941 7.941 0 01-2.549.968c-.644.125-1.298.187-1.953.185-1.45 0-2.73-.288-3.517-.792-.703-.449-1.243-1.182-1.606-2.177a8.25 8.25 0 01-.461-2.83.516.516 0 01.432-.516l.068-.005h10.54l.092-.007.149-.016c.256-.034.646-.11.92-.27-.328-.543-.421-1.178-.268-1.854a3.3 3.3 0 01.3-.81l.108-.187zM2.89 5.784l.04.007a.127.127 0 01.077.082l.006.04v1.315l-.006.041a.127.127 0 01-.078.082l-.039.006H1.478a.124.124 0 01-.117-.088l-.007-.04V5.912l.007-.04a.127.127 0 01.078-.083l.039-.006H2.89zm1.947 0l.039.007a.127.127 0 01.078.082l.006.04v1.315l-.007.041a.127.127 0 01-.078.082l-.039.006H3.424a.125.125 0 01-.117-.088L3.3 7.23V5.913a.13.13 0 01.085-.123l.039-.007h1.413zm1.976 0l.039.007a.127.127 0 01.077.082l.007.04v1.315l-.007.041a.127.127 0 01-.078.082l-.039.006H5.4a.124.124 0 01-.117-.088l-.006-.04V5.912l.006-.04a.127.127 0 01.078-.083l.039-.006h1.413zm1.952 0l.039.007a.127.127 0 01.078.082l.007.04v1.315a.13.13 0 01-.085.123l-.04.006H7.353a.124.124 0 01-.117-.088l-.006-.04V5.912l.006-.04a.127.127 0 01.078-.083l.04-.006h1.412zm1.97 0l.039.007a.127.127 0 01.078.082l.006.04v1.315a.13.13 0 01-.085.123l-.039.006H9.322a.124.124 0 01-.117-.088l-.006-.04V5.912l.006-.04a.127.127 0 01.078-.083l.04-.006h1.411zM4.835 3.892l.04.007a.127.127 0 01.077.081l.007.041v1.315a.13.13 0 01-.085.123l-.039.007H3.424a.125.125 0 01-.117-.09l-.007-.04V4.021a.13.13 0 01.085-.122l.039-.007h1.412zm1.976 0l.04.007a.127.127 0 01.077.081l.007.041v1.315a.13.13 0 01-.085.123l-.039.007H5.4a.125.125 0 01-.117-.09l-.006-.04V4.021l.006-.04a.127.127 0 01.078-.082l.039-.007h1.412zm1.953 0c.054 0 .1.037.117.088l.007.041v1.315a.13.13 0 01-.085.123l-.04.007H7.353a.125.125 0 01-.117-.09l-.006-.04V4.021l.006-.04a.127.127 0 01.078-.082l.04-.007h1.412zm0-1.892c.054 0 .1.037.117.088l.007.04v1.316a.13.13 0 01-.085.123l-.04.006H7.353a.124.124 0 01-.117-.088l-.006-.04V2.128l.006-.04a.127.127 0 01.078-.082L7.353 2h1.412z"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="-30.5 0 317 317" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<defs>
<linearGradient x1="3.9517088%" y1="26.9930287%" x2="75.8970734%" y2="52.9192657%" id="linearGradient-1">
<stop stop-color="#000000" offset="0%">
</stop>
<stop stop-color="#000000" stop-opacity="0" offset="100%">
</stop>
</linearGradient>
</defs>
<g>
<polygon fill="#47C5FB" points="157.665785 0.000549356223 0.000549356223 157.665785 48.8009614 206.466197 255.267708 0.000549356223">
</polygon>
<polygon fill="#47C5FB" points="156.567183 145.396793 72.1487107 229.815265 121.132608 279.530905 169.842925 230.820587 255.267818 145.396793">
</polygon>
<polygon fill="#00569E" points="121.133047 279.531124 158.214592 316.61267 255.267159 316.61267 169.842266 230.820807">
</polygon>
<polygon fill="#00B5F8" points="71.5995742 230.364072 120.401085 181.562561 169.842046 230.821136 121.132827 279.531454">

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 -10 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M128.07485,236.074667 L128.07485,236.074667 L175.17885,91.1043048 L80.9708495,91.1043048 L128.07485,236.074667 L128.07485,236.074667 Z" fill="#E24329">
</path>
<path d="M128.07485,236.074423 L80.9708495,91.104061 L14.9557638,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z" fill="#FC6D26">
</path>
<path d="M14.9558857,91.1044267 L14.9558857,91.1044267 L0.641828571,135.159589 C-0.663771429,139.17757 0.766171429,143.57955 4.18438095,146.06275 L128.074971,236.074789 L14.9558857,91.1044267 L14.9558857,91.1044267 Z" fill="#FCA326">
</path>
<path d="M14.9558857,91.1045486 L80.9709714,91.1045486 L52.6000762,3.79026286 C51.1408762,-0.703146667 44.7847619,-0.701927619 43.3255619,3.79026286 L14.9558857,91.1045486 L14.9558857,91.1045486 Z" fill="#E24329">
</path>
<path d="M128.07485,236.074423 L175.17885,91.104061 L241.193935,91.104061 L128.07485,236.074423 L128.07485,236.074423 Z" fill="#FC6D26">
</path>
<path d="M241.193935,91.1044267 L241.193935,91.1044267 L255.507992,135.159589 C256.813592,139.17757 255.38365,143.57955 251.96544,146.06275 L128.07485,236.074789 L241.193935,91.1044267 L241.193935,91.1044267 Z" fill="#FCA326">

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#FC6D26" d="M14.975 8.904L14.19 6.55l-1.552-4.67a.268.268 0 00-.255-.18.268.268 0 00-.254.18l-1.552 4.667H5.422L3.87 1.879a.267.267 0 00-.254-.179.267.267 0 00-.254.18l-1.55 4.667-.784 2.357a.515.515 0 00.193.583l6.78 4.812 6.778-4.812a.516.516 0 00.196-.583z"/><path fill="#E24329" d="M8 14.296l2.578-7.75H5.423L8 14.296z"/><path fill="#FC6D26" d="M8 14.296l-2.579-7.75H1.813L8 14.296z"/><path fill="#FCA326" d="M1.81 6.549l-.784 2.354a.515.515 0 00.193.583L8 14.3 1.81 6.55z"/><path fill="#E24329" d="M1.812 6.549h3.612L3.87 1.882a.268.268 0 00-.254-.18.268.268 0 00-.255.18L1.812 6.549z"/><path fill="#FC6D26" d="M8 14.296l2.578-7.75h3.614L8 14.296z"/><path fill="#FCA326" d="M14.19 6.549l.783 2.354a.514.514 0 01-.193.583L8 14.296l6.188-7.747h.001z"/><path fill="#E24329" d="M14.19 6.549H10.58l1.551-4.667a.267.267 0 01.255-.18c.115 0 .217.073.254.18l1.552 4.667z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 28L4 3H28L26 28L16 31L6 28Z" fill="#E44D26"/>
<path d="M26 5H16V29.5L24 27L26 5Z" fill="#F16529"/>
<path d="M9.5 17.5L8.5 8H24L23.5 11H11.5L12 14.5H23L22 24L16 26L10 24L9.5 19H12.5L13 21.5L16 22.5L19 21.5L19.5 17.5H9.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 475 B

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.0497 8.44062C22.6378 3.32607 19.2566 0 19.2566 0C19.7598 5.28738 13.813 6.53583 12.2189 10.1692C11.1312 12.6485 12.9638 14.8193 16.0475 17.5554C15.7749 16.9494 15.3544 16.3606 14.9288 15.7645C13.4769 13.7313 11.9645 11.6132 16.0497 8.44062Z" fill="#E76F00"/>
<path d="M17.1015 18.677C17.1015 18.677 19.0835 17.0779 17.5139 15.3008C12.1931 9.27186 23.3333 6.53583 23.3333 6.53583C16.5317 9.8125 17.5471 11.7574 19.2567 14.1202C21.0871 16.6538 17.1015 18.677 17.1015 18.677Z" fill="#E76F00"/>
<path d="M22.937 23.4456C29.0423 20.3258 26.2195 17.3278 24.2492 17.7317C23.7662 17.8305 23.5509 17.9162 23.5509 17.9162C23.5509 17.9162 23.7302 17.64 24.0726 17.5204C27.9705 16.1729 30.9682 21.4949 22.8143 23.6028C22.8143 23.6029 22.9088 23.5198 22.937 23.4456Z" fill="#5382A1"/>
<path d="M10.233 19.4969C6.41312 18.9953 12.3275 17.6139 12.3275 17.6139C12.3275 17.6139 10.0307 17.4616 7.20592 18.8043C3.86577 20.3932 15.4681 21.1158 21.474 19.5625C22.0984 19.1432 22.9614 18.7798 22.9614 18.7798C22.9614 18.7798 20.5037 19.2114 18.0561 19.4145C15.0612 19.6612 11.8459 19.7093 10.233 19.4969Z" fill="#5382A1"/>
<path d="M11.6864 22.4758C9.55624 22.2592 10.951 21.2439 10.951 21.2439C5.43898 23.0429 14.0178 25.083 21.7199 22.8682C20.9012 22.5844 20.3806 22.0653 20.3806 22.0653C16.6163 22.7781 14.441 22.7553 11.6864 22.4758Z" fill="#5382A1"/>
<path d="M12.6145 25.6991C10.486 25.4585 11.7295 24.7474 11.7295 24.7474C6.72594 26.1222 14.7729 28.9625 21.1433 26.2777C20.0999 25.8787 19.3528 25.4181 19.3528 25.4181C16.5111 25.9469 15.1931 25.9884 12.6145 25.6991Z" fill="#5382A1"/>
<path d="M25.9387 27.3388C25.9387 27.3388 26.8589 28.0844 24.9252 28.6612C21.2481 29.7566 9.62093 30.0874 6.39094 28.7049C5.22984 28.2082 7.40723 27.5189 8.09215 27.3742C8.80646 27.2219 9.21466 27.2503 9.21466 27.2503C7.9234 26.3558 0.868489 29.0067 5.63111 29.7659C18.6195 31.8372 29.3077 28.8331 25.9387 27.3388Z" fill="#5382A1"/>
<path d="M28 28.9679C27.7869 31.6947 18.7877 32.2683 12.9274 31.8994C9.10432 31.6583 8.33812 31.0558 8.32691 31.047C11.9859 31.6402 18.1549 31.7482 23.1568 30.8225C27.5903 30.0016 28 28.9679 28 28.9679Z" fill="#5382A1"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="a" x1="73.714" y1="910.226" x2="105.452" y2="878.134" gradientTransform="translate(-64.139 -782.556) scale(0.893)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0296d8"/><stop offset="1" stop-color="#8371d9"/></linearGradient><linearGradient id="b" x1="69.813" y1="905.226" x2="102.279" y2="875.745" gradientTransform="translate(-64.139 -782.556) scale(0.893)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#cb55c0"/><stop offset="1" stop-color="#f28e0e"/></linearGradient></defs><title>file_type_kotlin</title><path d="M2,2V30H30v-.047l-6.95-7L16.1,15.946l6.95-7.012L29.938,2Z" style="fill:url(#a)"/><path d="M16.318,2,2,16.318V30h.124L16.132,15.992l-.031-.031L23.05,8.95,29.938,2Z" style="fill:url(#b)"/></svg>

After

Width:  |  Height:  |  Size: 1018 B

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 -196 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M0,118.067201 L20.0767036,118.067201 L20.0767036,65.8336281 C20.0767036,55.5319609 26.8493059,48.0471816 36.5248058,48.0471816 C45.8774864,48.0471816 51.6828689,53.9224284 51.6828689,63.4191233 L51.6828689,118.065347 L71.1946592,118.065347 L71.1946592,65.3496558 C71.1946592,55.1285476 77.8060582,48.0461515 87.4813517,48.0461515 C97.3178485,48.0461515 102.800618,54.0017513 102.800618,64.4645365 L102.800618,118.066171 L122.87693,118.066171 L122.87693,59.5568223 C122.87693,42.4947891 111.830892,31.1468846 94.9790592,31.1468846 C82.6429825,31.1468846 72.4849047,37.7463386 68.371228,48.2894768 L67.887453,48.2894768 C64.74306,37.3439555 56.1158974,31.1468846 44.022761,31.1468846 C32.4124087,31.1468846 23.3821348,37.6659856 19.6730143,47.5652696 L19.2698822,47.5652696 L19.2698822,32.7566231 L0,32.7566231 L0,118.067201 L0,118.067201 Z M166.822061,104.304916 C158.114194,104.304916 152.309224,99.8783716 152.309224,92.8763285 C152.309224,86.1159624 157.872492,81.7698951 167.547785,81.1260409 L187.301484,79.9188091 L187.301484,86.4379101 C187.301484,96.7395773 178.190505,104.304916 166.822061,104.304916 L166.822061,104.304916 Z M160.774977,119.435469 C171.740309,119.435469 182.464147,113.72134 187.382808,104.46591 L187.78594,104.46591 L187.78594,118.067407 L207.136527,118.067407 L207.136527,59.3149391 C207.136527,42.1723469 193.349208,30.9853545 172.144474,30.9853545 C150.374805,30.9853545 136.749928,42.413818 135.862381,58.3486428 L154.487244,58.3486428 C155.777283,51.2662466 161.824367,46.6787082 171.338457,46.6787082 C181.255659,46.6787082 187.302743,51.8295417 187.302743,60.7629415 L187.302743,66.8796594 L164.726026,68.1673678 C143.924403,69.4550761 132.233552,78.5495939 132.233552,93.6804766 C132.233552,109.052418 144.247016,119.435469 160.77541,119.435469 L160.774977,119.435469 Z M295.265169,63.1780643 C293.894507,45.2307058 279.945903,30.9853545 257.371043,30.9853545 C232.538306,30.9853545 216.411785,48.1279467 216.411785,75.4102639 C216.411785,103.097025 232.537274,119.75482 257.53204,119.75482 C278.979715,119.75482 293.733634,107.19956 295.345667,88.1245815 L276.398192,88.1245815 C274.543755,97.7823945 267.932232,103.577082 257.773329,103.577082 C245.034141,103.577082 236.810709,93.2754151 236.810709,75.4082036 C236.810709,57.8632282 244.954055,47.2393249 257.612332,47.2393249 C268.335757,47.2393249 274.705248,54.08025 276.3179,63.1747678 L295.265375,63.1747678 L295.265169,63.1780643 Z M357.271674,0 C323.328164,0 302.041486,23.0983981 302.041486,60.0401765 C302.041486,96.9819549 323.3261,120 357.271674,120 C391.134685,120 412.421363,96.9819549 412.421363,60.0401765 C412.421363,23.0983981 391.136749,0 357.271674,0 Z M357.271674,17.7060934 C377.992799,17.7060934 391.215184,34.1244785 391.215184,60.0397644 C391.215184,85.8742853 377.992386,102.293082 357.271674,102.293082 C336.470051,102.293082 323.328164,85.8746974 323.328164,60.0397644 C323.328164,34.1248905 336.470464,17.7060934 357.271674,17.7060934 Z M420.890212,85.3921673 C421.777119,106.801092 439.353871,119.999588 466.12208,119.999588 C494.261446,119.999588 512,106.15662 512,84.1044589 C512,66.8009546 502.002093,57.0625826 478.378484,51.67069 L464.994276,48.6123311 C450.723141,45.2321481 444.837466,40.7251687 444.837466,32.9989183 C444.837466,23.3411054 453.706537,16.9025634 466.84863,16.9025634 C480.152133,16.9025634 489.262286,23.4216644 490.230332,34.2866267 L510.064735,34.2866267 C509.58096,13.8442045 492.649207,0.000618100029 467.010453,0.000618100029 C441.692661,0.000618100029 423.712611,13.9239394 423.712611,34.5276857 C423.712611,51.1069828 433.871721,61.408856 455.317538,66.3186306 L470.394896,69.8599317 C485.069143,73.3206737 491.035522,78.1494772 491.035522,86.5195818 C491.035522,96.1773947 481.279524,103.098879 467.251329,103.098879 C453.060898,103.098879 442.338093,96.0970417 441.048054,85.3927854 L420.891244,85.3927854 L420.890212,85.3921673 Z" fill="#000000" fill-rule="nonzero">
</path>
</g>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 7.5C0 3.35786 3.35786 0 7.5 0C11.6421 0 15 3.35786 15 7.5C15 10.087 13.6902 12.3681 11.6975 13.7163L4.90687 4.20942C4.78053 4.03255 4.5544 3.95756 4.34741 4.02389C4.14042 4.09022 4 4.28268 4 4.50004V12H5V6.06027L10.8299 14.2221C9.82661 14.7201 8.696 15 7.5 15C3.35786 15 0 11.6421 0 7.5ZM10 10V4H11V10H10Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 603 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 512 512"><path d="m354.5 441.9-32.8-9.9V80l32.8-9.9zM92 143.7 288.9 32.8V479L92 368.1zm32.8 202.6 32.8 16.5V149.2l-32.8 16.5zm295.3-233.8-32.8 4.1v278.8l32.8 4.1z" style="fill:#fff;stroke:#000;stroke-miterlimit:10"/><path d="M321.7 466.3v12.8c0 18.2-14.7 32.8-32.8 32.8-5.7 0-11.1-1.5-16.1-4.2l-197-110.8c-10.3-5.8-16.7-16.8-16.7-28.6V143.7c0-11.8 6.4-22.8 16.7-28.6l197-110.9c15.8-8.9 35.8-3.3 44.7 12.5 2.7 4.9 4.2 10.5 4.2 16.1v12.8l23.4-7c17.4-5.2 35.7 4.7 40.9 22 .9 3.1 1.4 6.2 1.4 9.4v13.3l28.7-3.6c18-2.3 34.4 10.6 36.6 28.5.1 1.4.2 2.7.2 4.1v287c0 18.2-14.7 32.8-32.8 32.8-1.4 0-2.7-.1-4.1-.2l-28.7-3.6v13.3c0 18.2-14.7 32.8-32.8 32.8-3.2 0-6.4-.5-9.4-1.4zm0-34.3 32.8 9.9V70.1L321.7 80zm65.6-315.4v278.8l32.8 4.1v-287zM92 143.7v224.4L288.9 479V32.8zm32.8 22 32.8-16.5v213.6l-32.8-16.5z" style="fill:#333"/></svg>

After

Width:  |  Height:  |  Size: 896 B

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<circle cx="512" cy="512" r="512" style="fill:#e57000"/>
<path d="M512 497.8 342.7 311.6c6.6-6.6 14.2-11.7 22.9-15.5 8.7-3.8 18.1-5.7 28.1-5.7 10.7.1 20.4 2.2 29.3 6.3 8.9 4.1 16.6 9.8 23.1 17l65.8 71.9 65.4-71.9c6.8-7.2 14.7-12.9 23.6-17 9-4.1 18.7-6.2 29.2-6.3 10 .1 19.4 2 28.1 5.7 8.7 3.8 16.4 8.9 22.9 15.5L512 497.8m0 28.4L342.7 712.4c6.6 6.6 14.2 11.7 22.9 15.5 8.7 3.8 18.1 5.7 28.1 5.7 10.5-.1 20.2-2.2 29.2-6.3s16.9-9.8 23.6-17l65.4-71.9 65.8 71.9c6.5 7.2 14.2 12.9 23.1 17 8.9 4.1 18.6 6.2 29.3 6.3 10-.1 19.4-2 28.1-5.7 8.7-3.8 16.4-8.9 22.9-15.5L512 526.2M497.8 512 370.3 372.2c-7.4-7.9-16-14.1-25.9-18.7-9.8-4.5-20.5-6.8-31.9-6.9-11 .1-21.3 2.2-30.8 6.3-9.6 4.1-17.9 9.8-25.1 16.9L385.9 512 256.5 654.2c7.2 7.4 15.6 13.2 25.1 17.4 9.6 4.2 19.8 6.3 30.8 6.3 11.5-.1 22.2-2.4 32.1-6.9 9.9-4.5 18.5-10.8 25.7-18.7L497.8 512m28.4 0 127.5 140.3c7.2 7.9 15.8 14.1 25.7 18.7 9.9 4.5 20.6 6.8 32.1 6.9 11-.1 21.3-2.2 30.8-6.3 9.6-4.2 17.9-9.9 25.1-17.4L638.1 512l129.4-142.2c-7.2-7.2-15.6-12.8-25.1-16.9-9.6-4.1-19.8-6.2-30.8-6.3-11.4.1-22.1 2.4-31.9 6.9-9.8 4.5-18.5 10.8-25.9 18.7L526.2 512" style="fill:#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h32v32H0z"/>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>file_type_typescript_official</title><rect x="2" y="2" width="28" height="28" rx="1.312" style="fill:#3178c6"/><path d="M18.245,23.759v3.068a6.492,6.492,0,0,0,1.764.575,11.56,11.56,0,0,0,2.146.192,9.968,9.968,0,0,0,2.088-.211,5.11,5.11,0,0,0,1.735-.7,3.542,3.542,0,0,0,1.181-1.266,4.469,4.469,0,0,0,.186-3.394,3.409,3.409,0,0,0-.717-1.117,5.236,5.236,0,0,0-1.123-.877,12.027,12.027,0,0,0-1.477-.734q-.6-.249-1.08-.484a5.5,5.5,0,0,1-.813-.479,2.089,2.089,0,0,1-.516-.518,1.091,1.091,0,0,1-.181-.618,1.039,1.039,0,0,1,.162-.571,1.4,1.4,0,0,1,.459-.436,2.439,2.439,0,0,1,.726-.283,4.211,4.211,0,0,1,.956-.1,5.942,5.942,0,0,1,.808.058,6.292,6.292,0,0,1,.856.177,5.994,5.994,0,0,1,.836.3,4.657,4.657,0,0,1,.751.422V13.9a7.509,7.509,0,0,0-1.525-.4,12.426,12.426,0,0,0-1.9-.129,8.767,8.767,0,0,0-2.064.235,5.239,5.239,0,0,0-1.716.733,3.655,3.655,0,0,0-1.171,1.271,3.731,3.731,0,0,0-.431,1.845,3.588,3.588,0,0,0,.789,2.34,6,6,0,0,0,2.395,1.639q.63.26,1.175.509a6.458,6.458,0,0,1,.942.517,2.463,2.463,0,0,1,.626.585,1.2,1.2,0,0,1,.23.719,1.1,1.1,0,0,1-.144.552,1.269,1.269,0,0,1-.435.441,2.381,2.381,0,0,1-.726.292,4.377,4.377,0,0,1-1.018.105,5.773,5.773,0,0,1-1.969-.35A5.874,5.874,0,0,1,18.245,23.759Zm-5.154-7.638h4V13.594H5.938v2.527H9.92V27.375h3.171Z" style="fill:#ffffff;fill-rule:evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 16C30 23.728 23.735 30 16 30C8.265 30 2 23.728 2 16C2 8.265 8.265 2 16 2C23.735 2 30 8.265 30 16Z" fill="#E95420"/>
<path d="M6.82154 14.1563C5.81185 14.1563 5 14.9865 5 16.0035C5 17.0205 5.81867 17.8507 6.82154 17.8507C7.82442 17.8507 8.64309 17.0205 8.64309 16.0035C8.64309 14.9795 7.82442 14.1563 6.82154 14.1563ZM19.8316 22.5482C18.9583 23.0602 18.665 24.1879 19.163 25.0734C19.6679 25.959 20.7799 26.2634 21.6531 25.7514C22.5264 25.2395 22.8197 24.1118 22.3217 23.2262C21.8101 22.3476 20.698 22.0432 19.8316 22.5482ZM10.7785 16.0035C10.7785 14.177 11.6722 12.565 13.0434 11.5896L11.7131 9.32725C10.1167 10.4065 8.93645 12.06 8.43842 13.9902C9.01149 14.4676 9.37989 15.194 9.37989 16.0035C9.37989 16.8129 9.01149 17.5393 8.43842 18.0167C8.92962 19.9469 10.1167 21.6004 11.7131 22.6797L13.0434 20.4174C11.6722 19.4419 10.7785 17.8299 10.7785 16.0035ZM16.0998 10.6071C18.8833 10.6071 21.1619 12.7657 21.4007 15.5261L24 15.4846C23.8704 13.4506 22.9971 11.6241 21.6463 10.282C20.9504 10.5449 20.1522 10.5034 19.4632 10.1021C18.7673 9.69393 18.3375 9.01593 18.2147 8.26875C17.5393 8.08195 16.8298 7.97817 16.0998 7.97817C14.8377 7.97817 13.6506 8.27566 12.5932 8.80838L13.8621 11.1053C14.5375 10.787 15.3016 10.6071 16.0998 10.6071ZM16.0998 21.3998C15.3016 21.3998 14.5375 21.2199 13.8553 20.9017L12.5864 23.1985C13.6438 23.7313 14.8377 24.0287 16.093 24.0287C16.823 24.0287 17.5325 23.925 18.2079 23.7382C18.3239 22.9979 18.7605 22.313 19.4564 21.9048C20.1454 21.4966 20.9504 21.462 21.6395 21.7249C22.9835 20.3828 23.8636 18.5563 23.9932 16.5223L21.3939 16.4808C21.1619 19.2343 18.8833 21.3998 16.0998 21.3998ZM19.8248 9.45178C20.698 9.96374 21.8101 9.65933 22.3149 8.77378C22.8197 7.88824 22.5196 6.76054 21.6463 6.24859C20.7731 5.73663 19.661 6.04104 19.1562 6.92659C18.6582 7.81213 18.9583 8.93983 19.8248 9.45178Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 128 B

View File

@@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>

Before

Width:  |  Height:  |  Size: 385 B

11
tailwind.config.ts Normal file
View File

@@ -0,0 +1,11 @@
import type { Config } from "tailwindcss";
export default {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {},
plugins: [],
} satisfies Config;

View File

@@ -18,7 +18,9 @@
"name": "next"
}
],
"baseUrl": ".",
"paths": {
"@/components/*": ["./components/*"],
"@/*": ["./*"]
}
},