From 3ca644d0c1539130a6c32634145a575db2850cb7 Mon Sep 17 00:00:00 2001 From: vimal-tech-starter Date: Fri, 20 Feb 2026 03:27:02 +0530 Subject: [PATCH 01/17] Service improvement done Signed-off-by: vimal-tech-starter Signed-off-by: vimal-java-dev --- css/services.css | 70 ++++++- expertise.html | 16 +- index.html | 2 +- js/services.js | 26 +++ seo/services-faq.schema.html | 40 ++++ seo/services.schema.html | 78 ++++++++ services.html | 353 ++++++++++++++++++++++++++++++++--- 7 files changed, 546 insertions(+), 39 deletions(-) create mode 100644 seo/services-faq.schema.html create mode 100644 seo/services.schema.html diff --git a/css/services.css b/css/services.css index 2cf4b19..953bd64 100644 --- a/css/services.css +++ b/css/services.css @@ -255,7 +255,9 @@ body.dark .service-card:hover p { /* Icon Bounce Animation */ @keyframes iconBounce { - 0%, 100% { + + 0%, + 100% { transform: translateY(0); } @@ -277,12 +279,70 @@ body.dark #services-offer { /* Wrapper for centering card horizontally */ .card-container { - display: flex; - justify-content: center; - width: 100%; - /* margin-top: 10px; */ + display: flex; + justify-content: center; + width: 100%; + /* margin-top: 10px; */ } body.dark .hamburger { color: #000; +} + +/* Accordion Styles */ +.accordion-header { + display: flex; + align-items: center; + justify-content: space-between; + cursor: pointer; +} + +.accordion-header h3 { + flex: 1; + margin-left: 12px; +} + +.accordion-icon { + font-size: 22px; + font-weight: bold; + transition: transform 0.3s ease; +} + +.accordion-body { + max-height: 0; + overflow: hidden; + transition: max-height 0.4s ease; + margin-top: 10px; +} + +.accordion-item.active .accordion-body { + max-height: 300px; + /* safe default */ +} + +.accordion-item.active .accordion-icon { + transform: rotate(45deg); + /* + becomes × */ +} + +/* Services Help Your Business */ +#services-help-business { + text-align: center; + background-color: #ced4da; +} + +body.dark #services-help-business { + background-color: #467db4; + color: #000; +} + +/* Let’s Build Something Solid */ +#lets-build { + text-align: center; + background-color: #ced4da; +} + +body.dark #lets-build { + background-color: #467db4; + color: #000; } \ No newline at end of file diff --git a/expertise.html b/expertise.html index 40c06ac..863c6f5 100644 --- a/expertise.html +++ b/expertise.html @@ -68,11 +68,14 @@

Hi,
Geeks and Nerds

-

Explore my expertise in Java development, backend systems, and REST APIs.

-
- Projects
- View Details -


+

Explore my expertise in Java development, backend systems, and REST APIs.

+

+
+ Projects + View Details +
+

+
Portfolio
@@ -80,6 +83,9 @@

Hi,
Geeks and Nerds

Skills

+

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

Java

diff --git a/index.html b/index.html index 7898f73..a71e922 100644 --- a/index.html +++ b/index.html @@ -82,7 +82,7 @@

Hello,
I'm Vimal

-

A Passionate Java Developer building scalable backend applications.

+

A Passionate Java Developer building scalable backend applications.

My Work
diff --git a/js/services.js b/js/services.js index 910dad7..b5bbaf3 100644 --- a/js/services.js +++ b/js/services.js @@ -124,3 +124,29 @@ function updateToggleIcon() { darkModeToggle.style.color = "#fff"; } } + +// ===== Services Accordion Logic ===== +document.addEventListener("DOMContentLoaded", function () { + const accordionItems = document.querySelectorAll(".accordion-item"); + + if (!accordionItems.length) return; + + accordionItems.forEach(item => { + const header = item.querySelector(".accordion-header"); + + if (!header) return; + + header.addEventListener("click", () => { + const isActive = item.classList.contains("active"); + + // Close all + accordionItems.forEach(i => i.classList.remove("active")); + + // Open clicked one if it was closed + if (!isActive) { + item.classList.add("active"); + } + }); + }); +}); + diff --git a/seo/services-faq.schema.html b/seo/services-faq.schema.html new file mode 100644 index 0000000..5d937b0 --- /dev/null +++ b/seo/services-faq.schema.html @@ -0,0 +1,40 @@ + \ No newline at end of file diff --git a/seo/services.schema.html b/seo/services.schema.html new file mode 100644 index 0000000..5216bc5 --- /dev/null +++ b/seo/services.schema.html @@ -0,0 +1,78 @@ + \ No newline at end of file diff --git a/services.html b/services.html index afb042a..6093152 100644 --- a/services.html +++ b/services.html @@ -5,6 +5,131 @@ Vimal Tech • Services + + + + + + + + + @@ -73,8 +198,10 @@

Our Professional Services

-

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

+

+ We help startups and businesses build scalable, secure, and high-performance + software systems — from backend architecture to cloud-ready deployments. +

My Work
@@ -82,42 +209,178 @@

Our Professional Services

Services We Offer

-

Explore our expertise to scale your projects efficiently:

+

Explore our expertise to scale your projects efficiently:

+ +
-
-
- -

Backend Development

-

Scalable applications using Java, Spring Boot, and Microservices.

+
+
+ +

Backend Development

+ + +
+
+

+ Design and development of scalable backend systems using Java, + Spring Boot, and Microservices. Ideal for APIs, SaaS platforms, + and enterprise-grade applications. +

+
-
- -

Cloud Integration

-

Deploy and manage apps efficiently on AWS and cloud platforms.

+ +
+
+ +

Cloud Integration

+ + +
+
+

+ Cloud-ready deployment, configuration, and scaling using AWS + and modern hosting platforms for reliability and performance. +

+
-
- -

Database Management

-

Relational and NoSQL database design & management.

+ +
+
+ +

Database Management

+ + +
+
+

+ Optimized relational and NoSQL database design, query tuning, + backups, and data integrity management. +

+
-
- -

Project Consulting

-

Architecture guidance and microservices design for enterprise projects.

+ +
+
+ +

Project Consulting

+ + +
+
+

+ System architecture planning, microservices strategy, + and technical guidance to reduce long-term technical debt. +

+
-
- -

API Development

-

RESTful APIs and integrations for modern web & mobile apps.

+ +
+
+ +

API Development

+ + +
+
+

+ Secure REST API development and third-party integrations + for web and mobile applications. +

+
-
- -

Security & Optimization

-

Secure, optimized, and maintainable solutions following best practices.

+ +
+
+ +

Security & Optimization

+ + +
+
+

+ Performance tuning, security best practices, and maintainable + code standards for long-term system stability. +

+
+

+
+

Why Work With Me

+

+ I focus on building software that is not only functional today, + but scalable, maintainable, and cost-effective in the long run. +

+ +
    +
  • ✔ Clean, production-ready backend code
  • +
  • ✔ Scalable system & microservice architecture
  • +
  • ✔ Performance-optimized & secure applications
  • +
  • ✔ Clear communication & structured delivery
  • +
  • ✔ Long-term support and optimization
  • +
+
+ +
+

How These Services Help Your Business

+ +
+

Backend Development

+

+ Ideal for applications that require secure APIs, business logic, + and high traffic handling. I design backend systems that are + stable, scalable, and easy to extend. +

+

+ +

Cloud Integration

+

+ Suitable for growing products that need reliable deployment, + scalability, and cost-optimized infrastructure on cloud platforms. +

+

+ +

Database Management

+

+ Designed for data-driven applications that require fast queries, + reliable storage, and secure data handling. +

+

+ +

API Development

+

+ Enables seamless communication between web apps, mobile apps, + and third-party services using secure REST APIs. +

+
+
+ +
+

My Working Process

+ +
    +
  1. Requirement Discussion – Understand business & technical goals
  2. +
  3. Architecture Planning – Design scalable system structure
  4. +
  5. Development – Clean, modular, and testable code
  6. +
  7. Testing & Deployment – Stability and performance validation
  8. +
  9. Support & Optimization – Continuous improvements
  10. +
+
+ +
+

Engagement Models

+ +

+ I offer flexible engagement options depending on your project needs: +

+ +
    +
  • Project-Based – Fixed scope with clear deliverables
  • +
  • Hourly / Monthly Retainer – Ongoing development & support
  • +
  • Consulting – Architecture review, planning, and guidance
  • +
+ +

+ Pricing depends on project complexity, timeline, and requirements. +

+
+
@@ -151,6 +414,40 @@

Live Websites

+
+

Frequently Asked Questions

+ +
+

How long does a project take?
+ Small projects usually take 2–4 weeks. Larger systems vary based on scope. +

+ +

Do you provide post-deployment support?
+ Yes. I offer maintenance, optimization, and feature enhancements. +

+ +

Can you work with existing codebases?
+ Absolutely. I can extend, refactor, or optimize existing systems. +

+ +

Do you help with MVP development?
+ Yes. I specialize in MVPs built with scalable architecture. +

+
+
+ +
+

Let’s Build Something Solid

+

+ Have an idea or an existing system that needs improvement? +

+

+ + Get in Touch + +

+
+

Contact No : 9638 474047

From 13b3d3223d98228b3b613c5e52d0eea113c94254 Mon Sep 17 00:00:00 2001 From: vimal-tech-dev Date: Fri, 20 Feb 2026 06:04:07 +0530 Subject: [PATCH 02/17] Strategic improvements done Signed-off-by: vimal-tech-dev Signed-off-by: vimal-java-dev --- contact.html | 493 +++++++++--------------- css/common.css | 1 + css/contact.css | 966 ++++++++++++++++++++++++------------------------ js/contact.js | 225 ++++++----- 4 files changed, 761 insertions(+), 924 deletions(-) diff --git a/contact.html b/contact.html index 10e9b41..5ac0157 100644 --- a/contact.html +++ b/contact.html @@ -2,346 +2,197 @@ - - - Vimal Tech • Contact - + + + + Vimal Tech | Contact + + - - - - - - - + + + + - -
+ +
+
+ Virtual Office · Valsad, Gujarat +
+ +
+ + + +
+

Contact No: 9638 474047

+

Email: vimal.patel@vimaltech.dev

+

© 2026 Vimal Patel | Java Developer

+
+ + + \ No newline at end of file diff --git a/css/common.css b/css/common.css index ec40781..9b72029 100644 --- a/css/common.css +++ b/css/common.css @@ -1,3 +1,4 @@ +/* ===== common.css ===== */ /* =================================================== ===== Global Styles ===== =================================================== */ diff --git a/css/contact.css b/css/contact.css index 14ad526..f55ea78 100644 --- a/css/contact.css +++ b/css/contact.css @@ -1,667 +1,659 @@ -:root { - --bg: #0b1020; - --panel: #0f1629; - --panel-2: #121a33; - --border: #1f2a4b; - --text: #e8ecf4; - --muted: #a9b3c7; - --brand: #7aa7ff; - --brand-2: #9b8cff; - --ok: #2ad4a1; - --warn: #ffb86b; - --error: #ff6b6b; - --shadow: 0 10px 30px rgba(0, 0, 0, .35); - --radius-xl: 18px; - --radius-lg: 14px; - --radius: 12px; -} - -* { - box-sizing: border-box; -} +/* contact.css */ -html, -body { - height: 100%; -} +/* ===================================== + CONTACT PAGE — REFINED DARK-TECH + Fonts: DM Serif Display + DM Sans + JetBrains Mono +===================================== */ -/* Logo image */ -.logo { - height: 32px; - width: 32px; - object-fit: contain; - border-radius: 6px; - /* optional for a softer look */ +:root { + --amber: #f59e0b; + --amber-light: #fbbf24; + --amber-dim: rgba(245, 158, 11, 0.12); + --bg-dark: #0b0f1a; + --bg-card: #111827; + --bg-card-light: #1a2235; + --text-primary: #f1f5f9; + --text-muted: #94a3b8; + --text-dim: #64748b; + --border: rgba(255, 255, 255, 0.07); + --border-focus: rgba(245, 158, 11, 0.5); + --radius: 14px; + --shadow-card: 0 24px 60px rgba(0, 0, 0, 0.4); +} + +/* ── GLOBAL OVERRIDES FOR CONTACT PAGE ───────────────── */ +/* These ensure the dark theme persists despite common.css */ + +body.contact-body { + background-color: var(--bg-dark); + color: var(--text-primary); +} + +/* Override Common Navbar to be Dark */ +.contact-body .navbar { + background-color: rgba(11, 15, 26, 0.95); + backdrop-filter: blur(10px); + border-bottom: 1px solid var(--border); + color: var(--text-primary); } -body { - margin: 0; - font-family: Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; - color: var(--text); - background: radial-gradient(1200px 1200px at 10% -10%, rgba(122, 167, 255, .18), transparent 50%), - radial-gradient(900px 900px at 100% 10%, rgba(155, 140, 255, .18), transparent 40%), - linear-gradient(180deg, #070b17, #0b1020); - overflow-x: hidden; +.contact-body .navbar .brand-name-vimal { + color: #fff; + /* White instead of black */ } -.noise { - position: fixed; - inset: 0; - pointer-events: none; - /* background-image: url("/assets/noise.svg"); - background-repeat: repeat; */ - opacity: .3; - mix-blend-mode: lighten; - background: url('/images/hero.png') no-repeat center/cover; +.contact-body .nav-links li a { + color: #cbd5e1; + /* Light grey instead of dark grey */ } -.container { - max-width: 1100px; - margin: 30px auto; - padding: 0 20px; +.contact-body .nav-links li a:hover, +.contact-body .nav-links li a.active { + color: var(--amber); + /* Amber instead of Tomato red */ } -header { - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - margin-bottom: 28px; +/* Fix mobile menu background on dark page */ +@media (max-width: 768px) { + .contact-body .nav-links { + background-color: var(--bg-card); + border: 1px solid var(--border); + } } -.brand { - display: flex; - align-items: center; - gap: 12px; - font-weight: 700; - letter-spacing: .4px; - font-size: 18px; -} -.brand .logo { - width: 34px; - height: 34px; - display: grid; - place-items: center; - border-radius: 10px; - background: linear-gradient(135deg, var(--brand), var(--brand-2)); - box-shadow: var(--shadow); -} +/* ── HERO ─────────────────────────────── */ -.brand .logo svg { - width: 20px; - height: 20px; - color: white +.contact-hero { + position: relative; + padding: 160px 24px 100px; + /* Increased top padding for fixed navbar */ + text-align: center; + background: var(--bg-dark); + overflow: hidden; + isolation: isolate; } -.theme-toggle { - border: 1px solid var(--border); - background: linear-gradient(180deg, var(--panel), var(--panel-2)); - color: var(--text); - border-radius: 999px; - padding: 10px 14px; - display: flex; - align-items: center; - gap: 10px; - cursor: pointer; - box-shadow: var(--shadow); +.hero-bg-grid { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(245, 158, 11, 0.04) 1px, transparent 1px), + linear-gradient(90deg, rgba(245, 158, 11, 0.04) 1px, transparent 1px); + background-size: 48px 48px; + z-index: -1; } -.theme-toggle span { - font-size: 12px; - color: var(--muted); +.hero-bg-grid::after { + content: ''; + position: absolute; + inset: 0; + background: radial-gradient(ellipse 70% 60% at 50% 0%, rgba(245, 158, 11, 0.08) 0%, transparent 70%); } -.grid { - display: grid; - grid-template-columns: 1.05fr .95fr; - gap: 26px; +.contact-hero-content { + position: relative; + max-width: 720px; + margin: 0 auto; + animation: heroReveal 0.8s cubic-bezier(0.22, 1, 0.36, 1) both; } -@media (max-width: 920px) { - .grid { - grid-template-columns: 1fr; +@keyframes heroReveal { + from { + opacity: 0; + transform: translateY(28px); } -} -.card { - border: 1px solid var(--border); - background: linear-gradient(180deg, rgba(255, 255, 255, .02), rgba(255, 255, 255, .01)); - border-radius: var(--radius-xl); - box-shadow: var(--shadow); - overflow: hidden; + to { + opacity: 1; + transform: translateY(0); + } } -.panel { - padding: 26px; - backdrop-filter: blur(8px); +.hero-label { + display: inline-block; + font-family: 'JetBrains Mono', monospace; + font-size: 12px; + font-weight: 500; + letter-spacing: 0.2em; + text-transform: uppercase; + color: var(--amber); + background: var(--amber-dim); + border: 1px solid rgba(245, 158, 11, 0.2); + padding: 6px 16px; + border-radius: 100px; + margin-bottom: 28px; } -.title { - font-size: 26px; - margin: 0 0 6px; - letter-spacing: .3px +.contact-hero h1 { + font-family: 'DM Serif Display', serif; + font-size: clamp(40px, 7vw, 72px); + font-weight: 400; + line-height: 1.1; + color: var(--text-primary); + margin-bottom: 20px; + letter-spacing: -0.02em; } -.subtitle { - margin: 0 0 22px; - color: var(--muted); - line-height: 1.6 +.contact-hero p { + font-family: 'DM Sans', sans-serif; + font-size: 18px; + max-width: 520px; + margin: 0 auto 32px; + color: var(--text-muted); + line-height: 1.75; + font-weight: 300; } -.contact-list { - display: grid; - gap: 12px; - margin: 16px 0 0 +.hero-availability { + display: inline-flex; + align-items: center; + gap: 10px; + font-family: 'DM Sans', sans-serif; + font-size: 14px; + font-weight: 500; + color: #4ade80; + background: rgba(74, 222, 128, 0.08); + border: 1px solid rgba(74, 222, 128, 0.2); + padding: 8px 18px; + border-radius: 100px; } -.contact-item { - display: flex; - gap: 14px; - align-items: flex-start; - padding: 12px; - border: 1px dashed var(--border); - border-radius: var(--radius-lg); - background: linear-gradient(180deg, rgba(255, 255, 255, .02), rgba(255, 255, 255, .01)); +.availability-dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: #4ade80; + box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.4); + animation: pulseDot 2s ease-in-out infinite; } -.contact-item svg { - flex: 0 0 20px; - opacity: .9 -} +@keyframes pulseDot { -.contact-item strong { - display: block; - font-size: 14px -} + 0%, + 100% { + box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.4); + } -.contact-item span { - color: var(--muted); - font-size: 13px + 50% { + box-shadow: 0 0 0 6px rgba(74, 222, 128, 0); + } } -.socials { +.hero-scroll-hint { + position: absolute; + bottom: -60px; + /* Adjusted to fit better */ + left: 50%; + transform: translateX(-50%); display: flex; - gap: 10px; - margin-top: 16px -} - -.icon-btn { - border: 1px solid var(--border); - background: linear-gradient(180deg, var(--panel), var(--panel-2)); - border-radius: 12px; - padding: 10px; - display: grid; - place-items: center; - cursor: pointer; - transition: transform .14s ease; -} - -.icon-btn:hover { - transform: translateY(-2px) + flex-direction: column; + align-items: center; + gap: 8px; + color: var(--text-dim); + font-family: 'JetBrains Mono', monospace; + font-size: 10px; + letter-spacing: 0.15em; + text-transform: uppercase; + text-decoration: none; + transition: color 0.3s; } -.icon-btn svg { - width: 20px; - height: 20px +.hero-scroll-hint:hover { + color: var(--amber); } -/* Map placeholder */ -.map { - height: 240px; - border-top: 1px solid var(--border); - background: conic-gradient(from 180deg at 0% 0%, rgba(122, 167, 255, .12), rgba(155, 140, 255, .08), rgba(42, 212, 161, .10)); - position: relative; +.scroll-line { + width: 1px; + height: 36px; + background: linear-gradient(to bottom, var(--text-dim), transparent); + animation: scrollBob 1.8s ease-in-out infinite; } -.map::after { - content: "Map preview"; - position: absolute; - bottom: 10px; - right: 12px; - font-size: 12px; - color: var(--muted); -} +@keyframes scrollBob { -/* Light theme */ -.light { - --bg: #f6f8fd; - --panel: #fff; - --panel-2: #f9fafc; - --border: #e6eaf3; - --text: #0d1321; - --muted: #5a6275; - --shadow: 0 10px 30px rgba(19, 33, 68, .08); - background: radial-gradient(1400px 1200px at 10% -10%, rgba(122, 167, 255, .25), transparent 50%), - radial-gradient(900px 900px at 100% 10%, rgba(155, 140, 255, .22), transparent 40%), - linear-gradient(180deg, #eef3ff, #f6f8fd); -} + 0%, + 100% { + transform: scaleY(1); + opacity: 0.6; + } -.light .label { - background: linear-gradient(180deg, #fff, #fff); + 50% { + transform: scaleY(0.6); + opacity: 1; + } } -/* Polishing visuals */ -.title em { - font-style: normal; - background: linear-gradient(90deg, var(--brand), var(--brand-2)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; -} +/* ── LAYOUT ───────────────────────────── */ -.card { - position: relative; - overflow: hidden; +.contact-section { + margin: 40px auto 80px; + padding: 0 24px; + max-width: 1100px; + display: grid; + grid-template-columns: 350px 1fr; + gap: 40px; + align-items: start; } -.card::after { - content: ""; - position: absolute; - inset: -1px; - border-radius: inherit; - padding: 1px; - background: linear-gradient(120deg, rgba(122, 167, 255, .6), rgba(42, 212, 161, .4), rgba(155, 140, 255, .6)); - -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); - -webkit-mask-composite: xor; - mask-composite: exclude; - opacity: .25; - transition: opacity .25s ease; - pointer-events: none +@media (max-width: 960px) { + .contact-section { + grid-template-columns: 1fr; + } } -.card:hover::after { - opacity: .55 -} +/* ── INFO CARD ────────────────────────── */ -.fade-in { - animation: fadeInUp .6s ease both +.contact-info { + background: var(--bg-card); + padding: 44px 36px; + border-radius: var(--radius); + border: 1px solid var(--border); + box-shadow: var(--shadow-card); + position: sticky; + top: 100px; + animation: slideInLeft 0.7s 0.2s cubic-bezier(0.22, 1, 0.36, 1) both; } -@keyframes fadeInUp { +@keyframes slideInLeft { from { opacity: 0; - transform: translateY(6px) + transform: translateX(-20px); } to { opacity: 1; - transform: none + transform: translateX(0); } } -.contact-links { - display: flex; - flex-wrap: wrap; - gap: 12px; +.contact-info .section-title { + font-family: 'DM Serif Display', serif; + font-weight: 400; + font-size: 26px; + color: var(--text-primary); + margin-bottom: 32px; + padding-bottom: 16px; + border-bottom: 1px solid var(--border); } -.contact-links a { - border: 1px solid var(--border); - background: linear-gradient(135deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, .02)); - border-radius: 14px; - padding: 12px 16px; - text-decoration: none; - color: var(--text); +.info-item { display: flex; - align-items: center; - gap: 10px; - font-weight: 600; - box-shadow: var(--shadow); - position: relative; - overflow: hidden; - transition: transform .18s ease, box-shadow .18s ease; + align-items: flex-start; + gap: 16px; + margin-bottom: 28px; } -.contact-links a::before { - content: ""; - position: absolute; - inset: 0; - background: radial-gradient(120px 120px at var(--mx, 0) var(--my, 0), rgba(122, 167, 255, .25), transparent 60%); - opacity: 0; - transition: opacity .2s ease; +.info-icon { + width: 40px; + height: 40px; + border-radius: 10px; + background: var(--amber-dim); + border: 1px solid rgba(245, 158, 11, 0.15); + display: flex; + align-items: center; + justify-content: center; + color: var(--amber); + flex-shrink: 0; + margin-top: 2px; } -.contact-links a:hover { - transform: translateY(-2px); +.info-content { + display: flex; + flex-direction: column; + gap: 4px; } -.contact-links a:hover::before { - opacity: 1 +.info-label { + font-family: 'JetBrains Mono', monospace; + font-size: 10px; + letter-spacing: 0.15em; + text-transform: uppercase; + color: var(--text-dim); } -.quote { - font-size: 18px; - line-height: 1.8; - color: var(--text); +.info-content a, +.info-content span { + font-family: 'DM Sans', sans-serif; + font-size: 15px; + font-weight: 500; + color: var(--text-primary); + text-decoration: none; + transition: color 0.2s; } -.quote strong { - background: linear-gradient(90deg, var(--brand), var(--ok)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; +.info-content a:hover { + color: var(--amber); } -.badge { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 8px 12px; - border-radius: 999px; - border: 1px solid var(--border); - background: linear-gradient(180deg, var(--panel), var(--panel-2)); - font-size: 12px; - color: var(--muted) +.info-divider { + height: 1px; + background: var(--border); + margin: 28px 0; } -.tech-badges { +.response-note { display: flex; - flex-wrap: wrap; + align-items: center; gap: 10px; - margin-top: 12px; + font-family: 'DM Sans', sans-serif; + font-size: 13px; + color: var(--text-muted); } -.sparkle { - position: absolute; - right: -40px; - top: -40px; - width: 200px; - height: 200px; - background: radial-gradient(closest-side, rgba(122, 167, 255, .18), transparent 65%); - filter: blur(8px); - pointer-events: none +.response-note svg { + color: var(--amber); + flex-shrink: 0; } -.icon { - width: 18px; - height: 18px +.response-note strong { + color: var(--text-primary); + font-weight: 600; } -/* Hover underline for Get in touch social links */ -.contact-item span:hover, -.contact-item strong:hover { - text-decoration: underline; - cursor: pointer; +/* ── FORM CARD ────────────────────────── */ + +.contact-form-wrapper { + background: #ffffff; + padding: 52px 48px; + border-radius: var(--radius); + box-shadow: 0 24px 64px rgba(0, 0, 0, 0.1); + animation: slideInRight 0.7s 0.3s cubic-bezier(0.22, 1, 0.36, 1) both; } -/* Full-width contact buttons on mobile */ -@media (max-width: 600px) { - .contact-links a { - width: 100%; - justify-content: center; +@keyframes slideInRight { + from { + opacity: 0; + transform: translateX(20px); } -} -/* Ripple effect for buttons */ -.contact-links a { - position: relative; - overflow: hidden; + to { + opacity: 1; + transform: translateX(0); + } } -.contact-links a .ripple { - position: absolute; - border-radius: 50%; - transform: scale(0); - animation: ripple 0.6s linear; - background: rgba(255, 255, 255, 0.35); - pointer-events: none; +.contact-form-wrapper .section-title { + font-family: 'DM Serif Display', serif; + font-weight: 400; + font-size: 26px; + color: #0b0f1a; + margin-bottom: 32px; + padding-bottom: 16px; + border-bottom: 1px solid #e2e8f0; } -@keyframes ripple { - to { - transform: scale(4); - opacity: 0 - } +/* Form rows */ +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; } @media (max-width: 600px) { - .contact-links a { - width: 100%; - justify-content: center; + .form-row { + grid-template-columns: 1fr; } -} -/* Micro-interactions & delightful polish */ -.card { - transition: transform .25s ease, box-shadow .25s ease + .contact-form-wrapper { + padding: 32px 24px; + } } -.card:hover { - transform: translateY(-3px) +.contact-form .form-group { + margin-bottom: 22px; + position: relative; } -.brand .logo { - transition: transform .3s ease +.contact-form label { + display: block; + margin-bottom: 8px; + font-family: 'DM Sans', sans-serif; + font-size: 13px; + font-weight: 600; + color: #1e293b; + letter-spacing: 0.01em; } -.brand:hover .logo { - transform: rotate(-8deg) scale(1.05) +.optional { + font-weight: 400; + color: #94a3b8; + font-size: 12px; } -.theme-toggle { - transition: transform .15s ease +.contact-form input, +.contact-form textarea { + width: 100%; + padding: 13px 16px; + border-radius: 10px; + border: 1.5px solid #e2e8f0; + background: #f8fafc; + font-family: 'DM Sans', sans-serif; + font-size: 14px; + color: #0f172a; + transition: all 0.2s ease; + box-sizing: border-box; } -.theme-toggle:active { - transform: scale(.96) +.contact-form input:hover, +.contact-form textarea:hover { + border-color: #cbd5e1; + background: #fff; } -.map { - background-size: 200% 200%; - animation: shimmer 6s ease-in-out infinite; +.contact-form input:focus, +.contact-form textarea:focus { + outline: none; + border-color: var(--amber); + background: #fff; + box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.1); } -@keyframes shimmer { - 0% { - background-position: 0% 0% - } - - 50% { - background-position: 100% 50% - } - - 100% { - background-position: 0% 0% - } +.contact-form input.input-error, +.contact-form textarea.input-error { + border-color: #ef4444; + background: #fef2f2; } -.contact-item { - transition: transform .2s ease, background .2s ease +.field-error { + display: block; + font-family: 'DM Sans', sans-serif; + font-size: 12px; + color: #ef4444; + margin-top: 6px; + min-height: 18px; + opacity: 0; + transition: opacity 0.3s; } -.contact-item:hover { - transform: translateX(4px) +.field-error.visible { + opacity: 1; } -.contact-item a { - color: inherit; - text-decoration: none; - border-bottom: 1px dashed transparent; - transition: border-color .2s ease +.char-count-wrapper { + display: flex; + justify-content: space-between; + align-items: flex-start; } -.contact-item a:hover { - border-color: var(--brand) +.char-count { + display: block; + text-align: right; + font-family: 'JetBrains Mono', monospace; + font-size: 11px; + color: #94a3b8; + margin-top: 6px; } -.card.in-view { - animation: fadeInUp .6s var(--delay, 0ms) ease both +.char-count.near-limit { + color: #f59e0b; } -/* Disable micro-interactions specifically for the Get in touch card */ -section[aria-labelledby="contact-info-title"] .contact-item { - transition: none; - transform: none; +.char-count.at-limit { + color: #ef4444; } -section[aria-labelledby="contact-info-title"] .contact-item a { - border: 0; - text-decoration: none; - color: var(--muted); +/* Submit Button */ +.btn-send { + display: inline-flex; + align-items: center; + gap: 10px; + margin-top: 8px; + padding: 15px 32px; + border-radius: 10px; + border: none; + background: #0b0f1a; + color: #fff; + font-family: 'DM Sans', sans-serif; + font-size: 15px; + font-weight: 600; + cursor: pointer; + transition: all 0.25s ease; + position: relative; + overflow: hidden; } -section[aria-labelledby="contact-info-title"] .contact-item a:hover { - text-decoration: underline; +.btn-send::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, var(--amber), #ea580c); + opacity: 0; + transition: opacity 0.25s ease; } -/* ===== Scroll to Top Button ===== */ -#scrollTopBtn { - position: fixed; - bottom: 60px; - right: 20px; - width: 46px; - height: 46px; - border-radius: 14px; - border: 1px solid var(--border); - background: linear-gradient(180deg, var(--panel), var(--panel-2)); - box-shadow: var(--shadow); - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - opacity: 0; - transform: translateY(12px); - pointer-events: none; - transition: opacity .25s ease, transform .25s ease; - z-index: 999; +.btn-send:hover::before { + opacity: 1; } -#scrollTopBtn svg { - width: 20px; - height: 20px; - color: var(--text); +.btn-send:hover { + transform: translateY(-2px); + box-shadow: 0 12px 28px rgba(245, 158, 11, 0.35); } -#scrollTopBtn.show { - opacity: 1; +.btn-send:active { transform: translateY(0); - pointer-events: auto; } -#scrollTopBtn:active { - transform: scale(.94); +.btn-send .btn-text, +.btn-send .btn-arrow { + position: relative; + z-index: 1; } -/* ========================= - Responsive Navigation Bar -========================= */ +.btn-send.loading { + pointer-events: none; + opacity: 0.7; +} -.navbar { - position: sticky; - top: 0; - z-index: 1000; - margin-bottom: 24px; - backdrop-filter: blur(10px); +/* Success state */ +.form-success { + display: none; + align-items: center; + gap: 10px; + margin-top: 20px; + padding: 16px 20px; + background: #f0fdf4; + border: 1px solid #bbf7d0; + border-radius: 10px; + font-family: 'DM Sans', sans-serif; + font-size: 14px; + font-weight: 500; + color: #16a34a; } -.nav-inner { +.form-success.visible { display: flex; - align-items: center; - justify-content: space-between; - padding: 14px 18px; - border: 1px solid var(--border); - border-radius: var(--radius-xl); - background: linear-gradient(180deg, var(--panel), var(--panel-2)); - box-shadow: var(--shadow); + animation: fadeSlideIn 0.4s ease both; } -.nav-brand { - font-weight: 700; - letter-spacing: .4px; - color: var(--brand); - text-decoration: none; - font-size: 25px; - line-height: 1.5; - font-family: var(--font-sans); +@keyframes fadeSlideIn { + from { + opacity: 0; + transform: translateY(8px); + } + to { + opacity: 1; + transform: translateY(0); + } } -/* Desktop links */ -.nav-links { - display: flex; - gap: 22px; - list-style: none; - margin: 0; - padding: 0; -} +/* ── MAP ──────────────────────────────── */ -.nav-links a { - text-decoration: none; - font-size: 14px; - color: var(--muted); +.map-section { + max-width: 1100px; + margin: 0 auto 80px; + padding: 0 24px; position: relative; } -.nav-links a:hover, -.nav-links a.active { - color: var(--text); +.map-label { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: 'JetBrains Mono', monospace; + font-size: 11px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--text-dim); + margin-bottom: 14px; } -.nav-links a.active::after { - content: ""; - position: absolute; - left: 0; - bottom: -6px; +.map-section iframe { width: 100%; - height: 2px; - background: linear-gradient(90deg, var(--brand), var(--ok)); - border-radius: 2px; + height: 420px; + border-radius: var(--radius); + border: 1px solid var(--border); + box-shadow: var(--shadow-card); + display: block; + filter: grayscale(1) invert(0.9); + /* Cool dark map effect */ + transition: filter 0.3s; } -/* Hamburger button */ -.nav-toggle { - display: none; - flex-direction: column; - gap: 5px; - background: none; - border: 0; - cursor: pointer; +.map-section iframe:hover { + filter: none; + /* Show colorful map on hover */ } -.nav-toggle span { - width: 22px; - height: 2px; - background: var(--text); - border-radius: 2px; - transition: transform .25s ease, opacity .25s ease; -} +/* ── RESPONSIVE ───────────────────────── */ -/* Mobile */ -@media (max-width: 760px) { - .nav-toggle { - display: flex; +@media (max-width: 640px) { + .contact-hero { + padding: 120px 20px 80px; } - .nav-links { - position: absolute; - top: calc(100% + 10px); - left: 0; - right: 0; - flex-direction: column; - gap: 14px; - padding: 18px; - border-radius: var(--radius-lg); - border: 1px solid var(--border); - background: linear-gradient(180deg, var(--panel), var(--panel-2)); - box-shadow: var(--shadow); + .contact-hero h1 { + font-size: 38px; + } + + .hero-scroll-hint { display: none; } - .nav-links.open { - display: flex; + .contact-section { + margin: 48px auto; } -} -/* Hamburger animation */ -.nav-toggle.open span:nth-child(1) { - transform: translateY(7px) rotate(45deg); + .contact-info { + position: static; + } + + .map-section iframe { + height: 300px; + } } -.nav-toggle.open span:nth-child(2) { - opacity: 0; +/* ── OVERRIDES for Common Section styling ──────────────── */ +/* Fix section border-radius clipping full-width hero/map */ +.contact-hero, +.map-section { + border-radius: 0; } -.nav-toggle.open span:nth-child(3) { - transform: translateY(-7px) rotate(-45deg); +/* Force the Contact link to stay highlighted, overriding common.js */ +.contact-body .nav-links li a[href="contact.html"], +.contact-body .nav-links li a[href="contact.html"].active { + color: var(--amber) !important; } \ No newline at end of file diff --git a/js/contact.js b/js/contact.js index 2e5d7b1..55b2f92 100644 --- a/js/contact.js +++ b/js/contact.js @@ -1,126 +1,119 @@ -// Year -document.getElementById("year").textContent = new Date().getFullYear(); - -// Theme toggle with localStorage persistence -const root = document.documentElement; -const themeToggle = document.getElementById("themeToggle"); -const sun = document.getElementById("sun"); -const moon = document.getElementById("moon"); - -const setTheme = (mode) => { - if (mode === "light") { - root.classList.add("light"); - sun.style.display = "none"; - moon.style.display = ""; - themeToggle.setAttribute("aria-pressed", "true"); - } else { - root.classList.remove("light"); - sun.style.display = ""; - moon.style.display = "none"; - themeToggle.setAttribute("aria-pressed", "false"); - } - localStorage.setItem("prefers-theme", mode); -}; - -const saved = localStorage.getItem("prefers-theme"); -if (saved) { - setTheme(saved); -} -themeToggle.addEventListener("click", () => { - const isLight = root.classList.contains("light"); - setTheme(isLight ? "dark" : "light"); -}); - -// Micro-interactions: gentle tilt on hover for cards -document.querySelectorAll(".card").forEach((card, i) => { - if (card.dataset.static === "true") { - return; +// contact.js +document.addEventListener("DOMContentLoaded", function () { + + // 1️⃣ Force "Contact" Link Active + // common.js has a ScrollSpy that removes active classes on scroll. + // This function ensures the contact link overrides that behavior. + const contactLink = document.querySelector('.nav-links a[href="contact.html"]'); + + function keepContactActive() { + if (contactLink) { + // Remove active from others, force it on Contact + document.querySelectorAll('.nav-links a').forEach(link => link.classList.remove('active')); + contactLink.classList.add('active'); + } } - card.style.setProperty("--delay", i * 80 + "ms"); - let rAF; - const onMove = (e) => { - const rect = card.getBoundingClientRect(); - const x = (e.clientX - rect.left) / rect.width - 0.5; - const y = (e.clientY - rect.top) / rect.height - 0.5; - cancelAnimationFrame(rAF); - rAF = requestAnimationFrame(() => { - card.style.transform = `rotateX(${-y * 3}deg) rotateY(${ - x * 3 - }deg) translateY(-3px)`; - }); - }; - const reset = () => { - card.style.transform = ""; - }; - card.addEventListener("mousemove", onMove); - card.addEventListener("mouseleave", reset); -}); - -// Reveal on scroll -const io = new IntersectionObserver( - (entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting) { - entry.target.classList.add("in-view"); - io.unobserve(entry.target); + + // Run on initial load + keepContactActive(); + + // Run on scroll to instantly override common.js + window.addEventListener("scroll", keepContactActive); + + + // 2️⃣ Character Count for Message + const messageInput = document.getElementById("message"); + const charCountSpan = document.getElementById("charCount"); + const maxChars = 1000; + + if (messageInput && charCountSpan) { + messageInput.addEventListener("input", () => { + const currentLength = messageInput.value.length; + charCountSpan.textContent = `${currentLength} / ${maxChars}`; + + if (currentLength >= maxChars) { + charCountSpan.classList.add("at-limit"); + messageInput.value = messageInput.value.substring(0, maxChars); + } else if (currentLength > maxChars * 0.9) { + charCountSpan.classList.add("near-limit"); + charCountSpan.classList.remove("at-limit"); + } else { + charCountSpan.classList.remove("near-limit", "at-limit"); } }); - }, - { threshold: 0.2 } -); -document.querySelectorAll(".card").forEach((el) => io.observe(el)); - -/* ============================ - Scroll-to-Top Button -============================ */ -document.addEventListener("DOMContentLoaded", () => { - const scrollTopBtn = document.getElementById("scrollTopBtn"); - - window.addEventListener("scroll", () => { - if (window.scrollY > 180) { - scrollTopBtn.classList.add("show"); - } else { - scrollTopBtn.classList.remove("show"); - } - }); + } - scrollTopBtn.addEventListener("click", () => { - window.scrollTo({ top: 0, behavior: "smooth" }); - }); + // 3️⃣ Form Validation & Submission + const form = document.getElementById("contactForm"); + const submitBtn = document.getElementById("submitBtn"); + const successMsg = document.getElementById("formSuccess"); - function makeNoise() { - const el = document.querySelector(".noise"); - if (!el) return; + if (form) { + form.addEventListener("submit", function (e) { + e.preventDefault(); // Prevent actual PHP submit for demo purposes - const size = 80; // texture tile size - const c = document.createElement("canvas"); - c.width = c.height = size; + let isValid = true; - const ctx = c.getContext("2d", { willReadFrequently: false }); - const img = ctx.createImageData(size, size); - const data = img.data; + // Clear previous errors + document.querySelectorAll(".field-error").forEach(el => el.classList.remove("visible")); + document.querySelectorAll(".input-error").forEach(el => el.classList.remove("input-error")); - // grayscale random pixels with low alpha - for (let i = 0; i < data.length; i += 4) { - const v = Math.random() * 255; - data[i] = data[i + 1] = data[i + 2] = v; // R,G,B - data[i + 3] = 12; // alpha (0–255) -> ~0.05 opacity per pixel - } - ctx.putImageData(img, 0, 0); + // Validate Name + const name = document.getElementById("name"); + if (!name.value.trim()) { + showError("name", "Name is required"); + isValid = false; + } + + // Validate Email + const email = document.getElementById("email"); + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!email.value.trim()) { + showError("email", "Email is required"); + isValid = false; + } else if (!emailRegex.test(email.value)) { + showError("email", "Please enter a valid email address"); + isValid = false; + } + + // Validate Message + const message = document.getElementById("message"); + if (!message.value.trim()) { + showError("message", "Please enter a message"); + isValid = false; + } + + if (isValid) { + // Simulate Loading + submitBtn.classList.add("loading"); + submitBtn.querySelector(".btn-text").textContent = "Sending..."; + + // Simulate Network Request (1.5 seconds) + setTimeout(() => { + submitBtn.classList.remove("loading"); + submitBtn.querySelector(".btn-text").textContent = "Message Sent"; + form.reset(); + if (charCountSpan) charCountSpan.textContent = `0 / ${maxChars}`; - el.style.backgroundImage = `url(${c.toDataURL("image/png")})`; - el.style.backgroundRepeat = "repeat"; + successMsg.classList.add("visible"); + + // Reset button text after a while + setTimeout(() => { + submitBtn.querySelector(".btn-text").textContent = "Send Message"; + }, 3000); + }, 1500); + } + }); + } + + function showError(fieldId, message) { + const input = document.getElementById(fieldId); + const errorSpan = document.getElementById(`error-${fieldId}`); + + if (input) input.classList.add("input-error"); + if (errorSpan) { + errorSpan.textContent = message; + errorSpan.classList.add("visible"); + } } -}); - -/* ========================= - Mobile Navigation Toggle -========================= */ -const navToggle = document.getElementById("navToggle"); -const navMenu = document.getElementById("navMenu"); - -navToggle.addEventListener("click", () => { - const isOpen = navMenu.classList.toggle("open"); - navToggle.classList.toggle("open", isOpen); - navToggle.setAttribute("aria-expanded", isOpen); -}); +}); \ No newline at end of file From 6458a8ea7e7a81011929bd1247552290c4c6b984 Mon Sep 17 00:00:00 2001 From: vimal-java-dev Date: Fri, 20 Feb 2026 21:19:37 +0530 Subject: [PATCH 03/17] Cleaned-up and refactored files of about page Signed-off-by: vimal-java-dev --- about.html | 271 +++++++++++++++----------------------------------- css/about.css | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ js/about.js | 23 +++++ 3 files changed, 372 insertions(+), 193 deletions(-) create mode 100644 css/about.css create mode 100644 js/about.js diff --git a/about.html b/about.html index cb46223..e7ef1d1 100644 --- a/about.html +++ b/about.html @@ -4,150 +4,62 @@ - Vimal Tech • About - + Vimal Tech | About + + + - - - - + - + - -
@@ -120,18 +121,18 @@

📘 Field Subjects

diff --git a/services.html b/services/index.html similarity index 95% rename from services.html rename to services/index.html index aa8979c..702a56f 100644 --- a/services.html +++ b/services/index.html @@ -11,13 +11,13 @@ - + - + @@ -29,7 +29,6 @@ -