diff --git a/css/expertise.css b/css/expertise.css index 2aba0c4..8d1a8d7 100644 --- a/css/expertise.css +++ b/css/expertise.css @@ -1,18 +1,15 @@ +/* expertise.css - Elegant & Modern Update (Matches services.css style) */ + /* =================================================== ===== Hero Section ===== =================================================== */ .hero { - background: url('/images/hero.png') no-repeat center/cover; - height: 100vh; - display: flex; - justify-content: center; - align-items: center; - text-align: center; - color: rgb(201, 238, 99); - position: relative; + /* background: url('/images/hero.png') no-repeat center/cover; */ + overflow: hidden; + background: radial-gradient(circle at center, #1e293b, #020617); } -.hero::after { +/* .hero::after { content: ""; position: absolute; top: 0; @@ -21,20 +18,29 @@ height: 100%; background: rgba(0, 0, 0, 0.55); border-radius: 12px; +} */ + +body.dark .hero-expertise { + background: radial-gradient(circle at center, #0f172a, #000000); } -.hero-content { - position: relative; - z-index: 2; - max-width: 850px; - padding: 20px; +#particles-js { + position: absolute; + width: 100%; + height: 100%; + z-index: 0; } -.hero h1 { - font-size: 3rem; - font-weight: 700; - line-height: 1.2; - margin-bottom: 15px; +body.dark #particles-js canvas { + filter: drop-shadow(0 0 6px rgba(0, 229, 255, 0.35)); +} + +.gradient-overlay { + position: absolute; + width: 100%; + height: 100%; + background: linear-gradient(45deg, rgba(56, 189, 248, 0.1), rgba(0, 0, 0, 0.5)); + z-index: 1; } .hero p { @@ -60,82 +66,245 @@ transform: translateY(-3px); } -/* =================================================== - ===== Skills Section ===== -=================================================== */ -#skills { +/* ===== UTILITIES ===== */ +.section-header { text-align: center; - background-color: #dee2e6; + margin-bottom: 3rem; +} + +.section-subtitle { + font-size: 1.2rem; + color: var(--color-muted); + max-width: 700px; + margin: 0 auto; +} + +.alt-bg { + background: rgba(255, 255, 255, 0.4); + border-radius: 20px; + margin-bottom: 2rem; + padding: 3rem 2rem; +} + +body.dark .alt-bg { + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.05); +} + +.category-title { + font-size: 1.5rem; + margin-bottom: 1.5rem; + text-align: center; + color: var(--color-text); +} + +body.dark .category-title { + color: #fff; +} + +/* ===== INFO BANNERS (For PoC & Shadowing) ===== */ +.info-banner-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 20px; } +.info-banner { + display: flex; + align-items: flex-start; + background: rgba(255, 255, 255, 0.7); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.4); + padding: 25px; + border-radius: 16px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); +} + +.banner-icon { + font-size: 1.8rem; + color: var(--color-primary); + margin-right: 15px; + margin-top: 5px; +} + +.banner-text h4 { + margin-bottom: 8px; + font-family: var(--font-primary); + font-size: 1.1rem; + color: var(--color-text); +} + +.banner-text p { + font-size: 0.95rem; + line-height: 1.6; + margin: 0; +} + +/* =================================================== + ===== Skills Section ===== +=================================================== */ +/* ===== SKILLS GRID ===== */ .skills-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); - gap: 1.2rem; + grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); + gap: 20px; + margin-top: 2rem; } .skill-card { - background: #fff; - padding: 1.5rem; + background: #ffffff; + padding: 25px 15px; text-align: center; - border-radius: 12px; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); - transition: transform 0.3s, box-shadow 0.3s; + border-radius: 16px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.04); + border: 1px solid rgba(0, 0, 0, 0.05); + transition: all 0.3s ease; } .skill-card i { - font-size: 2rem; - margin-bottom: 10px; - color: #ff9800; + font-size: 2.5rem; + margin-bottom: 15px; + transition: transform 0.3s ease; +} + +.skill-card h3 { + margin: 0; + font-size: 1rem; + font-family: var(--font-primary); } .skill-card:hover { - transform: translateY(-6px); - box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2); + transform: translateY(-8px); + box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); + border-color: var(--color-accent); +} + +.skill-card:hover i { + transform: scale(1.15); } /* =================================================== ===== Projects Section ===== =================================================== */ -#projects { - text-align: center; - background-color: #ced4da; -} - +/* ===== PROJECTS GRID ===== */ .projects-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 1.5rem; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 25px; } .project-card { + display: flex; + flex-direction: column; background: #fff; - padding: 1.5rem; - border-radius: 12px; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); + padding: 25px; + border-radius: 16px; + border-top: 4px solid var(--color-primary); + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05); transition: transform 0.3s, box-shadow 0.3s; + text-decoration: none; + color: var(--color-text); } .project-card:hover { - transform: translateY(-6px); - box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2); + transform: translateY(-5px); + box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1); } -.project-card a { - text-decoration: none; - color: black; +.project-card.static-card:hover { + transform: translateY(-3px); + border-top-color: var(--color-accent); } -.project-card a:hover { - color: blue; +.project-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.project-header h4 { + margin: 0; + font-size: 1.2rem; + color: var(--color-text); + transition: color 0.3s ease; +} + +.project-header i { + color: var(--color-muted); + font-size: 0.9rem; +} + +.project-card:hover .project-header h4, +.project-card:hover .project-header i { + color: var(--color-primary); +} + +.project-card p { + font-size: 0.95rem; + line-height: 1.6; + margin-bottom: 15px; + flex-grow: 1; +} + +/* Tech Tags inside projects */ +.tech-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 10px; +} + +.tech-tags span { + background: rgba(56, 189, 248, 0.1); + color: var(--color-accent); + padding: 4px 10px; + border-radius: 6px; + font-size: 0.8rem; + font-weight: 600; } -body.dark .project-card a { - color: white; +/* ===== PORTFOLIO & CTA (NEON STYLE) ===== */ +.cta-card { + background: linear-gradient(135deg, #0f172a, #1e293b); + color: #fff; + padding: 50px 30px; + border-radius: 24px; + text-align: center; + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.theme-neon { + background: linear-gradient(135deg, #020617, #0f172a); + position: relative; + overflow: hidden; } -body.dark .project-card a:hover { - color: #467db4; +.theme-neon::before { + content: ''; + position: absolute; + top: -50%; + right: -50%; + width: 200%; + height: 200%; + background: radial-gradient(circle, rgba(56, 189, 248, 0.1) 0%, transparent 60%); + z-index: 0; +} + +.theme-neon>* { + position: relative; + z-index: 1; +} + +.cta-card h2 { + color: #fff; + margin-bottom: 15px; +} + +.cta-card p { + color: #cbd5e1; + margin-bottom: 30px; } /* =================================================== @@ -171,31 +340,110 @@ body.dark .project-card a:hover { box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); } -/* Wrapper for centering card horizontally */ -.card-container { - display: flex; - justify-content: center; +/* Underline Animation Example */ +/* (For Services link at bottom of page) */ +.underline-hover { + text-decoration: none; + position: relative; + color: #333; +} + +.underline-hover::after { + content: ''; + position: absolute; width: 100%; - /* margin-top: 10px; */ + transform: scaleX(0); + height: 2px; + bottom: 0; + left: 0; + background-color: #000; + transform-origin: bottom right; + transition: transform 0.25s ease-out; +} + +.underline-hover:hover::after { + transform: scaleX(1); + transform-origin: bottom left; +} + +/* Keep the color the same even after the link is clicked */ +.underline-hover:visited { + color: #333; +} + +/* Ensure the underline still triggers on visited links */ +.underline-hover:visited:hover::after { + transform: scaleX(1); } /* =================================================== - ===== Dark Mode ===== + ===== DARK MODE OVERRIDES ===== =================================================== */ +body.dark .info-banner { + background: rgba(30, 41, 59, 0.8); + border-color: rgba(255, 255, 255, 0.05); +} -body.dark #skills, -body.dark #projects { - background-color: #467db4; - color: #000; +body.dark .info-banner h4 { + color: #fff; } body.dark .skill-card, body.dark .project-card { - background: #242424; - color: #e0e0e0; + background: #1e293b; + border: 1px solid rgba(255, 255, 255, 0.05); + color: #e2e8f0; } -body.dark .portfolio-card { - background-color: #467db4; - color: #000; +body.dark .project-card:hover { + background: #27354f; + border-color: var(--color-accent); } + +body.dark .skill-card:hover { + background: #27354f; +} + +body.dark .project-header h4 { + color: #fff; +} + +body.dark .tech-tags span { + background: rgba(255, 152, 0, 0.15); + color: #ff9800; +} + +body.dark .underline-hover { + color: #ff9800; +} + +body.dark .underline-hover::after { + background-color: #ff9800; +} + +/* Animations */ +@keyframes fadeUp { + to { + opacity: 1; + transform: translateY(0); + } +} + +.fade-in.visible { + opacity: 1 !important; + transform: translateY(0) !important; +} + +@media (max-width: 768px) { + .service-card-link { + margin-bottom: 10px; + } + + .service-card-link p { + white-space: pre-line; + } + + .break-mobile { + display: block; + } +} \ No newline at end of file diff --git a/css/global.css b/css/global.css index 4bc060e..2557848 100644 --- a/css/global.css +++ b/css/global.css @@ -59,6 +59,15 @@ h3 { margin-bottom: 1.5rem; } +h4 { + font-size: 1.1rem; + font-family: "Poppins", sans-serif; + font-optical-sizing: auto; + font-weight: 500; + font-style: normal; + margin-bottom: 1rem; +} + /* TYPOGRAPHY */ p { font-size: 1.1rem; @@ -120,6 +129,7 @@ p { .brand-name-tech { color: #a6e22e; + font-weight: 700; /* neon green */ } @@ -163,7 +173,11 @@ p { } .nav-links li a:hover { - color: #ff6347; + color: #a51a01; +} + +.nav-links ul li a:hover { + color: #a51a01; } .dropdown-menu { @@ -246,6 +260,10 @@ p { display: block; } + body.dark .nav-links { + background: #4b76ad; + } + .nav-links.active { display: flex; } @@ -276,14 +294,15 @@ p { .hero-content { position: relative; z-index: 2; - max-width: 750px; + max-width: 850px; opacity: 0; transform: translateY(30px); animation: heroFadeUp 1s ease forwards; display: flex; flex-direction: column; align-items: center; - gap: 20px; + gap: 5px; + padding: 20px; } @keyframes heroFadeUp { @@ -317,8 +336,8 @@ p { .hero p { font-size: 1.1rem; - margin-bottom: 2rem; - gap: 30px; + /* margin-bottom: 2rem; */ + /* gap: 30px; */ } .hero-subtext { @@ -326,7 +345,7 @@ p { color: #e5e7eb; line-height: 1.6; margin-top: 1rem; - margin-bottom: 2rem; + margin-bottom: 1.5rem; opacity: 0; animation: fadeUp 0.8s ease forwards; animation-delay: 0.3s; @@ -482,7 +501,7 @@ body.dark .nav-links a.active { } body.dark nav ul li a:hover { - color: #ff9800; + color: #a51a01; } body.dark .hamburger { diff --git a/css/services.css b/css/services.css index 09bceed..5c702be 100644 --- a/css/services.css +++ b/css/services.css @@ -425,14 +425,6 @@ body.dark p { } @media (max-width: 768px) { - .hero-services h1 { - font-size: 2.2rem; - } - - .hero-services p { - font-size: 1rem; - } - .process-step { min-width: 100%; } diff --git a/expertise/index.html b/expertise/index.html index ac3ef8e..af8774e 100644 --- a/expertise/index.html +++ b/expertise/index.html @@ -67,7 +67,21 @@ + + + + + + + @@ -108,190 +122,251 @@ -
+
+
+
-

Java Developer Expertise – Backend Systems, REST APIs & Microservices

- Projects - Portfolio +

Java Developer Expertise

+

+ Backend Systems • REST APIs • + Microservices • Cloud Computing + • Virtualization +

+

+ Having made API + and eventually gained experience on + Web Services (Enterprise Rest API, SOAP) and Standard REST APIs, + I specialize in bringing Proof of Concepts to production. +

+ +
+
+ +
+
+
+ + +
+
+ + +
-
-

Skills

-
-

Delivering scalable, secure, and modern efficient solutions for web, mobile, and enterprise systems using - below technologies. -

+
+
+

Technical Skills

+

+ Explore my skills, projects, and portfolio to see how I can help you build scalable, secure, and modern + applications. +

+

Delivering scalable, secure, and modern efficient solutions for web, mobile, and + enterprise systems.

+
-
+

Java

-
+

Spring Boot

-
+

Spring Cloud

-
+

Hibernate

-
+

REST API

-
-

Oracle/sql-developer

+
+

Oracle / SQL

-
+

AWS

-
+

MongoDB

-
+

PostgreSQL

-
+

Firebase

-
+

Docker

-
-

Microservice Architecture

+
+

Microservices

-
-

Node

+
+

Node.js

-
+

Angular

-
+

React

-
-

HTML

+
+

HTML5

-
-

CSS

+
+

CSS3

-
+

JavaScript

-
+

Bootstrap

-
+

Yarn

-
+

Bitbucket

-
+

Slack

-
+

Jenkins

-
-

Atlassian

-
-
+

Jira

-
+

GitHub

+
+

Ubuntu

+
-

+
-
-

Projects

-
-

Hi Geeks and Nerds 👋 Explore my expertise in Full stack development.

-
-
-

Frontend Live Websites On Server


-
-
- -

Suman Enterprise

-

- Vue.js + Vue-Router + Vuetify + Vite + Pinia-Vue.js -

+
+
+

Full Stack Projects

+

+ + Frontend Live Websites +

+

+ Hi Geeks and Nerds 👋 Explore my live frontend interfaces and robust backend systems.

+
- - + +

+ Backend & Enterprise Systems +

+

+ I have also worked on Microservices architecture and Docker for containerization. I have experience with + AWS for cloud deployment and services. +

+
+
+

PTC Windchill (Java Product)

+

Customised Java Client for PTC Windchill PDMLink as Shadow Resource.

+

Oracle SQL Developer, JSOUP, XML

+
+
+

Parking System (POC)

+

Scalable architecture using REST API, Microservices, and Docker.

+

Docker + Swagger-UI, Postman.

+
+
+

Data Streaming Data Streaming & Fleet Management (POC)

+

Real-Time Data Processing with Spring Boot, Kafka, Spark, and Docker.

+
+
+

Health Care Center Management

+

Enterprise system built on Core Java, Spring Framework, Hibernate, JSP and Oracle.

+
+
+

Consultant ROI

+

Core Java, JDBC, DAO Design Pattern, Struts 2.0 Framework and Oracle.

+
+
+

E-commerce Backend-Best Practices

+

REST API backend utilizing Java, Spring Boot, Hibernate, Maven, and MySQL.

+
+
+

Chat Application

+

Real-Time Chat implemented with Java WebSocket & Spring Boot.

+
+
+

Desktop Chat (LAN)

+

Java RMI, Stubs, Skeletons, and Swing Framework for desktop networks.

+
+
+
-
-
-

Explore my recent projects showcasing my skills in Java development and backend systems.

-
-
-

Backend Projects


-
-
-

PTC Windchill (Java Product)

-

Customised Java Client for PTC Windchill PDMLink as Shadow Resource.

-
-
-

Parking System (POC)

-

Rest API, Microservices, Docker + Swagger-UI, Postman.

-
-
-

Data Streaming App (POC)

-

Spring Boot + Kafka + Spark + Docker for Real-Time Data Processing.

-
-
-

Health Care Center Management

-

Core Java, Spring Framework and Hibernate + JSP + Oracle

-
-
-

Consultant Return On Investment

-

Core Java, JDBC, DAO Design Pattern, Struts 2.0 Framework. + Oracle

-
-
-

E-commerce Backend Best Practices

-

REST API backend with Java, Spring Boot, and Hibernate + Maven, MySQL

-
-
-

Chat Application

-

Real-Time Chat with Java WebSocket & Spring Boot.

-
-
-

Desktop Chat Application (Local Area Network)

-

Java Remote Method Invocation + Stubs + Skeletons, Swing Framework.

-
-

-
-

- See more backend services on
- Java Development Services. -

-

+
-
-
-

Portfolio

- View Overview +
+
+

Explore My Full Portfolio

+

+ Dive deeper into case studies, architecture diagrams, and comprehensive project overviews.

+ + View Portfolio Overview + +
diff --git a/js/about.js b/js/about.js index 6cf2d6f..12528c4 100644 --- a/js/about.js +++ b/js/about.js @@ -4,3 +4,37 @@ // This function ensures the about link overrides that behavior. // 1️⃣ Force "About" Link Active // Code was removed because common.js handles this with ScrollSpy. + +// ===== localStorage theme handling ===== +const darkModeToggle = document.getElementById("darkModeToggle"); +const body = document.body; + +// Apply saved theme on load +if (localStorage.getItem("theme") === "dark") { + document.documentElement.classList.add("dark"); + body.classList.add("dark"); + darkModeToggle.textContent = "☀️"; // show sun icon if dark mode is active +} else { + darkModeToggle.textContent = "🌙"; // show moon icon if light mode is active +} + +// ===== Dark Mode Persist Across Pages ===== +darkModeToggle.addEventListener("click", () => { + const isDark = body.classList.toggle("dark"); + darkModeToggle.textContent = isDark ? "☀️" : "🌙"; + localStorage.setItem("theme", isDark ? "dark" : "light"); + + // ===== Optional for Services Page ===== + if (typeof updateOverlayGradient === "function") updateOverlayGradient(); + + // Rebuild particles only if available + if (typeof initParticles === "function") { + setTimeout(() => { + if (window.pJSDom && pJSDom.length) { + pJSDom[0].pJS.fn.vendors.destroypJS(); + document.getElementById("particles-js").innerHTML = ""; + } + initParticles(); + }, 300); + } +}); \ No newline at end of file diff --git a/js/contact.js b/js/contact.js index d59a78d..1806ab0 100644 --- a/js/contact.js +++ b/js/contact.js @@ -148,3 +148,36 @@ document.addEventListener("DOMContentLoaded", function () { } } }); +// ===== localStorage theme handling ===== +const darkModeToggle = document.getElementById("darkModeToggle"); +const body = document.body; + +// Apply saved theme on load +if (localStorage.getItem("theme") === "dark") { + document.documentElement.classList.add("dark"); + body.classList.add("dark"); + darkModeToggle.textContent = "☀️"; // show sun icon if dark mode is active +} else { + darkModeToggle.textContent = "🌙"; // show moon icon if light mode is active +} + +// ===== Dark Mode Persist Across Pages ===== +darkModeToggle.addEventListener("click", () => { + const isDark = body.classList.toggle("dark"); + darkModeToggle.textContent = isDark ? "☀️" : "🌙"; + localStorage.setItem("theme", isDark ? "dark" : "light"); + + // ===== Optional for Services Page ===== + if (typeof updateOverlayGradient === "function") updateOverlayGradient(); + + // Rebuild particles only if available + if (typeof initParticles === "function") { + setTimeout(() => { + if (window.pJSDom && pJSDom.length) { + pJSDom[0].pJS.fn.vendors.destroypJS(); + document.getElementById("particles-js").innerHTML = ""; + } + initParticles(); + }, 300); + } +}); \ No newline at end of file diff --git a/js/expertise.js b/js/expertise.js index c9dcedb..ed49769 100644 --- a/js/expertise.js +++ b/js/expertise.js @@ -1,33 +1,213 @@ -// ===== localStorage theme handling ===== -const darkModeToggle = document.getElementById("darkModeToggle"); -const body = document.body; - -// Apply saved theme on load -if (localStorage.getItem("theme") === "dark") { - document.documentElement.classList.add("dark"); - body.classList.add("dark"); - darkModeToggle.textContent = "☀️"; // show sun icon if dark mode is active -} else { - darkModeToggle.textContent = "🌙"; // show moon icon if light mode is active +// =================================================== +// ===== 1. PARTICLES INITIALIZATION ===== +// =================================================== +function initParticles() { + const isDark = document.body.classList.contains("dark"); + + particlesJS("particles-js", { + "particles": { + "number": { "value": 70, "density": { "enable": true, "value_area": 900 } }, + "color": { "value": isDark ? "#00e5ff" : "#ff9800" }, + "shape": { "type": "circle" }, + "opacity": { "value": 0.6, "random": true, "anim": { "enable": true, "speed": 0.5, "opacity_min": 0.1, "sync": false } }, + "size": { "value": 3, "random": true }, + "line_linked": { + "enable": true, + "distance": 120, + "color": isDark ? "#00bcd4" : "#ffb74d", + "opacity": isDark ? 0.4 : 0.35, + "width": 1 + }, + "move": { + "enable": true, + "speed": 2, + "direction": "none", + "random": true, + "straight": false, + "bounce": false + } + }, + "interactivity": { + "detect_on": "canvas", + "events": { + "onhover": { "enable": true, "mode": "grab" }, + "onclick": { "enable": false }, + "resize": true + }, + "modes": { + "grab": { "distance": 200, "line_linked": { "opacity": 0.8 } } + } + }, + "retina_detect": true + }); +} + +function reloadParticles() { + if (window.pJSDom && window.pJSDom.length > 0) { + window.pJSDom[0].pJS.fn.vendors.destroypJS(); + window.pJSDom = []; + } + const container = document.getElementById("particles-js"); + if (container) container.innerHTML = ""; + initParticles(); } -// ===== Dark Mode Persist Across Pages ===== -darkModeToggle.addEventListener("click", () => { - const isDark = body.classList.toggle("dark"); - darkModeToggle.textContent = isDark ? "☀️" : "🌙"; - localStorage.setItem("theme", isDark ? "dark" : "light"); - - // ===== Optional for Services Page ===== - if (typeof updateOverlayGradient === "function") updateOverlayGradient(); - - // Rebuild particles only if available - if (typeof initParticles === "function") { - setTimeout(() => { - if (window.pJSDom && pJSDom.length) { - pJSDom[0].pJS.fn.vendors.destroypJS(); - document.getElementById("particles-js").innerHTML = ""; +// =================================================== +// ===== 2. CUSTOM PHYSICS (IDLE TIMER + EXPLOSION) == +// =================================================== +let mouseX = -9999; +let mouseY = -9999; +let isMousePresent = false; +let hasActuallyMoved = false; + +// THE FIX: Idle Timer variables +let isMouseActive = false; +let idleTimeout = null; +let initialX = null; +let initialY = null; + +document.addEventListener("mousemove", (e) => { + // 25-Pixel Deadzone Lock + if (!hasActuallyMoved) { + if (initialX === null && initialY === null) { + initialX = e.clientX; + initialY = e.clientY; + return; + } + const dx = e.clientX - initialX; + const dy = e.clientY - initialY; + if (Math.sqrt(dx * dx + dy * dy) < 25) return; + hasActuallyMoved = true; + } + + // Update coordinates + mouseX = e.clientX; + mouseY = e.clientY; + isMousePresent = true; + + // Turn the magnet ON because the mouse is currently moving + isMouseActive = true; + + // Reset the Idle Timer every time the mouse moves + clearTimeout(idleTimeout); + idleTimeout = setTimeout(() => { + // If the mouse stops moving for 1 second, turn the magnet OFF + isMouseActive = false; + }, 1000); +}); + +document.addEventListener("mouseleave", () => { + isMousePresent = false; + isMouseActive = false; // Turn off magnet if mouse leaves window +}); + +// Click to Explode (Now uses exact click coordinates) +document.addEventListener("click", (e) => { + if (!window.pJSDom || window.pJSDom.length === 0) return; + + const clickX = e.clientX; + const clickY = e.clientY; + const particles = window.pJSDom[0].pJS.particles.array; + + particles.forEach(p => { + const dx = p.x - clickX; + const dy = p.y - clickY; + const dist = Math.sqrt(dx * dx + dy * dy); + + if (dist < 400 && dist > 0) { + const force = (400 - dist) / 400; + p.vx += (dx / dist) * force * 35; + p.vy += (dy / dist) * force * 35; + } + }); +}); + +// The Physics Engine Loop +function applyCustomPhysics() { + if (window.pJSDom && window.pJSDom.length > 0) { + const pJS = window.pJSDom[0].pJS; + const particles = pJS.particles.array; + + // Hide native library cursor tracking if idle or deadzone locked + if (!hasActuallyMoved || !isMouseActive) { + pJS.interactivity.mouse.pos_x = null; + pJS.interactivity.mouse.pos_y = null; + } else { + pJS.interactivity.mouse.pos_x = mouseX; + pJS.interactivity.mouse.pos_y = mouseY; + } + + particles.forEach(p => { + // Air Resistance (Slows them down after explosion) + if (Math.abs(p.vx) > 1.0 || Math.abs(p.vy) > 1.0) { + p.vx *= 0.88; + p.vy *= 0.88; + } + + // Magnetic Pull (ONLY runs if the mouse is actively moving) + if (isMouseActive && isMousePresent) { + const dx = mouseX - p.x; + const dy = mouseY - p.y; + const dist = Math.sqrt(dx * dx + dy * dy); + + if (dist < 250 && dist > 0) { + p.x += dx * 0.015; + p.y += dy * 0.015; + } } - initParticles(); - }, 300); + }); + } + requestAnimationFrame(applyCustomPhysics); +} + +applyCustomPhysics(); + +// =================================================== +// ===== 3. UI, THEME ===== +// =================================================== +function updateOverlayGradient() { + const overlay = document.querySelector(".gradient-overlay"); + if (!overlay) return; + if (document.body.classList.contains("dark")) { + overlay.style.background = "linear-gradient(45deg, rgba(0,150,255,0.25), rgba(0,0,0,0.3), rgba(0,200,255,0.25))"; + } else { + overlay.style.background = "linear-gradient(45deg, rgba(255,140,0,0.25), rgba(255,255,255,0.15), rgba(255,215,64,0.25))"; + } +} + +function updateToggleIcon() { + const darkModeToggle = document.getElementById("darkModeToggle"); + if (!darkModeToggle) return; + if (document.body.classList.contains("dark")) { + darkModeToggle.textContent = "☀️"; + darkModeToggle.title = "Switch to light mode"; + darkModeToggle.style.background = "#00bcd4"; + darkModeToggle.style.color = "#000"; + } else { + darkModeToggle.textContent = "🌙"; + darkModeToggle.title = "Switch to dark mode"; + darkModeToggle.style.background = "#000000"; + darkModeToggle.style.color = "#fff"; + } +} + +const darkModeToggle = document.getElementById("darkModeToggle"); +if (darkModeToggle) { + darkModeToggle.addEventListener("click", () => { + const isDark = document.body.classList.toggle("dark"); + localStorage.setItem("theme", isDark ? "dark" : "light"); + updateOverlayGradient(); + updateToggleIcon(); + reloadParticles(); + }); +} + +document.addEventListener("DOMContentLoaded", () => { + if (localStorage.getItem("theme") === "dark") { + document.body.classList.add("dark"); + document.documentElement.classList.add("dark"); } + updateOverlayGradient(); + updateToggleIcon(); + initParticles(); }); \ No newline at end of file diff --git a/services/index.html b/services/index.html index fa01fa0..8743db1 100644 --- a/services/index.html +++ b/services/index.html @@ -228,9 +228,9 @@
-

Our Professional Services +

Our Professional Services Handling Virtual Infrastructure - Software Architect + Software Architect

We help startups and businesses build scalable, secure, and @@ -435,7 +435,7 @@

Consulting

-
+

Live Websites & Systems

Check out some of the systems currently running in production.