From 14ec81f4c24080a36c88939a8675f574ef845eda Mon Sep 17 00:00:00 2001 From: Thatsaphorn Atchariyaphap Date: Fri, 11 Apr 2025 19:08:43 +0000 Subject: [PATCH] Merge branch 'homepage-refactoring' into 'dev' Refactor the whole page. See merge request rheinsw/website!26 --- app/(root)/layout.tsx | 2 +- app/contact/layout.tsx | 2 +- app/legal/layout.tsx | 2 +- app/services/layout.tsx | 2 +- components/Footer/Footer.tsx | 97 ++++++++++++++++ components/Home/About/About.tsx | 118 +++++++++++-------- components/Home/Contact/ContactCTA.tsx | 86 +++++++------- components/Home/Footer/Footer.tsx | 96 ---------------- components/Home/Hero/Hero.tsx | 76 ++++++++----- components/Home/Home.tsx | 27 ++--- components/Home/HomeServices.tsx | 115 +++++++++++++++++++ components/Home/TechStack.tsx | 150 +++++++++++++++++++++++++ components/Navbar/DesktopNav.tsx | 10 +- package-lock.json | 43 +++++++ package.json | 1 + public/images/svg/bootstrap.svg | 10 ++ public/images/svg/css.svg | 6 + public/images/svg/dart.svg | 18 +++ public/images/svg/debian.svg | 4 + public/images/svg/docker.svg | 2 + public/images/svg/flutter.svg | 24 ++++ public/images/svg/gitlab-ci.svg | 20 ++++ public/images/svg/gitlab.svg | 2 + public/images/svg/html.svg | 6 + public/images/svg/java.svg | 11 ++ public/images/svg/kotlin.svg | 2 + public/images/svg/macos.svg | 8 ++ public/images/svg/nextjs.svg | 4 + public/images/svg/outline.svg | 1 + public/images/svg/proxmox.svg | 5 + public/images/svg/spring.svg | 8 ++ public/images/svg/typescript.svg | 2 + public/images/svg/ubuntu.svg | 5 + 33 files changed, 728 insertions(+), 237 deletions(-) create mode 100644 components/Footer/Footer.tsx delete mode 100644 components/Home/Footer/Footer.tsx create mode 100644 components/Home/HomeServices.tsx create mode 100644 components/Home/TechStack.tsx create mode 100644 public/images/svg/bootstrap.svg create mode 100644 public/images/svg/css.svg create mode 100644 public/images/svg/dart.svg create mode 100644 public/images/svg/debian.svg create mode 100644 public/images/svg/docker.svg create mode 100644 public/images/svg/flutter.svg create mode 100644 public/images/svg/gitlab-ci.svg create mode 100644 public/images/svg/gitlab.svg create mode 100644 public/images/svg/html.svg create mode 100644 public/images/svg/java.svg create mode 100644 public/images/svg/kotlin.svg create mode 100644 public/images/svg/macos.svg create mode 100644 public/images/svg/nextjs.svg create mode 100644 public/images/svg/outline.svg create mode 100644 public/images/svg/proxmox.svg create mode 100644 public/images/svg/spring.svg create mode 100644 public/images/svg/typescript.svg create mode 100644 public/images/svg/ubuntu.svg diff --git a/app/(root)/layout.tsx b/app/(root)/layout.tsx index 99a74fe..4a3ccb9 100644 --- a/app/(root)/layout.tsx +++ b/app/(root)/layout.tsx @@ -2,7 +2,7 @@ import type {Metadata} from "next"; import "../globals.css"; import Nav from "@/components/Navbar/Nav"; -import Footer from "@/components/Home/Footer/Footer"; +import Footer from "@/components/Footer/Footer"; import {ThemeProvider} from "@/components/provider/ThemeProvider"; import React from "react"; import {cookies} from "next/headers"; diff --git a/app/contact/layout.tsx b/app/contact/layout.tsx index 99a74fe..4a3ccb9 100644 --- a/app/contact/layout.tsx +++ b/app/contact/layout.tsx @@ -2,7 +2,7 @@ import type {Metadata} from "next"; import "../globals.css"; import Nav from "@/components/Navbar/Nav"; -import Footer from "@/components/Home/Footer/Footer"; +import Footer from "@/components/Footer/Footer"; import {ThemeProvider} from "@/components/provider/ThemeProvider"; import React from "react"; import {cookies} from "next/headers"; diff --git a/app/legal/layout.tsx b/app/legal/layout.tsx index 99a74fe..4a3ccb9 100644 --- a/app/legal/layout.tsx +++ b/app/legal/layout.tsx @@ -2,7 +2,7 @@ import type {Metadata} from "next"; import "../globals.css"; import Nav from "@/components/Navbar/Nav"; -import Footer from "@/components/Home/Footer/Footer"; +import Footer from "@/components/Footer/Footer"; import {ThemeProvider} from "@/components/provider/ThemeProvider"; import React from "react"; import {cookies} from "next/headers"; diff --git a/app/services/layout.tsx b/app/services/layout.tsx index 99a74fe..4a3ccb9 100644 --- a/app/services/layout.tsx +++ b/app/services/layout.tsx @@ -2,7 +2,7 @@ import type {Metadata} from "next"; import "../globals.css"; import Nav from "@/components/Navbar/Nav"; -import Footer from "@/components/Home/Footer/Footer"; +import Footer from "@/components/Footer/Footer"; import {ThemeProvider} from "@/components/provider/ThemeProvider"; import React from "react"; import {cookies} from "next/headers"; diff --git a/components/Footer/Footer.tsx b/components/Footer/Footer.tsx new file mode 100644 index 0000000..3bcb1df --- /dev/null +++ b/components/Footer/Footer.tsx @@ -0,0 +1,97 @@ +'use client'; + +import React from 'react'; +import Link from 'next/link'; +import {motion} from 'framer-motion'; + +const Footer = () => { + return ( + +
+
+ {/* Logo and description */} +
+

+ Rhein Software +

+
+ + {/* Informationen */} +
+

Informationen

+
    +
  • + +

    + Kontakt +

    + +
  • +
  • + +

    + Zahlung und Versand +

    + +
  • +
+
+ + {/* Rechtliches */} +
+

Rechtliches

+
    +
  • + +

    + AGB +

    + +
  • +
  • + +

    + Widerruf +

    + +
  • +
  • + +

    + Datenschutz +

    + +
  • +
  • + +

    + Impressum +

    + +
  • +
+
+
+ + {/* Bottom Section */} +
+

+ © 2025 Rhein Software Development. All rights reserved. +

+
+
+
+ ); +}; + +export default Footer; diff --git a/components/Home/About/About.tsx b/components/Home/About/About.tsx index 057946f..a1c299e 100644 --- a/components/Home/About/About.tsx +++ b/components/Home/About/About.tsx @@ -1,57 +1,81 @@ -import Image from "next/image"; -import React from "react"; +'use client'; + +import Link from 'next/link'; +import {FiArrowRight} from 'react-icons/fi'; +import {motion} from 'framer-motion'; const About = () => { - return ( -
-

- Über Uns -

-
-
- image +
+
+ {/* Title */} + + Über uns + + + -
-
-

+ + 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. + + + + 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. + +

+ + {/* CTA Button */} + - Wir sind Rhein Software Development – ein Team, das sich auf maßgeschneiderte Softwarelösungen - und zuverlässige digitale Services spezialisiert hat. Unser Fokus liegt darauf, Software zu - entwickeln, die nicht nur funktioniert, sondern langfristig überzeugt. -

-

- Von der ersten Idee bis zur fertigen Anwendung begleiten wir Unternehmen, Startups und - individuelle Projekte mit einer klaren Strategie und einem hohen Anspruch an Qualität. Wir - glauben daran, dass gute Software nicht kompliziert sein muss – sondern effizient, intuitiv und - zukunftssicher. -

+ + + +
-
+ ); }; diff --git a/components/Home/Contact/ContactCTA.tsx b/components/Home/Contact/ContactCTA.tsx index 4367417..ab8403c 100644 --- a/components/Home/Contact/ContactCTA.tsx +++ b/components/Home/Contact/ContactCTA.tsx @@ -1,46 +1,56 @@ -import Link from "next/link"; -import {useContext} from "react"; -import {ThemeContext} from "@/components/provider/ThemeProvider"; -import {themeColors} from "@/components/Helper/ThemeColors"; +'use client'; + +import Link from 'next/link'; +import { motion } from 'framer-motion'; +import { FiArrowRight } from 'react-icons/fi'; const ContactCTA = () => { - const {theme} = useContext(ThemeContext); - const colors = themeColors[theme]; - return ( -
-

- Interesse geweckt? -

-

- Lass uns über dein Projekt sprechen. Wir freuen uns darauf, - deine Ideen in die Realität umzusetzen. -

- - - -
+ Interesse geweckt? + + + {/* Description */} + + Lass uns über dein Projekt sprechen. Wir freuen uns darauf, deine Ideen in die Realität umzusetzen. + + + {/* CTA Button */} + + + + + +
+ ); }; diff --git a/components/Home/Footer/Footer.tsx b/components/Home/Footer/Footer.tsx deleted file mode 100644 index 1adc73d..0000000 --- a/components/Home/Footer/Footer.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React from "react"; -import Link from "next/link"; - -const Footer = () => { - - return ( -
-
-
- {/* Logo and description */} -
- {/* Logo */} -

- Rhein Software -

-
- {/* Our information links */} -
-

- Informationen -

-
    -
  • - -

    Kontakt

    - -
  • -
  • - -

    Zahlung und - Versand

    - -
  • -
-
- {/* About us links */} -
-

- Rechtliches -

-
    -
  • - -

    AGB

    - -
  • -
  • - -

    Widerruf

    - -
  • -
  • - -

    Datenschutz

    - -
  • -
  • - -

    Impressum

    - -
  • -
-
-
- {/* Bottom Section */} -
-

- Copyright © 2025 Rhein Software Development. All rights reserved -

-
-
-
- ); -}; - -export default Footer; diff --git a/components/Home/Hero/Hero.tsx b/components/Home/Hero/Hero.tsx index 588be07..2ecf7d7 100644 --- a/components/Home/Hero/Hero.tsx +++ b/components/Home/Hero/Hero.tsx @@ -1,15 +1,16 @@ -"use client"; +'use client'; -import Image from "next/image"; -import {Typewriter} from "react-simple-typewriter"; +import Image from 'next/image'; +import {Typewriter} from 'react-simple-typewriter'; +import {motion} from 'framer-motion'; const Hero = () => { return (
{/* Background Image */} @@ -25,56 +26,71 @@ const Hero = () => {
- {/* Main Content */} + {/* Main content */}
{/* Text Content */}
-

Rhein-Software Development -

+ -

Digitale Lösungen für dein Unternehmen. -

+ -

-

+
{/* Floating Image */} -
- hero graphic -
+ + hero graphic + +
diff --git a/components/Home/Home.tsx b/components/Home/Home.tsx index 96deca3..5785fd0 100644 --- a/components/Home/Home.tsx +++ b/components/Home/Home.tsx @@ -1,38 +1,25 @@ -"use client"; +'use client'; -import React, {useEffect} from "react"; +import React from "react"; import Hero from "./Hero/Hero"; -import AOS from "aos"; -import "aos/dist/aos.css"; import About from "@/components/Home/About/About"; -import Offer from "@/components/Home/Offer/Offer"; 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 = () => { - useEffect(() => { - const initAOS = async () => { - await import("aos"); - AOS.init({ - duration: 1000, - easing: "ease", - once: true, - anchorPlacement: "top-bottom", - }); - }; - initAOS(); - }, []); - return (
- + - + +
); }; diff --git a/components/Home/HomeServices.tsx b/components/Home/HomeServices.tsx new file mode 100644 index 0000000..0aa0349 --- /dev/null +++ b/components/Home/HomeServices.tsx @@ -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: , + 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: , + 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: , + 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: , + 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 ( +
+
+ {/* Heading */} + + Leistungen + + + + + {/* Service Cards */} +
+ {services.map((service, index) => ( + +
{service.icon}
+

+ {service.title} +

+

+ {service.description} +

+
+ ))} +
+ + {/* Weitere Leistungen */} + + + Weitere Leistungen + + +
+
+ ); +}; + +export default HomeServices; diff --git a/components/Home/TechStack.tsx b/components/Home/TechStack.tsx new file mode 100644 index 0000000..031c768 --- /dev/null +++ b/components/Home/TechStack.tsx @@ -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 ( +
+
+ + Technologien + + + + + + Mit diesen Technologien realisieren wir moderne, leistungsstarke Softwarelösungen. + + + {/* Row 1 */} +
+ {techStack.row1.map((group, index) => ( + + ))} +
+ + {/* Row 2 */} +
+ {techStack.row2.map((group, index) => ( + + ))} +
+
+
+ ); +}; + +const TechCard = ({ + group, + delay, + }: { + group: { category: string; items: { id: string; label: string }[] }; + delay: number; +}) => ( + +

+ {group.category} +

+
+ {group.items.map(({id, label}) => ( +
+ {label} + + {label} + +
+ ))} +
+
+); + +export default TechStack; diff --git a/components/Navbar/DesktopNav.tsx b/components/Navbar/DesktopNav.tsx index 9ed9f06..4761101 100644 --- a/components/Navbar/DesktopNav.tsx +++ b/components/Navbar/DesktopNav.tsx @@ -63,12 +63,18 @@ const Nav = ({openNav}: Props) => { {navLinks.map((link) => (

+ }`} + > {link.label} + {pathname !== link.url && ( + + )}

))} diff --git a/package-lock.json b/package-lock.json index 1023b89..c27636f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "aos": "^2.3.4", + "framer-motion": "^12.6.5", "js-cookie": "^3.0.5", "next": "15.1.7", "react": "^19.0.0", @@ -3455,6 +3456,33 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "12.6.5", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.6.5.tgz", + "integrity": "sha512-MKvnWov0paNjvRJuIy6x418w23tFqRfS6CXHhZrCiSEpXVlo/F+usr8v4/3G6O0u7CpsaO1qop+v4Ip7PRCBqQ==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.6.5", + "motion-utils": "^12.6.5", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -4824,6 +4852,21 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/motion-dom": { + "version": "12.6.5", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.6.5.tgz", + "integrity": "sha512-jpM9TQLXzYMWMJ7Ec7sAj0iis8oIuu6WvjI3yNKJLdrZyrsI/b2cRInDVL8dCl683zQQq19DpL9cSMP+k8T1NA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.6.5" + } + }, + "node_modules/motion-utils": { + "version": "12.6.5", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.6.5.tgz", + "integrity": "sha512-IsOeKsOF+FWBhxQEDFBO6ZYC8/jlidmVbbLpe9/lXSA9j9kzGIMUuIBx2SZY+0reAS0DjZZ1i7dJp4NHrjocPw==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/package.json b/package.json index 379afc6..d828a0c 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "aos": "^2.3.4", + "framer-motion": "^12.6.5", "js-cookie": "^3.0.5", "next": "15.1.7", "react": "^19.0.0", diff --git a/public/images/svg/bootstrap.svg b/public/images/svg/bootstrap.svg new file mode 100644 index 0000000..fe085fe --- /dev/null +++ b/public/images/svg/bootstrap.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/css.svg b/public/images/svg/css.svg new file mode 100644 index 0000000..b7f50fd --- /dev/null +++ b/public/images/svg/css.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/images/svg/dart.svg b/public/images/svg/dart.svg new file mode 100644 index 0000000..4a0a1dc --- /dev/null +++ b/public/images/svg/dart.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/debian.svg b/public/images/svg/debian.svg new file mode 100644 index 0000000..46cb9a9 --- /dev/null +++ b/public/images/svg/debian.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/images/svg/docker.svg b/public/images/svg/docker.svg new file mode 100644 index 0000000..e1e413e --- /dev/null +++ b/public/images/svg/docker.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/images/svg/flutter.svg b/public/images/svg/flutter.svg new file mode 100644 index 0000000..30c0275 --- /dev/null +++ b/public/images/svg/flutter.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/gitlab-ci.svg b/public/images/svg/gitlab-ci.svg new file mode 100644 index 0000000..24e3ea0 --- /dev/null +++ b/public/images/svg/gitlab-ci.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/gitlab.svg b/public/images/svg/gitlab.svg new file mode 100644 index 0000000..71a666d --- /dev/null +++ b/public/images/svg/gitlab.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/images/svg/html.svg b/public/images/svg/html.svg new file mode 100644 index 0000000..75b1979 --- /dev/null +++ b/public/images/svg/html.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/public/images/svg/java.svg b/public/images/svg/java.svg new file mode 100644 index 0000000..9f0f599 --- /dev/null +++ b/public/images/svg/java.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/kotlin.svg b/public/images/svg/kotlin.svg new file mode 100644 index 0000000..800a6d1 --- /dev/null +++ b/public/images/svg/kotlin.svg @@ -0,0 +1,2 @@ + +file_type_kotlin \ No newline at end of file diff --git a/public/images/svg/macos.svg b/public/images/svg/macos.svg new file mode 100644 index 0000000..c47eea1 --- /dev/null +++ b/public/images/svg/macos.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/nextjs.svg b/public/images/svg/nextjs.svg new file mode 100644 index 0000000..338a4c1 --- /dev/null +++ b/public/images/svg/nextjs.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/images/svg/outline.svg b/public/images/svg/outline.svg new file mode 100644 index 0000000..5a2a213 --- /dev/null +++ b/public/images/svg/outline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/svg/proxmox.svg b/public/images/svg/proxmox.svg new file mode 100644 index 0000000..bf60bdf --- /dev/null +++ b/public/images/svg/proxmox.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/public/images/svg/spring.svg b/public/images/svg/spring.svg new file mode 100644 index 0000000..4f70f0b --- /dev/null +++ b/public/images/svg/spring.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/public/images/svg/typescript.svg b/public/images/svg/typescript.svg new file mode 100644 index 0000000..4bf36f8 --- /dev/null +++ b/public/images/svg/typescript.svg @@ -0,0 +1,2 @@ + +file_type_typescript_official \ No newline at end of file diff --git a/public/images/svg/ubuntu.svg b/public/images/svg/ubuntu.svg new file mode 100644 index 0000000..c08ad24 --- /dev/null +++ b/public/images/svg/ubuntu.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file