diff --git a/src/components/mainViews/Contact.jsx b/src/components/mainViews/Contact.jsx
index 43fea43..5822bb8 100644
--- a/src/components/mainViews/Contact.jsx
+++ b/src/components/mainViews/Contact.jsx
@@ -1,9 +1,60 @@
-import React from 'react'
+import React from "react";
+import "../../css/Home.css";
+import LangSelect from "../LangSelect";
+import Mail from "../Mail";
+import Switch from "../Switch";
+import Navigation from "../Navigation";
+import LinkedInIcon from "../../assets/icons/socials/linkedin.svg?react";
+import GitHubIcon from "../../assets/icons/socials/square-github.svg?react";
+import Location from "../Location";
+import "animate.css";
+import { useState } from "react";
+import "../../css/GridContainer.css";
+import ContactTile from "../subComponents/Contact/ContactTile";
const Contact = () => {
- return (
-
Contact
- )
-}
+ const social = (url) => () => {
+ window.open(url, "_blank", "noopener,noreferrer");
+ };
+ const [hoverAnimation, setHoverAnimation] = useState("animate__headShake");
-export default Contact
\ No newline at end of file
+ const handleMouseEnter = (setAnimation) => {
+ setAnimation(hoverAnimation); // Trigger hover animation
+ };
+
+ const handleAnimationEnd = (setAnimation) => {
+ setAnimation(""); // Clear animation to prevent re-triggering
+ };
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Contact;
diff --git a/src/components/subComponents/Contact/ContactTile.jsx b/src/components/subComponents/Contact/ContactTile.jsx
new file mode 100644
index 0000000..92a1ac2
--- /dev/null
+++ b/src/components/subComponents/Contact/ContactTile.jsx
@@ -0,0 +1,98 @@
+import React, { useState } from "react";
+import "../../../css/ContactTile.css";
+import { useTheme } from "../../../Context/ThemeContext";
+import { useLang } from "../../../Context/LangContext";
+
+const ContactTileTiltFlip = ({
+ initialAnimation,
+ onMouseEnter,
+ onAnimationEnd,
+}) => {
+ const [animation, setAnimation] = useState(initialAnimation);
+ const { colormode } = useTheme();
+ const { language } = useLang();
+ const [isFlipped, setIsFlipped] = useState(false);
+ const [tiltStyle, setTiltStyle] = useState({});
+
+ const handleMouseMove = (e) => {
+ const rect = e.currentTarget.getBoundingClientRect();
+ const x = e.clientX - rect.left - rect.width / 2;
+ const y = e.clientY - rect.top - rect.height / 2;
+ const tiltX = (y / rect.height) * 40; // Harter Tilt
+ const tiltY = -(x / rect.width) * 40;
+
+ setTiltStyle({
+ transform: `rotateX(${tiltX}deg) rotateY(${tiltY}deg)`,
+ });
+ };
+
+ const handleMouseLeave = () => {
+ setTiltStyle({ transform: "rotateX(0deg) rotateY(0deg)" });
+ };
+
+ const handleClick = () => {
+ setIsFlipped(!isFlipped);
+ };
+
+ return (
+ onMouseEnter(setAnimation)}
+ */ onAnimationEnd={() => onAnimationEnd(setAnimation)}
+ >
+
+
+
+
Yousif Paulus
+
React | Node.js | TypeScript
+
+ {language === "en-GB"
+ ? "Full-Stack Developer"
+ : "Full-Stack Entwickler"}
+
+
+
+
+
+
+ );
+};
+
+export default ContactTileTiltFlip;
diff --git a/src/css/ContactTile.css b/src/css/ContactTile.css
new file mode 100644
index 0000000..5b77262
--- /dev/null
+++ b/src/css/ContactTile.css
@@ -0,0 +1,163 @@
+.contactTile {
+ grid-area: 1 / 1 / 8 / 9;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.container.contactTile {
+ perspective: 1500px; /* Für 3D-Effekt */
+}
+
+.card {
+ width: 340px; /* Visitenkartenformat */
+ height: 200px;
+ transform-style: preserve-3d;
+ cursor: pointer;
+ transition: transform 0.5s ease-out; /* Smooth Flip Transition */
+}
+
+.card.flipped {
+ transform: rotateY(180deg); /* Rückseite anzeigen */
+}
+
+.card-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ transform-style: preserve-3d;
+}
+
+.card-front.dark h2 {
+ color: #333;
+}
+
+.card-front,
+.card-back {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ backface-visibility: hidden;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ border-radius: 10px;
+ background: linear-gradient(145deg, #d9d9d9, #f2f2f2); /* Helles Silber */
+ box-shadow: inset 0 4px 8px rgba(255, 255, 255, 0.5),
+ inset 0 -4px 8px rgba(0, 0, 0, 0.1), 0 6px 10px rgba(0, 0, 0, 0.2);
+ overflow: hidden; /* Für Glanzeffekt-Beschneidung */
+}
+
+/* Rückseite - dunkler Silber-Look */
+.card-back {
+ background: linear-gradient(145deg, #999999, #b3b3b3);
+ transform: rotateY(180deg);
+ color: #333;
+}
+
+.card-back p {
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0rem 3.5rem;
+}
+
+.card-back p a {
+ color: #333;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+/* Glanzeffekt nur innerhalb der Karte */
+.card-front::before
+/*, .card-back::before */ {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 150%;
+ height: 150%;
+ background: radial-gradient(
+ circle at 50% 50%,
+ rgba(255, 255, 255, 0.4),
+ rgba(255, 255, 255, 0) 70%
+ );
+ transform: translate(-25%, -25%) rotate(30deg);
+ animation: subtle-glow 3s ease-in-out infinite;
+ pointer-events: none;
+ filter: blur(4px);
+ mix-blend-mode: screen; /* Lichtdurchlässigkeit */
+}
+
+/* Subtile Animation des Glanzes */
+@keyframes subtle-glow {
+ 0% {
+ transform: translate(-25%, -25%) rotate(30deg) scale(1.1);
+ }
+ 50% {
+ transform: translate(-25%, -25%) rotate(30deg) scale(1.3);
+ }
+ 100% {
+ transform: translate(-25%, -25%) rotate(30deg) scale(1.1);
+ }
+}
+
+/* Light Mode Styles */
+.card-front.light,
+.card-back.light {
+ background: linear-gradient(
+ 145deg,
+ #fdfdfd,
+ #e6e6e6
+ ); /* Heller, weicher Silber-Look */
+ box-shadow: inset 0 4px 8px rgba(255, 255, 255, 0.6),
+ inset 0 -4px 8px rgba(0, 0, 0, 0.1), 0 6px 10px rgba(0, 0, 0, 0.15);
+}
+
+/* Vorderseite Light Mode */
+.card-front.light {
+ border: 1px solid #ddd; /* Leichte Kontur für hellen Look */
+}
+
+/* Rückseite Light Mode */
+.card-back.light {
+ border: 1px solid #ccc; /* Etwas dunklere Kontur für Kontrast */
+ transform: rotateY(180deg);
+ color: #333; /* Dunkler Text für bessere Lesbarkeit */
+}
+
+/* Glanzeffekt für Light Mode */
+.card-front.light::before,
+.card-back.light::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 150%;
+ height: 150%;
+ background: radial-gradient(
+ circle at 50% 50%,
+ rgba(255, 255, 255, 0.5),
+ rgba(255, 255, 255, 0) 70%
+ );
+ transform: translate(-25%, -25%) rotate(30deg);
+ animation: subtle-glow-light 3s ease-in-out infinite;
+ pointer-events: none;
+ filter: blur(3px);
+ mix-blend-mode: overlay; /* Leicht transparenter Glanz */
+}
+
+/* Glanz-Animation für Light Mode */
+@keyframes subtle-glow-light {
+ 0% {
+ transform: translate(-25%, -25%) rotate(30deg) scale(1.05);
+ }
+ 50% {
+ transform: translate(-25%, -25%) rotate(30deg) scale(1.2);
+ }
+ 100% {
+ transform: translate(-25%, -25%) rotate(30deg) scale(1.05);
+ }
+}