From fb6eccc8350dab46c1f7662606ba82519afec2fa Mon Sep 17 00:00:00 2001
From: Muthu Kumar <muthukumar@thefeathers.in>
Date: Mon, 7 Apr 2025 21:35:11 +0530
Subject: [PATCH] feat: use Flippable to make chaotic Contact page

---
 package.json               |   1 +
 src/pages/main/Contact.tsx | 233 +++++++++++++++++++++++++--------------------
 2 files changed, 130 insertions(+), 104 deletions(-)

diff --git a/package.json b/package.json
index f589943..31a2f63 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
 	"type": "module",
 	"scripts": {
 		"start": "vite --host",
+		"check": "tsc --noEmit",
 		"build": "tsc && vite build",
 		"serve": "vite preview",
 		"blog": "node scripts/blog.js"
diff --git a/src/pages/main/Contact.tsx b/src/pages/main/Contact.tsx
index e5fddf8..e53cf44 100644
--- a/src/pages/main/Contact.tsx
+++ b/src/pages/main/Contact.tsx
@@ -5,6 +5,7 @@ import Container from "../../components/Container";
 import { setupCursorTracking } from "../../util";
 import { ReactComponent as Logo } from "../../assets/logo.svg";
 import { DraggableButton } from "../../components/DraggableButton";
+import { Flippable } from "../../components/Flippable";
 
 const A = css`
 	text-decoration: none;
@@ -43,7 +44,13 @@ const CONTACT: Contact = {
 	"Blog": { value: "→", link: "https://MKRhere.com" },
 };
 
-const Home: React.FC = () => {
+// slightly random rotations within -20 to 20 degrees
+const cardRotations = Array.from({ length: 5 }, (_, i) => {
+	const rotation = Math.random() * 40 - 20;
+	return rotation;
+});
+
+const Contact: React.FC = () => {
 	const [contact, setContact] = useState<Contact>(CONTACT);
 
 	useEffect(() => {
@@ -89,113 +96,131 @@ const Home: React.FC = () => {
 				position: relative;
 			`}>
 			<h1>MKRhere</h1>
-			<DraggableButton
-				className={css`
-					width: 22rem;
-					height: auto;
-					aspect-ratio: 3 / 2;
-
-					bottom: 0rem;
-					background: var(--card-tags);
-					border-radius: 0.5rem;
-					transform: rotateZ(5deg);
-
-					position: absolute;
-					bottom: 0;
-					left: 0;
-
-					display: flex;
-					align-items: center;
-					justify-content: center;
-				`}>
-				<Logo width={100} />
-			</DraggableButton>
-			<DraggableButton
-				className={css`
-					width: 22rem;
-					height: auto;
-					aspect-ratio: 3 / 2;
-
-					margin-top: auto;
-					display: flex;
-					align-items: center;
-					justify-content: center;
-					gap: 1rem;
-					font-size: 1rem;
-
-					padding: 1rem 2.8em;
-					background: var(--card-bg);
-					border-radius: 0.5rem;
-					transform: rotateZ(-5deg);
-
-					position: absolute;
-					bottom: 0;
-					left: 0;
-
-					ul {
-						padding: 0;
-						display: flex;
-						flex-direction: column;
-						gap: 0.5rem;
-						max-width: 50vw;
-
-						li {
-							list-style: none;
-							min-width: 4rem;
-							max-width: 100%;
-						}
+			{cardRotations.map((r, i) => (
+				<DraggableButton
+					key={i}
+					className={css`
+						width: 22rem;
+						height: auto;
+						aspect-ratio: 3 / 2;
 
-						li a {
-							display: block;
-							max-width: 100%;
-							white-space: nowrap;
-							text-overflow: ellipsis;
-							overflow: hidden;
-						}
+						position: absolute;
+						bottom: 0;
+						left: 0;
 
-						/* Blog entry */
-						li:last-child {
-							margin-block-start: 1rem;
+						rotate: ${r}deg;
+
+						padding: 0;
+						background: transparent;
+					`}
+					ref={setupCursorTracking}>
+					<Flippable
+						defaultSide={i === cardRotations.length - 1 ? "front" : "back"}
+						front={
+							<main
+								className={css`
+									height: 100%;
+									width: 100%;
+
+									overflow: hidden;
+									border-radius: 0.5rem;
+									background: var(--card-bg);
+
+									box-shadow: 0 0 50rem 0 rgba(0, 0, 0, 0.8);
+
+									display: flex;
+									align-items: center;
+									justify-content: center;
+									gap: 1rem;
+									font-size: 1rem;
+
+									padding: 1rem 2.8em;
+
+									ul {
+										padding: 0;
+										display: flex;
+										flex-direction: column;
+										gap: 0.5rem;
+										max-width: 50vw;
+
+										li {
+											list-style: none;
+											min-width: 4rem;
+											max-width: 100%;
+										}
+
+										li a {
+											display: block;
+											max-width: 100%;
+											white-space: nowrap;
+											text-overflow: ellipsis;
+											overflow: hidden;
+										}
+
+										/* Blog entry */
+										li:last-child {
+											margin-block-start: 1rem;
+										}
+									}
+								`}>
+								<div className="dynamic-gradient" />
+								<ul
+									className={css`
+										text-align: right;
+									`}>
+									{Object.keys(contact).map(key => (
+										<li key={key}>
+											<b>{key}.</b>
+										</li>
+									))}
+								</ul>
+								<ul>
+									{Object.keys(contact).map(key => {
+										const value = contact[key];
+
+										return (
+											<li key={key}>
+												{value.link ? (
+													<a
+														className={A}
+														href={value.link}
+														target="_blank"
+														rel="noreferrer"
+														style={{ width: "fit-content" }}>
+														{value.value}
+													</a>
+												) : (
+													value.value
+												)}
+											</li>
+										);
+									})}
+								</ul>
+							</main>
 						}
-					}
-				`}
-				ref={setupCursorTracking}>
-				<div className="dynamic-gradient" />
-				<ul
-					className={css`
-						text-align: right;
-					`}>
-					{Object.keys(contact).map(key => (
-						<li key={key}>
-							<b>{key}.</b>
-						</li>
-					))}
-				</ul>
-				<ul>
-					{Object.keys(contact).map(key => {
-						const value = contact[key];
-
-						return (
-							<li key={key}>
-								{value.link ? (
-									<a
-										className={A}
-										href={value.link}
-										target="_blank"
-										rel="noreferrer"
-										style={{ width: "fit-content" }}>
-										{value.value}
-									</a>
-								) : (
-									value.value
-								)}
-							</li>
-						);
-					})}
-				</ul>
-			</DraggableButton>
+						back={
+							<main
+								className={css`
+									width: 100%;
+									height: 100%;
+
+									overflow: hidden;
+									border-radius: 0.5rem;
+									background: var(--card-active);
+									border: 1px solid var(--card-active-border);
+
+									display: flex;
+									align-items: center;
+									justify-content: center;
+								`}>
+								<Logo width={100} />
+							</main>
+						}
+					/>
+				</DraggableButton>
+			))}
 		</Container>
 	);
 };
 
-export default Home;
+export default Contact;