From 19fe6d30f43cb6c2978066177401b3ee0857e466 Mon Sep 17 00:00:00 2001
From: ssbg04
Date: Fri, 5 Jun 2026 18:47:00 +0800
Subject: [PATCH] secured privacy
---
.env.example | 14 +-
.gitignore | 1 +
assets/css/style.css | 1818 ++++++++++++++++++++++++------------------
blog.php | 239 +++---
certifications.php | 262 +++---
config/db.php | 51 +-
index.php | 370 +++++----
projects.php | 82 +-
views/projects.php | 67 +-
views/tprojects.php | 67 +-
10 files changed, 1666 insertions(+), 1305 deletions(-)
diff --git a/.env.example b/.env.example
index 8969c9e..1d1cfeb 100644
--- a/.env.example
+++ b/.env.example
@@ -1,9 +1,15 @@
-# Email Configuration
-CONTACT_EMAIL=your-email@gmail.com
+# Database Configuration
+DB_HOST=your-database-host
+DB_USER=your-database-username
+DB_PASS=your-database-password
+DB_NAME=your-database-name
# Google reCAPTCHA
-RECAPTCHA_SITE_KEY=your-site-key-here
-RECAPTCHA_SECRET_KEY=your-secret-key-here
+RECAPTCHA_SITE_KEY=your-recaptcha-site-key-here
+RECAPTCHA_SECRET_KEY=your-recaptcha-secret-key-here
+
+# Contact Email (used in FormSubmit action)
+CONTACT_EMAIL=your-email@gmail.com
# Rate Limiting (requests per hour)
RATE_LIMIT=10
diff --git a/.gitignore b/.gitignore
index 3f02504..b9e8365 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
if0_41132991_portfolio.sql
googl*
+.env
diff --git a/assets/css/style.css b/assets/css/style.css
index b8445d3..420b3b0 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -1,755 +1,1063 @@
-/* --- Variables & Configuration --- */
-:root {
- --bg: #0a0a0a;
- --card-bg: #161616;
- --text-main: #ededed;
- --text-muted: #a1a1a1;
- --accent: #3b82f6;
- --border: #2a2a2a;
- /* NEW: Dark Mode Transparent Background */
- --glass-bg: rgba(10, 10, 10, 0.8);
-}
-
-* {
- box-sizing: border-box;
- margin: 0;
- padding: 0;
-}
-html {
- scroll-behavior: smooth;
-}
-/* 1. Set the width of the scrollbar */
-html::-webkit-scrollbar {
- width: 8px; /* Thin and sleek */
-}
-
-/* 2. The background of the scrollbar (Track) */
-html::-webkit-scrollbar-track {
- background: var(--bg); /* Matches your dark background */
-}
-
-/* 3. The moving part of the scrollbar (Thumb) */
-html::-webkit-scrollbar-thumb {
- background-color: #333; /* Dark Grey */
- border-radius: 4px; /* Rounded edges */
-}
-
-/* 4. Hover effect */
-html::-webkit-scrollbar-thumb:hover {
- background-color: var(--accent); /* Turns Blue when hovered */
-}
-
-.site-wrapper {
- background-color: var(--bg);
- color: var(--text-main);
- min-height: 100vh;
- width: 100%;
- padding: 0 5%;
- transition:
- background-color 0.3s ease,
- color 0.3s ease;
- display: flex;
- flex-direction: column;
-}
-
-/* --- Dark/Light Logic --- */
-.toggle-checkbox {
- display: none;
-}
-
-.toggle-checkbox:not(:checked) ~ .site-wrapper {
- --bg: #ffffff;
- --card-bg: #f3f4f6;
- --text-main: #111827;
- --text-muted: #4b5563;
- --accent: #2563eb;
- --border: #e5e7eb;
- /* NEW: Light Mode Transparent Background */
- --glass-bg: rgba(255, 255, 255, 0.8);
-}
-
-.mode-btn {
- cursor: pointer;
- margin-left: 20px;
- font-size: 1.2rem;
- user-select: none;
-}
-.toggle-checkbox:checked ~ .site-wrapper .icon-sun {
- display: none;
-}
-.toggle-checkbox:checked ~ .site-wrapper .icon-moon {
- display: inline;
-}
-.toggle-checkbox:not(:checked) ~ .site-wrapper .icon-moon {
- display: none;
-}
-.toggle-checkbox:not(:checked) ~ .site-wrapper .icon-sun {
- display: inline;
-}
-
-/* --- Global Styles --- */
-body {
- font-family: "Inter", sans-serif;
- line-height: 1.6;
- margin: 0;
-}
-
-/* --- UPDATED: Sticky Nav --- */
-nav {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px 0; /* Slightly reduced for a sleeker sticky bar */
- max-width: 1000px;
- width: 100%;
- margin: 0 auto;
-
- /* Sticky properties */
- position: sticky;
- top: 0;
- z-index: 1000;
-
- /* Theme-based Glass Background */
- background: var(--glass-bg);
- backdrop-filter: blur(12px);
- -webkit-backdrop-filter: blur(12px);
- border-bottom: 1px solid var(--border); /* Adds a nice separation line when scrolling */
-}
-
-.logo {
- font-weight: 800;
- font-size: 1.5rem;
- letter-spacing: -1px;
-}
-
-/* Desktop: Show links normally */
-.nav-links {
- display: flex;
- align-items: center;
- gap: 24px;
-}
-
-.nav-links a {
- color: var(--text-muted);
- text-decoration: none;
- font-size: 0.95rem;
- transition: color 0.2s;
-}
-.nav-links a:hover {
- color: var(--accent);
-}
-
-/* Hamburger Icon (Hidden on Desktop) */
-.hamburger {
- display: none;
- cursor: pointer;
-}
-
-.bar {
- display: block;
- width: 25px;
- height: 3px;
- margin: 5px auto;
- transition: all 0.3s ease-in-out;
- background-color: var(--text-main); /* Matches theme color */
-}
-
-/* --- Mobile Menu (Max-width 768px) --- */
-@media (max-width: 768px) {
- /* Show Hamburger */
- .hamburger {
- display: block;
- }
-
- /* Animate Hamburger to X when active */
- .hamburger.active .bar:nth-child(2) {
- opacity: 0;
- }
- .hamburger.active .bar:nth-child(1) {
- transform: translateY(8px) rotate(45deg);
- }
- .hamburger.active .bar:nth-child(3) {
- transform: translateY(-8px) rotate(-45deg);
- }
-
- /* --- UPDATED: Mobile Dropdown --- */
- .nav-links {
- position: absolute; /* Attaches exactly to the sticky nav */
- left: -100%; /* Hide off-screen */
- top: 100%; /* Sits exactly below the navbar */
- flex-direction: column;
- width: 100%;
- text-align: center;
- transition: 0.3s ease-in-out;
- box-shadow: 0 10px 27px rgba(0, 0, 0, 0.05);
- border-bottom: 1px solid var(--border);
- padding: 20px 0;
- gap: 20px;
-
- /* Theme-Based Transparent Background */
- background: var(--glass-bg);
- backdrop-filter: blur(15px);
- -webkit-backdrop-filter: blur(15px);
- }
-
- /* Show Links when active */
- .nav-links.active {
- left: 0; /* Slide in */
- }
-
- .nav-links a {
- color: var(--text-main); /* Automatically matches dark/light mode */
- font-size: 1.2rem;
- display: block;
- padding: 10px;
- }
-}
-
-/* --- Hero --- */
-.hero {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 80px 0;
- gap: 40px;
- max-width: 1000px;
- margin: 0 auto;
-}
-
-.hero-text {
- flex: 1;
-}
-.greeting {
- color: var(--accent);
- font-weight: 600;
- display: block;
- margin-bottom: 10px;
-}
-h1 {
- font-size: clamp(2.5rem, 5vw, 3.5rem);
- line-height: 1.1;
- font-weight: 800;
- margin-bottom: 20px;
- letter-spacing: -1px;
-}
-.subtitle {
- color: var(--text-muted);
- font-size: 1.1rem;
- margin-bottom: 30px;
-}
-.highlight {
- color: var(--accent);
-}
-
-.hero-btns {
- display: flex;
- gap: 15px;
-}
-
-.btn {
- text-decoration: none;
- padding: 12px 24px;
- border-radius: 6px;
- font-weight: 600;
- transition: transform 0.2s;
-}
-.btn.primary {
- background: var(--accent);
- color: white;
- border: 1px solid var(--accent);
-}
-.btn.secondary {
- background: transparent;
- color: var(--text-main);
- border: 1px solid var(--border);
-}
-.btn:hover {
- transform: translateY(-2px);
-}
-
-.hero-img-container {
- position: relative;
- width: 250px;
- height: 250px;
- flex-shrink: 0;
-}
-
-.profile-pic {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- object-fit: cover;
- border-radius: 20px;
- border: 1px solid var(--border);
- transition: opacity 0.4s ease-in-out;
- opacity: 0; /* Hide all images by default */
-}
-/* -----------------------------------
- DARK MODE (Default State)
------------------------------------ */
-.img-night-normal {
- opacity: 1;
- z-index: 2;
- cursor: none;
-} /* Show Night Normal */
-
-/* On Hover: Fade in Night Hover, Fade out Night Normal */
-.hero-img-container:hover .img-night-hover {
- opacity: 1;
- z-index: 3;
- cursor: none;
-}
-.hero-img-container:hover .img-night-normal {
- opacity: 0;
- cursor: none;
-}
-
-/* -----------------------------------
- LIGHT MODE (When Checkbox is unchecked)
------------------------------------ */
-/* 1. Hide the Dark Mode images entirely */
-.toggle-checkbox:not(:checked) ~ .site-wrapper .img-night-normal,
-.toggle-checkbox:not(:checked) ~ .site-wrapper .img-night-hover {
- opacity: 0 !important;
-}
-
-/* 2. Show Day Normal */
-.toggle-checkbox:not(:checked) ~ .site-wrapper .img-day-normal {
- opacity: 1;
- z-index: 2;
- cursor: none;
-}
-
-/* 3. On Hover: Fade in Day Hover, Fade out Day Normal */
-.toggle-checkbox:not(:checked)
- ~ .site-wrapper
- .hero-img-container:hover
- .img-day-hover {
- opacity: 1;
- z-index: 3;
- cursor: none;
-}
-.toggle-checkbox:not(:checked)
- ~ .site-wrapper
- .hero-img-container:hover
- .img-day-normal {
- opacity: 0;
- cursor: none;
-}
-
-.glow-effect {
- position: absolute;
- top: 20px;
- left: 20px;
- width: 100%;
- height: 100%;
- background: var(--accent);
- border-radius: 20px;
- opacity: 0.2;
- z-index: 1;
- filter: blur(20px);
-}
-
-/* --- Common Section Styles --- */
-.section-pad {
- padding: 80px 0;
- max-width: 1000px;
- margin: 0 auto;
- width: 100%;
-}
-.section-title {
- font-size: 2rem;
- margin-bottom: 40px;
-}
-
-.about-content {
- display: grid;
- grid-template-columns: 3fr 2fr;
- gap: 50px;
-}
-.about-text p {
- margin-bottom: 15px;
- color: var(--text-muted);
-}
-.tags span {
- background: var(--card-bg);
- border: 1px solid var(--border);
- padding: 6px 14px;
- border-radius: 50px;
- font-size: 0.85rem;
- display: inline-block;
- margin: 5px 0;
-}
-
-/* --- Projects (Clickable) --- */
-.project-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- gap: 30px;
-}
-
-/* Wrapper is now an anchor tag */
-a.project-card {
- text-decoration: none; /* Remove underline */
- color: inherit; /* Keep text color */
- background: var(--card-bg);
- border: 1px solid var(--border);
- border-radius: 12px;
- overflow: hidden;
- display: block;
- transition:
- transform 0.3s,
- border-color 0.3s;
-}
-
-a.project-card:hover {
- transform: translateY(-5px);
- border-color: var(--accent);
-}
-
-.card-img img {
- width: 100%;
- height: 200px;
- object-fit: cover;
-}
-.card-content {
- padding: 25px;
-}
-
-/* Card Header for Arrow Icon */
-.card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 10px;
-}
-.arrow-icon {
- font-size: 1.2rem;
- opacity: 0;
- transform: translateX(-10px);
- transition: 0.3s;
- color: var(--accent);
-}
-a.project-card:hover .arrow-icon {
- opacity: 1;
- transform: translateX(0);
-}
-
-.card-content p {
- color: var(--text-muted);
- font-size: 0.9rem;
- margin-bottom: 15px;
-}
-.stack-icons {
- font-size: 0.8rem;
- color: var(--accent);
- font-weight: 600;
-}
-
-/* --- Certificates Section --- */
-.cert-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
- gap: 20px;
-}
-
-.cert-card {
- background: var(--card-bg);
- border: 1px solid var(--border);
- border-radius: 12px;
- padding: 25px;
- display: flex;
- align-items: center;
- gap: 20px;
- transition: 0.3s;
-}
-
-.cert-card:hover {
- border-color: var(--accent);
-}
-
-.cert-icon {
- font-size: 2rem;
-}
-.cert-info h3 {
- font-size: 1rem;
- margin-bottom: 5px;
-}
-.issuer {
- color: var(--accent);
- font-size: 0.85rem;
- font-weight: 600;
-}
-.date {
- display: block;
- font-size: 0.75rem;
- color: var(--text-muted);
- margin-top: 5px;
-}
-
-/* --- Blog Section --- */
-.blog-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- gap: 30px;
-}
-
-.blog-card {
- background: var(--card-bg);
- border: 1px solid var(--border);
- padding: 30px;
- border-radius: 12px;
- display: flex;
- flex-direction: column;
- transition:
- transform 0.3s,
- border-color 0.3s;
- height: 100%;
-}
-
-.blog-card:hover {
- transform: translateY(-5px);
- border-color: var(--accent);
-}
-
-.blog-meta {
- display: flex;
- justify-content: space-between;
- font-size: 0.8rem;
- color: var(--text-muted);
- margin-bottom: 15px;
- text-transform: uppercase;
- letter-spacing: 1px;
-}
-
-.blog-tag {
- color: var(--accent);
- font-weight: 600;
-}
-
-.blog-title {
- font-size: 1.2rem;
- margin-bottom: 10px;
- line-height: 1.4;
-}
-
-.blog-excerpt {
- color: var(--text-muted);
- font-size: 0.95rem;
- margin-bottom: 20px;
- flex-grow: 1; /* Pushes the link to the bottom */
-}
-
-.read-more {
- text-decoration: none;
- color: var(--accent);
- font-weight: 600;
- font-size: 0.9rem;
- transition: opacity 0.2s;
-}
-
-.read-more:hover {
- opacity: 0.8;
-}
-
-/* --- View All Button Wrapper --- */
-.view-all-container {
- display: flex;
- justify-content: center;
- margin-top: 40px;
-}
-
-/* --- Social Media Buttons --- */
-.social-links {
- display: flex;
- justify-content: center;
- gap: 20px;
- margin-bottom: 40px;
-}
-
-.social-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 50px;
- height: 50px;
- border-radius: 50%; /* Makes them round */
- background: var(--card-bg);
- border: 1px solid var(--border);
- color: var(--text-muted);
- transition: all 0.3s ease;
-}
-
-.social-btn svg {
- width: 22px;
- height: 22px;
-}
-
-/* Hover Effect: Glows with the accent color */
-.social-btn:hover {
- border-color: var(--accent);
- color: var(--accent);
- transform: translateY(-3px);
- box-shadow: 0 5px 15px var(--glow);
-}
-
-/* --- Contact & Footer --- */
-.contact-container {
- max-width: 600px;
- margin: 0 auto;
- text-align: center;
-}
-.contact-container p {
- color: var(--text-muted);
- margin-bottom: 30px;
-}
-.email-form {
- display: flex;
- flex-direction: column;
- gap: 15px;
-}
-input,
-textarea {
- width: 100%;
- padding: 15px;
- background: var(--card-bg);
- border: 1px solid var(--border);
- color: var(--text-main);
- border-radius: 8px;
- font-family: inherit;
-}
-.full-width {
- width: 100%;
- cursor: pointer;
-}
-
-footer {
- padding: 50px 0;
- text-align: center;
- color: var(--text-muted); /* Maintained your font fix */
- font-size: 0.9rem;
- border-top: 1px solid var(--border);
- margin-top: auto;
-}
-
-/* --- Back to Top Button --- */
-#back-to-top {
- position: fixed;
- bottom: 30px;
- right: 30px;
- width: 50px;
- height: 50px;
- background-color: var(--accent);
- color: white; /* Arrow color */
- border-radius: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- text-decoration: none;
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
- z-index: 1000;
-
- /* Hidden state */
- opacity: 0;
- visibility: hidden;
- transform: translateY(20px);
- transition: all 0.3s ease;
-}
-
-/* Visible state (added by JS) */
-#back-to-top.show {
- opacity: 1;
- visibility: visible;
- transform: translateY(0);
-}
-
-#back-to-top:hover {
- background-color: var(--text-main); /* Inverts color on hover */
- color: var(--bg);
- transform: translateY(-5px); /* Lift effect */
-}
-
-/* Mobile Adjustment */
-@media (max-width: 600px) {
- #back-to-top {
- bottom: 20px;
- right: 20px;
- width: 45px;
- height: 45px;
- }
-}
-
-/* Mobile Content Layout */
-/* --- Mobile Menu (Max-width 768px) --- */
-@media (max-width: 768px) {
- /* Show Hamburger */
- .hamburger {
- display: block;
- }
-
- /* Animate Hamburger to X when active */
- .hamburger.active .bar:nth-child(2) {
- opacity: 0;
- }
- .hamburger.active .bar:nth-child(1) {
- transform: translateY(8px) rotate(45deg);
- }
- .hamburger.active .bar:nth-child(3) {
- transform: translateY(-8px) rotate(-45deg);
- }
-
- /* --- FIXED: Mobile Dropdown --- */
- .nav-links {
- position: absolute;
- top: 100%; /* Sits exactly below the navbar */
- left: -120vw; /* Hide completely off-screen to the left */
- flex-direction: column;
-
- /* Force it to fill the ENTIRE screen width */
- width: 100vw;
-
- text-align: center;
- transition: left 0.4s ease-in-out; /* Smooth sliding animation */
- box-shadow: 0 10px 27px rgba(0, 0, 0, 0.05);
- border-bottom: 1px solid var(--border);
- padding: 30px 0;
- gap: 20px;
-
- /* Theme-Based Transparent Background */
- background: var(--glass-bg);
- backdrop-filter: blur(15px);
- -webkit-backdrop-filter: blur(15px);
- }
-
- /* Show Links when active */
- .nav-links.active {
- /* This offsets the 5% padding of your site-wrapper
- so the menu perfectly touches the left edge of the phone screen */
- left: -5vw;
- }
-
- .nav-links a {
- color: var(--text-main);
- font-size: 1.2rem;
- display: block;
- padding: 10px;
- }
-
- /* Mobile Content Layout */
- .hero {
- flex-direction: column-reverse;
- text-align: center;
- }
- .hero-btns {
- justify-content: center;
- }
- .about-content {
- grid-template-columns: 1fr;
- }
- .cert-card {
- flex-direction: column;
- text-align: center;
- }
-}
+/* =====================================================
+ DESIGN SYSTEM — Premium Portfolio v2
+ ===================================================== */
+
+/* --- Google Fonts --- */
+@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800;900&family=Inter:wght@300;400;500;600&display=swap');
+
+/* Prevent horizontal scroll on all viewports */
+html, body { overflow-x: hidden; max-width: 100%; }
+
+/* --- CSS Variables (Dark Mode Default) --- */
+:root {
+ /* Backgrounds */
+ --bg: #050814;
+ --bg-secondary: #0d1225;
+ --card-bg: rgba(255, 255, 255, 0.035);
+ --card-border: rgba(255, 255, 255, 0.08);
+ --glass-bg: rgba(5, 8, 20, 0.75);
+
+ /* Text */
+ --text-main: #f0f4ff;
+ --text-muted: #8892b0;
+ --text-subtle: #4a5578;
+
+ /* Accents */
+ --accent: #7c3aed;
+ --accent-2: #6366f1;
+ --accent-glow: rgba(124, 58, 237, 0.4);
+ --grad-1: #7c3aed;
+ --grad-2: #6366f1;
+ --grad-3: #06b6d4;
+
+ /* Borders */
+ --border: rgba(255, 255, 255, 0.08);
+ --border-hover: rgba(124, 58, 237, 0.5);
+
+ /* Shadows */
+ --shadow-card: 0 4px 32px rgba(0, 0, 0, 0.4);
+ --shadow-glow: 0 0 40px rgba(124, 58, 237, 0.25);
+
+ /* Transitions */
+ --ease: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+/* --- Light Mode Overrides --- */
+.toggle-checkbox:not(:checked) ~ .site-wrapper {
+ --bg: #f8f7ff;
+ --bg-secondary: #ede9fe;
+ --card-bg: rgba(255, 255, 255, 0.7);
+ --card-border: rgba(124, 58, 237, 0.15);
+ --glass-bg: rgba(248, 247, 255, 0.85);
+ --text-main: #1e1b4b;
+ --text-muted: #5b5698;
+ --text-subtle: #9ca3af;
+ --accent: #7c3aed;
+ --accent-glow: rgba(124, 58, 237, 0.2);
+ --border: rgba(124, 58, 237, 0.12);
+ --border-hover: rgba(124, 58, 237, 0.45);
+ --shadow-card: 0 4px 24px rgba(124, 58, 237, 0.1);
+ --shadow-glow: 0 0 40px rgba(124, 58, 237, 0.15);
+}
+
+/* =====================================================
+ RESET & BASE
+ ===================================================== */
+*, *::before, *::after {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ scroll-behavior: smooth;
+ font-size: 16px;
+}
+
+/* Custom Scrollbar */
+html::-webkit-scrollbar { width: 6px; }
+html::-webkit-scrollbar-track { background: var(--bg); }
+html::-webkit-scrollbar-thumb {
+ background: linear-gradient(to bottom, var(--grad-1), var(--grad-2));
+ border-radius: 3px;
+}
+html::-webkit-scrollbar-thumb:hover { background: var(--grad-1); }
+
+body {
+ font-family: 'Inter', sans-serif;
+ line-height: 1.6;
+ background: var(--bg);
+ color: var(--text-main);
+ overflow-x: hidden;
+}
+
+/* Hidden toggle */
+.toggle-checkbox { display: none; }
+
+/* =====================================================
+ ANIMATED MESH BACKGROUND
+ ===================================================== */
+.mesh-bg {
+ position: fixed;
+ inset: 0;
+ z-index: 0;
+ pointer-events: none;
+ overflow: hidden;
+}
+
+.orb {
+ position: absolute;
+ border-radius: 50%;
+ filter: blur(100px);
+ opacity: 0.15;
+ animation: float-orb 20s ease-in-out infinite;
+}
+
+.orb-1 {
+ width: 600px; height: 600px;
+ background: radial-gradient(circle, #7c3aed, transparent 70%);
+ top: -200px; left: -200px;
+ animation-duration: 25s;
+ animation-delay: 0s;
+}
+
+.orb-2 {
+ width: 500px; height: 500px;
+ background: radial-gradient(circle, #6366f1, transparent 70%);
+ top: 30%; right: -150px;
+ animation-duration: 20s;
+ animation-delay: -8s;
+ opacity: 0.12;
+}
+
+.orb-3 {
+ width: 400px; height: 400px;
+ background: radial-gradient(circle, #06b6d4, transparent 70%);
+ bottom: 10%; left: 20%;
+ animation-duration: 30s;
+ animation-delay: -15s;
+ opacity: 0.08;
+}
+
+@keyframes float-orb {
+ 0%, 100% { transform: translate(0, 0) scale(1); }
+ 33% { transform: translate(40px, -60px) scale(1.08); }
+ 66% { transform: translate(-30px, 40px) scale(0.95); }
+}
+
+/* Light mode: softer orbs */
+.toggle-checkbox:not(:checked) ~ .mesh-bg .orb { opacity: 0.07; }
+
+/* =====================================================
+ SITE WRAPPER
+ ===================================================== */
+.site-wrapper {
+ position: relative;
+ z-index: 1;
+ min-height: 100vh;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ transition: background-color 0.4s var(--ease), color 0.4s var(--ease);
+}
+
+/* =====================================================
+ NAVIGATION
+ ===================================================== */
+nav {
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 16px 5%;
+ width: 100%;
+ background: var(--glass-bg);
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+ border-bottom: 1px solid var(--border);
+ transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
+}
+
+.logo {
+ font-family: 'Outfit', sans-serif;
+ font-weight: 900;
+ font-size: 1.6rem;
+ letter-spacing: -2px;
+ background: linear-gradient(135deg, var(--grad-1), var(--grad-2), var(--grad-3));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.nav-links {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.nav-links a {
+ color: var(--text-muted);
+ text-decoration: none;
+ font-size: 0.9rem;
+ font-weight: 500;
+ padding: 7px 14px;
+ border-radius: 8px;
+ transition: color 0.2s var(--ease), background 0.2s var(--ease);
+ letter-spacing: 0.02em;
+}
+
+.nav-links a:hover {
+ color: var(--text-main);
+ background: var(--card-bg);
+}
+
+.nav-links a.active-nav {
+ color: var(--accent);
+ background: rgba(124, 58, 237, 0.1);
+}
+
+/* Theme Toggle */
+.mode-btn {
+ cursor: pointer;
+ margin-left: 8px;
+ width: 38px;
+ height: 38px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 10px;
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ font-size: 1.1rem;
+ transition: background 0.2s, border-color 0.2s, transform 0.2s;
+ user-select: none;
+}
+.mode-btn:hover { border-color: var(--border-hover); transform: scale(1.05); }
+
+.toggle-checkbox:checked ~ .site-wrapper .icon-sun { display: none; }
+.toggle-checkbox:checked ~ .site-wrapper .icon-moon { display: flex; }
+.toggle-checkbox:not(:checked) ~ .site-wrapper .icon-moon { display: none; }
+.toggle-checkbox:not(:checked) ~ .site-wrapper .icon-sun { display: flex; }
+
+/* Hamburger */
+.hamburger {
+ display: none;
+ cursor: pointer;
+ flex-direction: column;
+ gap: 5px;
+ padding: 4px;
+}
+.bar {
+ display: block;
+ width: 24px;
+ height: 2px;
+ background: var(--text-main);
+ border-radius: 2px;
+ transition: all 0.3s var(--ease);
+}
+.hamburger.active .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
+.hamburger.active .bar:nth-child(2) { opacity: 0; transform: scaleX(0); }
+.hamburger.active .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
+
+/* =====================================================
+ SCROLL REVEAL
+ ===================================================== */
+.reveal {
+ opacity: 0;
+ transform: translateY(40px);
+ transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
+}
+.reveal.active {
+ opacity: 1;
+ transform: translateY(0);
+}
+.reveal-delay-1 { transition-delay: 0.1s; }
+.reveal-delay-2 { transition-delay: 0.2s; }
+.reveal-delay-3 { transition-delay: 0.3s; }
+.reveal-delay-4 { transition-delay: 0.4s; }
+
+/* =====================================================
+ HERO SECTION
+ ===================================================== */
+.hero {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 60px;
+ padding: clamp(60px, 10vw, 120px) 5% clamp(50px, 8vw, 100px);
+ max-width: 1100px;
+ margin: 0 auto;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.hero-text { flex: 1; }
+
+.hero-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ background: rgba(124, 58, 237, 0.1);
+ border: 1px solid rgba(124, 58, 237, 0.3);
+ border-radius: 50px;
+ padding: 6px 16px;
+ font-size: 0.8rem;
+ font-weight: 600;
+ color: var(--accent-2);
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ margin-bottom: 20px;
+}
+.hero-badge .dot {
+ width: 7px; height: 7px;
+ background: #22c55e;
+ border-radius: 50%;
+ animation: pulse-dot 2s ease-in-out infinite;
+}
+@keyframes pulse-dot {
+ 0%, 100% { opacity: 1; transform: scale(1); }
+ 50% { opacity: 0.6; transform: scale(0.8); }
+}
+
+h1 {
+ font-family: 'Outfit', sans-serif;
+ font-size: clamp(2.8rem, 5.5vw, 4rem);
+ font-weight: 900;
+ line-height: 1.05;
+ letter-spacing: -2px;
+ margin-bottom: 20px;
+ color: var(--text-main);
+}
+
+.highlight {
+ background: linear-gradient(135deg, var(--grad-1) 0%, var(--grad-2) 50%, var(--grad-3) 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.subtitle {
+ color: var(--text-muted);
+ font-size: clamp(0.95rem, 2vw, 1.1rem);
+ margin-bottom: 30px;
+ max-width: 500px;
+ line-height: 1.7;
+}
+
+.hero-btns {
+ display: flex;
+ gap: 14px;
+ flex-wrap: wrap;
+}
+
+/* =====================================================
+ BUTTONS
+ ===================================================== */
+.btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ text-decoration: none;
+ padding: 13px 26px;
+ border-radius: 10px;
+ font-weight: 600;
+ font-size: 0.95rem;
+ transition: all 0.25s var(--ease);
+ border: none;
+ cursor: pointer;
+ font-family: inherit;
+ letter-spacing: 0.01em;
+}
+
+.btn.primary {
+ background: linear-gradient(135deg, var(--grad-1), var(--grad-2));
+ color: #fff;
+ box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4);
+}
+.btn.primary:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 30px rgba(124, 58, 237, 0.5);
+}
+
+.btn.secondary {
+ background: var(--card-bg);
+ color: var(--text-main);
+ border: 1px solid var(--border);
+ backdrop-filter: blur(10px);
+}
+.btn.secondary:hover {
+ transform: translateY(-2px);
+ border-color: var(--border-hover);
+ background: rgba(124, 58, 237, 0.08);
+}
+
+.btn.full-width { width: 100%; justify-content: center; }
+
+/* =====================================================
+ HERO PROFILE IMAGE
+ ===================================================== */
+.hero-img-container {
+ position: relative;
+ width: 280px;
+ height: 280px;
+ flex-shrink: 0;
+}
+
+.img-ring {
+ position: absolute;
+ inset: -12px;
+ border-radius: 28px;
+ background: linear-gradient(135deg, var(--grad-1), var(--grad-2), var(--grad-3));
+ z-index: 0;
+ opacity: 0.6;
+ animation: spin-ring 8s linear infinite;
+}
+@keyframes spin-ring {
+ 0% { filter: blur(4px) hue-rotate(0deg); }
+ 100% { filter: blur(4px) hue-rotate(360deg); }
+}
+
+.profile-pic {
+ position: absolute;
+ top: 0; left: 0;
+ width: 100%; height: 100%;
+ object-fit: cover;
+ border-radius: 20px;
+ border: 2px solid var(--border);
+ z-index: 2;
+ transition: opacity 0.4s var(--ease);
+ opacity: 0;
+}
+
+/* Dark mode (default) image states */
+.img-night-normal { opacity: 1; z-index: 3; cursor: default; }
+.hero-img-container:hover .img-night-hover { opacity: 1; z-index: 4; cursor: default; }
+.hero-img-container:hover .img-night-normal { opacity: 0; }
+
+/* Light mode image states */
+.toggle-checkbox:not(:checked) ~ .site-wrapper .img-night-normal,
+.toggle-checkbox:not(:checked) ~ .site-wrapper .img-night-hover { opacity: 0 !important; }
+.toggle-checkbox:not(:checked) ~ .site-wrapper .img-day-normal { opacity: 1; z-index: 3; cursor: default; }
+.toggle-checkbox:not(:checked) ~ .site-wrapper .hero-img-container:hover .img-day-hover { opacity: 1; z-index: 4; cursor: default; }
+.toggle-checkbox:not(:checked) ~ .site-wrapper .hero-img-container:hover .img-day-normal { opacity: 0; }
+
+.glow-effect {
+ position: absolute;
+ inset: 0;
+ background: var(--accent);
+ border-radius: 20px;
+ opacity: 0.12;
+ z-index: 1;
+ filter: blur(30px);
+ transform: translate(10px, 10px);
+ transition: opacity 0.4s;
+}
+.hero-img-container:hover .glow-effect { opacity: 0.2; }
+
+/* =====================================================
+ SECTION COMMONS
+ ===================================================== */
+.section-pad {
+ padding: clamp(60px, 8vw, 100px) 5%;
+ max-width: 1100px;
+ margin: 0 auto;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.section-header {
+ margin-bottom: 60px;
+}
+
+.section-label {
+ display: inline-block;
+ font-size: 0.75rem;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.15em;
+ color: var(--accent-2);
+ margin-bottom: 12px;
+}
+
+.section-title {
+ font-family: 'Outfit', sans-serif;
+ font-size: clamp(1.8rem, 3vw, 2.5rem);
+ font-weight: 800;
+ letter-spacing: -1px;
+ background: linear-gradient(135deg, var(--text-main) 60%, var(--text-muted));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+/* =====================================================
+ ABOUT SECTION
+ ===================================================== */
+.about-content {
+ display: grid;
+ grid-template-columns: 3fr 2fr;
+ gap: 60px;
+ align-items: start;
+}
+
+.about-text p {
+ color: var(--text-muted);
+ margin-bottom: 18px;
+ font-size: 1.05rem;
+ line-height: 1.8;
+}
+.about-text p strong { color: var(--text-main); font-weight: 600; }
+
+.tech-stack h3 {
+ font-family: 'Outfit', sans-serif;
+ font-size: 1rem;
+ font-weight: 700;
+ color: var(--text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ margin-bottom: 16px;
+}
+
+.tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.tags span {
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ padding: 7px 16px;
+ border-radius: 50px;
+ font-size: 0.82rem;
+ font-weight: 600;
+ color: var(--text-muted);
+ letter-spacing: 0.02em;
+ transition: all 0.2s var(--ease);
+ backdrop-filter: blur(10px);
+}
+.tags span:hover {
+ border-color: var(--border-hover);
+ color: var(--accent-2);
+ background: rgba(124, 58, 237, 0.08);
+ transform: translateY(-1px);
+}
+
+/* =====================================================
+ STATS ROW
+ ===================================================== */
+.stats-row {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 20px;
+ margin-top: 50px;
+ padding-top: 50px;
+ border-top: 1px solid var(--border);
+}
+
+.stat-item {
+ text-align: center;
+}
+.stat-number {
+ font-family: 'Outfit', sans-serif;
+ font-size: 2.2rem;
+ font-weight: 900;
+ background: linear-gradient(135deg, var(--grad-1), var(--grad-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ line-height: 1;
+ margin-bottom: 6px;
+}
+.stat-label {
+ font-size: 0.8rem;
+ color: var(--text-muted);
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+}
+
+/* =====================================================
+ PROJECT CARDS
+ ===================================================== */
+.project-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
+ gap: 24px;
+}
+
+a.project-card {
+ text-decoration: none;
+ color: inherit;
+ display: block;
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ border-radius: 16px;
+ overflow: hidden;
+ transition: transform 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
+ backdrop-filter: blur(10px);
+}
+a.project-card:hover {
+ transform: translateY(-6px);
+ border-color: var(--border-hover);
+ box-shadow: var(--shadow-glow);
+}
+
+.card-img {
+ position: relative;
+ height: 200px;
+ overflow: hidden;
+}
+.card-img img {
+ width: 100%; height: 100%;
+ object-fit: cover;
+ transition: transform 0.5s var(--ease);
+}
+a.project-card:hover .card-img img { transform: scale(1.05); }
+
+.card-img-overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(to bottom, transparent 40%, rgba(5, 8, 20, 0.8));
+ transition: opacity 0.3s;
+}
+
+.card-content { padding: 24px; }
+
+.card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 10px;
+ gap: 10px;
+}
+.card-header h3 {
+ font-family: 'Outfit', sans-serif;
+ font-size: 1.15rem;
+ font-weight: 700;
+ color: var(--text-main);
+ line-height: 1.3;
+}
+.arrow-icon {
+ font-size: 1.1rem;
+ opacity: 0;
+ transform: translate(-6px, 6px);
+ transition: all 0.3s var(--ease);
+ color: var(--accent-2);
+ flex-shrink: 0;
+}
+a.project-card:hover .arrow-icon {
+ opacity: 1;
+ transform: translate(0, 0);
+}
+
+.card-content p {
+ color: var(--text-muted);
+ font-size: 0.88rem;
+ margin-bottom: 18px;
+ line-height: 1.7;
+}
+
+.stack-badges {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+.stack-badge {
+ padding: 4px 10px;
+ border-radius: 50px;
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ background: rgba(99, 102, 241, 0.1);
+ border: 1px solid rgba(99, 102, 241, 0.25);
+ color: var(--accent-2);
+}
+
+/* =====================================================
+ CERTIFICATIONS
+ ===================================================== */
+.cert-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
+ gap: 20px;
+}
+
+.cert-card {
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ border-radius: 16px;
+ padding: 28px;
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ transition: all 0.3s var(--ease);
+ backdrop-filter: blur(10px);
+ cursor: default;
+}
+.cert-card:hover {
+ border-color: var(--border-hover);
+ transform: translateY(-3px);
+ box-shadow: var(--shadow-glow);
+}
+
+.cert-icon {
+ font-size: 2rem;
+ width: 56px;
+ height: 56px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(124, 58, 237, 0.1);
+ border: 1px solid rgba(124, 58, 237, 0.2);
+ border-radius: 14px;
+ flex-shrink: 0;
+ transition: background 0.3s;
+}
+.cert-card:hover .cert-icon { background: rgba(124, 58, 237, 0.18); }
+
+.cert-info h3 {
+ font-family: 'Outfit', sans-serif;
+ font-size: 1rem;
+ font-weight: 700;
+ margin-bottom: 4px;
+ color: var(--text-main);
+}
+.issuer {
+ color: var(--accent-2);
+ font-size: 0.82rem;
+ font-weight: 600;
+}
+.date {
+ display: block;
+ font-size: 0.75rem;
+ color: var(--text-subtle);
+ margin-top: 4px;
+}
+
+/* =====================================================
+ BLOG CARDS
+ ===================================================== */
+.blog-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
+ gap: 24px;
+}
+
+.blog-card {
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ padding: 32px;
+ border-radius: 16px;
+ display: flex;
+ flex-direction: column;
+ transition: all 0.3s var(--ease);
+ backdrop-filter: blur(10px);
+}
+.blog-card:hover {
+ transform: translateY(-5px);
+ border-color: var(--border-hover);
+ box-shadow: var(--shadow-glow);
+}
+
+.blog-meta {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 0.75rem;
+ color: var(--text-subtle);
+ margin-bottom: 16px;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+ font-weight: 600;
+}
+.blog-tag {
+ color: var(--accent-2);
+ background: rgba(99, 102, 241, 0.1);
+ border: 1px solid rgba(99, 102, 241, 0.2);
+ padding: 3px 10px;
+ border-radius: 50px;
+}
+
+.blog-title {
+ font-family: 'Outfit', sans-serif;
+ font-size: 1.15rem;
+ font-weight: 700;
+ margin-bottom: 12px;
+ line-height: 1.4;
+ color: var(--text-main);
+}
+
+.blog-excerpt {
+ color: var(--text-muted);
+ font-size: 0.9rem;
+ margin-bottom: 24px;
+ flex-grow: 1;
+ line-height: 1.7;
+}
+
+.read-more {
+ text-decoration: none;
+ color: var(--accent-2);
+ font-weight: 600;
+ font-size: 0.85rem;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ transition: gap 0.2s var(--ease), opacity 0.2s;
+}
+.read-more:hover { gap: 10px; opacity: 0.8; }
+
+/* =====================================================
+ VIEW ALL BUTTON
+ ===================================================== */
+.view-all-container {
+ display: flex;
+ justify-content: center;
+ margin-top: 50px;
+}
+
+/* =====================================================
+ CONTACT SECTION
+ ===================================================== */
+.contact-container {
+ max-width: 620px;
+ margin: 0 auto;
+ text-align: center;
+}
+.contact-container > p {
+ color: var(--text-muted);
+ margin-bottom: 40px;
+ font-size: 1.05rem;
+ line-height: 1.8;
+}
+
+.social-links {
+ display: flex;
+ justify-content: center;
+ gap: 14px;
+ margin-bottom: 50px;
+}
+
+.social-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 50px;
+ height: 50px;
+ border-radius: 13px;
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ color: var(--text-muted);
+ transition: all 0.25s var(--ease);
+ text-decoration: none;
+}
+.social-btn svg { width: 20px; height: 20px; }
+.social-btn:hover {
+ border-color: var(--border-hover);
+ color: var(--accent-2);
+ transform: translateY(-3px);
+ background: rgba(124, 58, 237, 0.08);
+ box-shadow: 0 4px 20px rgba(124, 58, 237, 0.2);
+}
+
+.email-form {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+ text-align: left;
+}
+
+input, textarea {
+ width: 100%;
+ padding: 14px 18px;
+ background: var(--card-bg);
+ border: 1px solid var(--border);
+ color: var(--text-main);
+ border-radius: 12px;
+ font-family: inherit;
+ font-size: 0.95rem;
+ transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease), background 0.25s;
+ backdrop-filter: blur(10px);
+ outline: none;
+}
+input::placeholder, textarea::placeholder { color: var(--text-subtle); }
+input:focus, textarea:focus {
+ border-color: var(--border-hover);
+ box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.15);
+ background: rgba(124, 58, 237, 0.03);
+}
+
+/* reCAPTCHA centering */
+.g-recaptcha { display: flex; justify-content: center; }
+
+/* =====================================================
+ FOOTER
+ ===================================================== */
+footer {
+ padding: 50px 5%;
+ text-align: center;
+ color: var(--text-subtle);
+ font-size: 0.85rem;
+ border-top: 1px solid var(--border);
+ margin-top: auto;
+}
+
+/* =====================================================
+ BACK TO TOP
+ ===================================================== */
+#back-to-top {
+ position: fixed;
+ bottom: 30px;
+ right: 30px;
+ width: 48px;
+ height: 48px;
+ background: linear-gradient(135deg, var(--grad-1), var(--grad-2));
+ color: white;
+ border-radius: 13px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ text-decoration: none;
+ box-shadow: 0 4px 20px rgba(124, 58, 237, 0.4);
+ z-index: 999;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(20px);
+ transition: all 0.3s var(--ease);
+}
+#back-to-top.show {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+#back-to-top:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 30px rgba(124, 58, 237, 0.5);
+}
+
+/* =====================================================
+ PAGE HERO (Sub-pages)
+ ===================================================== */
+.page-hero {
+ padding: clamp(50px, 8vw, 80px) 5% clamp(40px, 6vw, 60px);
+ max-width: 1100px;
+ margin: 0 auto;
+ width: 100%;
+ box-sizing: border-box;
+}
+.page-hero h1 { font-size: clamp(1.8rem, 5vw, 3rem); margin-bottom: 14px; }
+.page-hero .subtitle { max-width: 500px; }
+
+/* =====================================================
+ DIVIDER
+ ===================================================== */
+.section-divider {
+ height: 1px;
+ background: linear-gradient(to right, transparent, var(--border), transparent);
+ margin: 0 5%;
+}
+
+/* =====================================================
+ RESPONSIVE — TABLET (≤ 900px)
+ ===================================================== */
+@media (max-width: 900px) {
+ .hero { gap: 40px; }
+ .hero-img-container { width: 220px; height: 220px; }
+ .about-content { grid-template-columns: 1fr; gap: 40px; }
+ .stats-row { grid-template-columns: repeat(3, 1fr); }
+}
+
+/* =====================================================
+ RESPONSIVE — MOBILE (≤ 768px)
+ ===================================================== */
+@media (max-width: 768px) {
+ /* Hamburger visible */
+ .hamburger { display: flex; }
+
+ /* Nav desktop links hidden by default on mobile */
+ .nav-links {
+ /* Nav is full viewport width (no container offset), so left: 0 = screen edge */
+ position: fixed;
+ top: 0;
+ left: -100vw; /* hide completely off-screen */
+ width: 100vw;
+ height: 100vh;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ padding: 40px 20px;
+ gap: 8px;
+ background: var(--glass-bg);
+ backdrop-filter: blur(24px);
+ -webkit-backdrop-filter: blur(24px);
+ border-right: 1px solid var(--border);
+ transition: left 0.35s var(--ease);
+ z-index: 999;
+ box-shadow: 4px 0 40px rgba(0, 0, 0, 0.3);
+ }
+ /* Slide in from left */
+ .nav-links.active { left: 0; }
+
+ .nav-links a {
+ font-size: 1.2rem;
+ font-weight: 600;
+ display: block;
+ padding: 14px 30px;
+ width: 100%;
+ border-radius: 12px;
+ }
+
+ /* Close button (mode-btn) repositioned */
+ .mode-btn {
+ margin-top: 20px;
+ margin-left: 0;
+ }
+
+ /* Hero */
+ .hero {
+ flex-direction: column-reverse;
+ text-align: center;
+ gap: 30px;
+ }
+ .hero-btns { justify-content: center; flex-wrap: wrap; }
+ .subtitle { margin: 0 auto 24px; }
+ .hero-badge { margin: 0 auto 16px; }
+ .hero-img-container { width: 180px; height: 180px; }
+
+ /* Stats */
+ .stats-row { grid-template-columns: repeat(3, 1fr); gap: 8px; }
+ .stat-number { font-size: 1.6rem; }
+ .stat-label { font-size: 0.7rem; }
+
+ /* Certs */
+ .cert-card { flex-direction: column; text-align: center; }
+
+ /* Project grid single column on very narrow */
+ .project-grid,
+ .blog-grid {
+ grid-template-columns: 1fr;
+ }
+
+ /* Back to top smaller */
+ #back-to-top { bottom: 16px; right: 16px; width: 42px; height: 42px; }
+
+ /* Section divider */
+ .section-divider { margin: 0 4%; }
+}
+
+/* =====================================================
+ RESPONSIVE — SMALL MOBILE (≤ 480px)
+ ===================================================== */
+@media (max-width: 480px) {
+ h1 { letter-spacing: -1px; }
+ .stats-row { grid-template-columns: repeat(3, 1fr); }
+ .cert-grid { grid-template-columns: 1fr; }
+ .btn { padding: 11px 18px; font-size: 0.9rem; }
+ .hero-img-container { width: 150px; height: 150px; }
+ .social-links { gap: 10px; }
+ .social-btn { width: 44px; height: 44px; }
+}
diff --git a/blog.php b/blog.php
index 2bd7dbc..467313d 100755
--- a/blog.php
+++ b/blog.php
@@ -1,124 +1,117 @@
-
-
-
-
-
- Blog | Cris Charles Garcia
-
-
-
-
-
-
-
-
-
-
- CG.
-
-
-
-
-
-
-
-
-
-
- Feb 10, 2026
- React
-
- Understanding Custom Hooks in React
- Why you should stop copying code and start abstracting logic into reusable hooks.
- Read Article →
-
-
-
-
- Jan 22, 2026
- DevOps
-
- Why I Switched from XAMPP to Docker
- Setting up a consistent development environment for PHP and Node.js without the headache.
- Read Article →
-
-
-
-
- Dec 05, 2025
- Career
-
- My Journey as a BSIT Student
- Balancing capstone projects, freelance work, and learning new tech stacks in 2026.
- Read Article →
-
-
-
-
- Nov 15, 2025
- CSS
-
- Dark Mode in 5 Minutes
- How to implement a pure CSS dark mode toggle without flashing content.
- Read Article →
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Blog | Cris Charles Garcia
+
+
+
+
+
+
+
+
+
+
+
+
+ CG.
+
+
+
+
+
Writing
+
Writing & Thoughts
+
Tutorials, tech reviews, and updates from my developer journey.
+
+
+
+
+
+
+
+
+
+ Feb 10, 2026
+ React
+
+ Understanding Custom Hooks in React
+ Why you should stop copying code and start abstracting logic into reusable hooks. A deep dive into the why and how.
+ Read Article →
+
+
+
+
+ Jan 22, 2026
+ DevOps
+
+ Why I Switched from XAMPP to Docker
+ Setting up a consistent development environment for PHP and Node.js without the headache. Containers changed everything.
+ Read Article →
+
+
+
+
+ Dec 05, 2025
+ Career
+
+ My Journey as a BSIT Student
+ Balancing capstone projects, freelance work, and learning new tech stacks in 2026.
+ Read Article →
+
+
+
+
+ Nov 15, 2025
+ CSS
+
+ Dark Mode in 5 Minutes
+ How to implement a pure CSS dark mode toggle without flashing content. The trick most tutorials miss.
+ Read Article →
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/certifications.php b/certifications.php
index 6015d95..b9c82be 100755
--- a/certifications.php
+++ b/certifications.php
@@ -1,132 +1,132 @@
-
-
-
-
-
- Certifications | Cris Charles Garcia
-
-
-
-
-
-
-
-
-
-
- CG.
-
-
-
-
-
-
-
-
-
🏆
-
-
Responsive Web Design
-
FreeCodeCamp
-
Issued Dec 2024
-
-
-
-
📜
-
-
JavaScript Algorithms
-
HackerRank
-
Issued Nov 2024
-
-
-
-
☁️
-
-
Cloud Fundamentals
-
AWS
-
Issued Oct 2024
-
-
-
-
🐍
-
-
Python for Data Science
-
Coursera
-
Issued Sept 2024
-
-
-
-
🔒
-
-
Cybersecurity Essentials
-
Cisco
-
Issued Aug 2024
-
-
-
-
⚛️
-
-
React Advanced Patterns
-
Udemy
-
Issued July 2024
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ Certifications | Cris Charles Garcia
+
+
+
+
+
+
+
+
+
+
+
+
+ CG.
+
+
+
+
+
Credentials
+
Certifications
+
Qualifications and courses I have completed.
+
+
+
+
+
+
+
+
+
🏆
+
+
Responsive Web Design
+
FreeCodeCamp
+
Issued Dec 2024
+
+
+
+
+
📜
+
+
JavaScript Algorithms
+
HackerRank
+
Issued Nov 2024
+
+
+
+
+
☁️
+
+
Cloud Fundamentals
+
AWS
+
Issued Oct 2024
+
+
+
+
+
🐍
+
+
Python for Data Science
+
Coursera
+
Issued Sept 2024
+
+
+
+
+
🔒
+
+
Cybersecurity Essentials
+
Cisco
+
Issued Aug 2024
+
+
+
+
+
⚛️
+
+
React Advanced Patterns
+
Udemy
+
Issued July 2024
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/db.php b/config/db.php
index b18d3ec..57b5090 100644
--- a/config/db.php
+++ b/config/db.php
@@ -1,17 +1,46 @@
DB config missing. Please create a .env file from .env.example
');
+}
+
$mysqli = new mysqli($host, $ngalan, $sikreto, $deytabeys);
if ($mysqli->connect_error) {
- die("Connection failed: " . $mysqli->connect_error);
+ die('Connection failed: ' . htmlspecialchars($mysqli->connect_error) . '
');
}
-echo "";
?>
\ No newline at end of file
diff --git a/index.php b/index.php
index 0a45abb..df7d4cb 100755
--- a/index.php
+++ b/index.php
@@ -1,116 +1,155 @@
+
+
Cris Charles Garcia | Software Developer
-
-
-
-
-
+
+
+
+
+
-
+
+
+
CG.
-
-
+
+
-
-
About
-
Work
-
Certs
-
Blog
-
Contact
-
-
+
+
-
Hi, I'm Cris Charles Garcia
+
+
+ Available for opportunities
+
+
Hi, I'm Cris Charles Garcia
Building digital products with purpose .
-
BSIT Software Development Student based in Laguna, Philippines.
+
BSIT Software Development student based in Laguna, Philippines — turning ideas into scalable, polished web experiences.
+
+
+
- About Me
+
-
I am a senior BSIT student majoring in Software Development with a passion for building scalable web applications.
-
Currently, I focus on the MERN Stack and PHP ecosystems. I love solving complex problems, whether it's architecting a database or designing a seamless UI.
+
I am a senior BSIT student majoring in Software Development with a passion for building scalable web applications that solve real-world problems.
+
Currently focused on the MERN Stack and PHP ecosystems. I love solving complex challenges — whether it's architecting a database, designing a seamless UI, or squashing that one annoying bug.
Tech Stack
+
+
+
+
+
- Featured Work
-
-
-
-
+
+
+
-
+
+
+
- Certifications
+
-
+
🏆
Responsive Web Design
@@ -118,7 +157,7 @@
Issued Dec 2024
-
+
📜
JavaScript Algorithms
@@ -126,7 +165,7 @@
Issued Nov 2024
-
+
☁️
Cloud Fundamentals
@@ -135,17 +174,21 @@
-
+
+
+
- Latest Articles
+
-
-
+
Feb 10, 2026
React
@@ -154,8 +197,7 @@
Why you should stop copying code and start abstracting logic into reusable hooks.
Read Article →
-
-
+
Jan 22, 2026
DevOps
@@ -164,8 +206,7 @@
Setting up a consistent development environment for PHP and Node.js without the headache.
Read Article →
-
-
+
Dec 05, 2025
Career
@@ -174,136 +215,129 @@
Balancing capstone projects, freelance work, and learning new tech stacks in 2026.
Read Article →
-
-
+
+
+
-
-
-
+
+
+
-
+ // 5. HAMBURGER MENU
+ const hamburger = document.getElementById("hamburger");
+ const navLinks = document.getElementById("nav-links");
+ const navItems = document.querySelectorAll(".nav-item");
+
+ function closeMenu() {
+ hamburger.classList.remove("active");
+ navLinks.classList.remove("active");
+ hamburger.setAttribute("aria-expanded", "false");
+ }
+
+ hamburger.addEventListener("click", (e) => {
+ e.stopPropagation();
+ const isOpen = hamburger.classList.toggle("active");
+ navLinks.classList.toggle("active");
+ hamburger.setAttribute("aria-expanded", isOpen);
+ });
+
+ // Close on nav link click
+ navItems.forEach(item => item.addEventListener("click", closeMenu));
+
+ // Close when clicking outside the menu
+ document.addEventListener("click", (e) => {
+ if (navLinks.classList.contains("active") && !navLinks.contains(e.target) && !hamburger.contains(e.target)) {
+ closeMenu();
+ }
+ });
+
+ // Close on scroll
+ window.addEventListener('scroll', () => {
+ if (navLinks.classList.contains('active')) {
+ closeMenu();
+ }
+ });
+ });
+
+ // Prevent right-click & drag on images
+ document.addEventListener("contextmenu", e => { if (e.target.tagName === 'IMG') e.preventDefault(); });
+ document.addEventListener("dragstart", e => { if (e.target.tagName === 'IMG') e.preventDefault(); });
+
\ No newline at end of file
diff --git a/projects.php b/projects.php
index cbe7b11..c2d36b8 100755
--- a/projects.php
+++ b/projects.php
@@ -3,84 +3,76 @@
+
All Projects | Cris Charles Garcia
-
-
+
+
+
+
CG.
-
+
+
Portfolio
+
Project Archive
+
A complete list of apps, websites, and experiments I've built.
+
+
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/views/projects.php b/views/projects.php
index 92317b3..5576b6a 100644
--- a/views/projects.php
+++ b/views/projects.php
@@ -1,35 +1,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
- No projects found in the database.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No projects found in the database.
\ No newline at end of file
diff --git a/views/tprojects.php b/views/tprojects.php
index 6557b1d..b0dd474 100644
--- a/views/tprojects.php
+++ b/views/tprojects.php
@@ -1,35 +1,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
- No projects found in the database.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No projects found in the database.
\ No newline at end of file