Spaces:
Running
Running
File size: 2,424 Bytes
4a5bd8c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
// Simple color and theme management
(function () {
const config = {
primary: "gray",
secondary: "slate",
theme: "light", // light | dark
};
function applyTheme(theme) {
const root = document.documentElement;
if (theme === "dark") {
root.classList.add("dark");
} else {
root.classList.remove("dark");
}
}
// Theme toggle
const toggle = document.getElementById("themeToggle");
if (toggle) {
toggle.addEventListener("click", () => {
const isDark = document.documentElement.classList.toggle("dark");
const next = isDark ? "dark" : "light";
try {
localStorage.setItem("theme", next);
} catch (_) {}
});
}
// Restore saved theme
try {
const saved = localStorage.getItem("theme");
if (saved === "dark" || saved === "light") {
applyTheme(saved);
} else {
applyTheme(config.theme);
}
} catch (_) {
applyTheme(config.theme);
}
// Device tilt effect (hero)
const device = document.getElementById("device3d");
if (device) {
let raf = null;
let rx = 0, ry = 0, tx = 0, ty = 0;
const max = 8;
const onMove = (e) => {
const rect = device.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
const dx = (e.clientX - cx) / (rect.width / 2);
const dy = (e.clientY - cy) / (rect.height / 2);
tx = Math.max(-1, Math.min(1, dx));
ty = Math.max(-1, Math.min(1, dy));
ry = tx * max;
rx = -ty * max;
if (!raf) {
raf = requestAnimationFrame(() => {
device.style.transform = `perspective(1000px) rotateX(${rx.toFixed(2)}deg) rotateY(${ry.toFixed(2)}deg) translateZ(0)`;
raf = null;
});
}
};
const reset = () => {
device.style.transform = "perspective(1000px) rotateX(0deg) rotateY(0deg)";
};
window.addEventListener("mousemove", onMove, { passive: true });
window.addEventListener("mouseleave", reset);
window.addEventListener("touchmove", (e) => {
if (!e.touches || e.touches.length === 0) return;
const t = e.touches[0];
onMove({ clientX: t.clientX, clientY: t.clientY });
}, { passive: true });
window.addEventListener("touchend", reset);
}
// Optional: uncomment to log config or expose it for debugging
// console.log("iPhone 1 Landing — Config:", config);
})(); |