{"id":594,"date":"2026-04-30T04:12:29","date_gmt":"2026-04-30T04:12:29","guid":{"rendered":"https:\/\/panditjaydev.co.uk\/?page_id=594"},"modified":"2026-04-30T07:32:43","modified_gmt":"2026-04-30T07:32:43","slug":"contact-us","status":"publish","type":"page","link":"https:\/\/panditjaydev.co.uk\/index.php\/contact-us\/","title":{"rendered":"Contact Us"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"594\" class=\"elementor elementor-594\">\n\t\t\t\t<div class=\"elementor-element elementor-element-96c7fb0 e-flex e-con-boxed e-con e-parent\" data-id=\"96c7fb0\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2fbdd76 elementor-widget elementor-widget-page-title\" data-id=\"2fbdd76\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;align&quot;:&quot;center&quot;}\" data-widget_type=\"page-title.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\n\t\t<div class=\"hfe-page-title hfe-page-title-wrapper elementor-widget-heading\">\n\n\t\t\t\t\t\t\t\t\t\t\t<a href=\"https:\/\/panditjaydev.co.uk\">\n\t\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">\n\t\t\t\t\t\t\t\t\n\t\t\t\tContact Us  \n\t\t\t<\/h2 > \n\t\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-98237c1 e-flex e-con-boxed e-con e-parent\" data-id=\"98237c1\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-897209c e-con-full e-flex e-con e-child\" data-id=\"897209c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-26d8eb6 elementor-widget elementor-widget-html\" data-id=\"26d8eb6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>Cosmic Mobile Orbit<\/title>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;700;900&display=swap\" rel=\"stylesheet\">\r\n<style>\r\n  * { margin: 0; padding: 0; box-sizing: border-box; }\r\n\r\n\r\n\r\n \r\n\r\n  .mobile-icon {\r\n    width: 32px;\r\n    height: 38px;\r\n    z-index: 6;\r\n    filter: drop-shadow(0 0 8px rgba(255,200,120,0.9));\r\n  }\r\n\r\n  \r\n  \r\n  .phone-link {\r\n    font-family: 'Montserrat', sans-serif;\r\n    font-weight: 700;\r\n    font-size: 1rem;\r\n    letter-spacing: 0.12em;\r\n    color: rgba(255,255,255,0.85);\r\n    text-decoration: none;\r\n    text-transform: uppercase;\r\n    text-shadow: 0 0 8px rgba(192,96,20,0.3);\r\n    transition: all 0.3s ease;\r\n    display: block;\r\n  }\r\n\r\n  .phone-link:hover {\r\n    color: #FFFFFF;\r\n    text-shadow: 0 0 16px rgba(192,96,20,0.8), 0 0 32px rgba(192,96,20,0.4);\r\n    letter-spacing: 0.16em;\r\n  }\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div class=\"section\" id=\"section\">\r\n  <canvas id=\"particleCanvas\"><\/canvas>\r\n  <div class=\"bg-glow\"><\/div>\r\n\r\n  <div class=\"orbit-system\" id=\"orbitSystem\">\r\n    <div class=\"wave\"><\/div>\r\n    <div class=\"wave\"><\/div>\r\n    <div class=\"wave\"><\/div>\r\n\r\n    <div class=\"ring ring-1\"><\/div>\r\n    <div class=\"ring ring-2\"><\/div>\r\n    <div class=\"ring ring-3\"><\/div>\r\n\r\n    <span class=\"zodiac\" style=\"top:8%;right:12%;--dur:7s;--tx:5px;--ty:-4px;\">\u2653<\/span>\r\n    <span class=\"zodiac\" style=\"top:15%;left:8%;--dur:9s;--tx:-4px;--ty:-6px;\">\u2652<\/span>\r\n    <span class=\"zodiac\" style=\"bottom:10%;right:10%;--dur:6s;--tx:3px;--ty:5px;\">\u2650<\/span>\r\n    <span class=\"zodiac\" style=\"bottom:12%;left:12%;--dur:8s;--tx:-5px;--ty:4px;\">\u264e<\/span>\r\n    <span class=\"zodiac\" style=\"top:45%;left:2%;--dur:10s;--tx:-3px;--ty:-3px;font-size:11px;\">\u264b<\/span>\r\n    <span class=\"zodiac\" style=\"top:40%;right:2%;--dur:7.5s;--tx:4px;--ty:2px;font-size:11px;\">\u264a<\/span>\r\n\r\n    <div class=\"core\" id=\"core\">\r\n      <div class=\"core-border\"><\/div>\r\n      <!-- Mobile phone SVG icon -->\r\n      <svg class=\"mobile-icon\" viewBox=\"0 0 32 48\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\r\n        <rect x=\"1\" y=\"1\" width=\"30\" height=\"46\" rx=\"5\" stroke=\"white\" stroke-width=\"1.8\"\/>\r\n        <line x1=\"11\" y1=\"6\" x2=\"21\" y2=\"6\" stroke=\"white\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/>\r\n        <circle cx=\"16\" cy=\"41\" r=\"2.5\" stroke=\"white\" stroke-width=\"1.5\"\/>\r\n      <\/svg>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"content\">\r\n    <div class=\"heading\">MOBILE<\/div>\r\n    <div class=\"divider\"><\/div>\r\n    <a class=\"phone-link\" href=\"tel:+447438562563\">\r\n      +44 7438 562563\r\n    <\/a>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\n  const canvas = document.getElementById('particleCanvas');\r\n  const ctx = canvas.getContext('2d');\r\n  const section = document.getElementById('section');\r\n  const core = document.getElementById('core');\r\n\r\n  let mouse = { x: -999, y: -999 };\r\n  let centerX, centerY;\r\n  let particles = [];\r\n  const PARTICLE_COUNT = 55;\r\n\r\n  function resize() {\r\n    canvas.width  = section.offsetWidth;\r\n    canvas.height = section.offsetHeight;\r\n    centerX = canvas.width  \/ 2;\r\n    centerY = canvas.height \/ 2;\r\n  }\r\n  resize();\r\n  window.addEventListener('resize', () => { resize(); initParticles(); });\r\n\r\n  class Particle {\r\n    constructor() { this.reset(); }\r\n    reset() {\r\n      const orbits = [130, 100, 74];\r\n      this.orbit  = orbits[Math.floor(Math.random() * orbits.length)] + (Math.random() - 0.5) * 22;\r\n      this.angle  = Math.random() * Math.PI * 2;\r\n      this.speed  = (0.003 + Math.random() * 0.007) * (Math.random() < 0.5 ? 1 : -1);\r\n      this.size   = 1.2 + Math.random() * 2;\r\n      this.alpha  = 0.3 + Math.random() * 0.7;\r\n      this.hue    = 20  + Math.random() * 30;\r\n      this.phase  = Math.random() * Math.PI * 2;\r\n      this.twinkleSpeed = 0.02 + Math.random() * 0.04;\r\n    }\r\n    update(mx, my) {\r\n      this.angle += this.speed;\r\n      this.phase += this.twinkleSpeed;\r\n      const px = centerX + Math.cos(this.angle) * this.orbit;\r\n      const py = centerY + Math.sin(this.angle) * this.orbit;\r\n      const dx = px - mx, dy = py - my;\r\n      const dist = Math.sqrt(dx * dx + dy * dy);\r\n      if (dist < 70) {\r\n        const push = (70 - dist) \/ 70;\r\n        this.angle += push * 0.04 * (Math.random() < 0.5 ? 1 : -1);\r\n      }\r\n    }\r\n    draw() {\r\n      const x = centerX + Math.cos(this.angle) * this.orbit;\r\n      const y = centerY + Math.sin(this.angle) * this.orbit;\r\n      const twinkle = 0.5 + 0.5 * Math.sin(this.phase);\r\n      ctx.save();\r\n      ctx.globalAlpha = this.alpha * twinkle;\r\n      const grd = ctx.createRadialGradient(x, y, 0, x, y, this.size * 2.5);\r\n      grd.addColorStop(0,   `hsla(${this.hue}, 90%, 70%, 1)`);\r\n      grd.addColorStop(0.4, `hsla(${this.hue}, 80%, 55%, 0.6)`);\r\n      grd.addColorStop(1,   'transparent');\r\n      ctx.fillStyle = grd;\r\n      ctx.beginPath();\r\n      ctx.arc(x, y, this.size * 2.5, 0, Math.PI * 2);\r\n      ctx.fill();\r\n      ctx.restore();\r\n    }\r\n  }\r\n\r\n  class Sparkle {\r\n    constructor() { this.reset(); }\r\n    reset() {\r\n      const angle = Math.random() * Math.PI * 2;\r\n      const orbit = 40 + Math.random() * 18;\r\n      this.x = centerX + Math.cos(angle) * orbit;\r\n      this.y = centerY + Math.sin(angle) * orbit;\r\n      const speed = 0.4 + Math.random() * 0.8;\r\n      const dir   = angle + (Math.random() - 0.5) * 1.2;\r\n      this.vx   = Math.cos(dir) * speed;\r\n      this.vy   = Math.sin(dir) * speed;\r\n      this.life  = 1;\r\n      this.decay = 0.015 + Math.random() * 0.025;\r\n      this.size  = 0.8 + Math.random() * 1.5;\r\n    }\r\n    update() {\r\n      this.x  += this.vx;\r\n      this.y  += this.vy;\r\n      this.life -= this.decay;\r\n      this.vx *= 0.97;\r\n      this.vy *= 0.97;\r\n    }\r\n    draw() {\r\n      ctx.save();\r\n      ctx.globalAlpha = this.life * 0.8;\r\n      ctx.fillStyle   = `rgba(255, 160, 60, ${this.life})`;\r\n      ctx.shadowBlur  = 6;\r\n      ctx.shadowColor = 'rgba(192,96,20,0.9)';\r\n      ctx.beginPath();\r\n      ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\r\n      ctx.fill();\r\n      ctx.restore();\r\n    }\r\n  }\r\n\r\n  function initParticles() {\r\n    particles = [];\r\n    for (let i = 0; i < PARTICLE_COUNT; i++) particles.push(new Particle());\r\n  }\r\n  initParticles();\r\n\r\n  let sparkles = [];\r\n  let sparkleTimer = 0;\r\n\r\n  function animate() {\r\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n    particles.forEach(p => { p.update(mouse.x, mouse.y); p.draw(); });\r\n    sparkleTimer++;\r\n    if (sparkleTimer % 4 === 0 && sparkles.length < 30) sparkles.push(new Sparkle());\r\n    sparkles = sparkles.filter(s => s.life > 0);\r\n    sparkles.forEach(s => { s.update(); s.draw(); });\r\n    requestAnimationFrame(animate);\r\n  }\r\n  animate();\r\n\r\n  document.addEventListener('mousemove', e => {\r\n    const rect = canvas.getBoundingClientRect();\r\n    mouse.x = e.clientX - rect.left;\r\n    mouse.y = e.clientY - rect.top;\r\n  });\r\n\r\n  document.addEventListener('touchmove', e => {\r\n    const rect = canvas.getBoundingClientRect();\r\n    mouse.x = e.touches[0].clientX - rect.left;\r\n    mouse.y = e.touches[0].clientY - rect.top;\r\n  }, { passive: true });\r\n\r\n  core.addEventListener('mouseenter', () => {\r\n    for (let i = 0; i < 15; i++) sparkles.push(new Sparkle());\r\n  });\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-20a8c0b e-con-full e-flex e-con e-child\" data-id=\"20a8c0b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t<div class=\"elementor-element elementor-element-5a50f75 e-con-full e-flex e-con e-child\" data-id=\"5a50f75\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a7cbfb8 elementor-widget elementor-widget-shortcode\" data-id=\"a7cbfb8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f782-o1\" lang=\"en-US\" dir=\"ltr\" data-wpcf7-id=\"782\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/index.php\/wp-json\/wp\/v2\/pages\/594#wpcf7-f782-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Contact form\" novalidate=\"novalidate\" data-status=\"init\">\n<fieldset class=\"hidden-fields-container\"><input type=\"hidden\" name=\"_wpcf7\" value=\"782\" \/><input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.1.5\" \/><input type=\"hidden\" name=\"_wpcf7_locale\" value=\"en_US\" \/><input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f782-o1\" \/><input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/><input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/>\n<\/fieldset>\n<div class=\"pv-form\">\n\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-name\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Your Name\" value=\"\" type=\"text\" name=\"your-name\" \/><\/span>\n\t<\/p>\n\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-email\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Your Email\" value=\"\" type=\"email\" name=\"your-email\" \/><\/span>\n\t<\/p>\n\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-phone\"><input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-tel wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-tel\" aria-required=\"true\" aria-invalid=\"false\" placeholder=\"Your Phone\" value=\"\" type=\"tel\" name=\"your-phone\" \/><\/span>\n\t<\/p>\n\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"your-message\"><textarea cols=\"40\" rows=\"10\" maxlength=\"2000\" class=\"wpcf7-form-control wpcf7-textarea\" aria-invalid=\"false\" placeholder=\"Your Message\" name=\"your-message\"><\/textarea><\/span>\n\t<\/p>\n\t<p><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Send Message\" \/>\n\t<\/p>\n<\/div><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0b7e157 e-con-full e-flex e-con e-child\" data-id=\"0b7e157\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-babb448 elementor-widget elementor-widget-html\" data-id=\"babb448\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>Cosmic Email Orbit<\/title>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Montserrat:wght@400;700;900&display=swap\" rel=\"stylesheet\">\r\n<style>\r\n\r\n\r\n  .section {\r\n    position: relative;\r\n    width: 100%;\r\n    min-height: 400px;\r\n    display: flex;\r\n    flex-direction: column;\r\n    align-items: center;\r\n    justify-content: center;\r\n    padding: 20px 20px;\r\n  }\r\n\r\n \r\n   \r\n   \r\n    \r\n   \r\n\r\n  \/* Radial glow background *\/\r\n  .bg-glow {\r\n    position: absolute;\r\n    top: 50%;\r\n    left: 50%;\r\n    transform: translate(-50%, -50%);\r\n    width: 320px;\r\n    height: 320px;\r\n    border-radius: 50%;\r\n    background: radial-gradient(circle, rgba(192,96,20,0.18) 0%, rgba(11,60,73,0.10) 50%, transparent 75%);\r\n    pointer-events: none;\r\n    animation: bgPulse 4s ease-in-out infinite;\r\n  }\r\n\r\n  @keyframes bgPulse {\r\n    0%, 100% { opacity: 0.7; transform: translate(-50%, -50%) scale(1); }\r\n    50% { opacity: 1; transform: translate(-50%, -50%) scale(1.12); }\r\n  }\r\n\r\n  \/* Orbit container *\/\r\n  .orbit-system {\r\n    position: relative;\r\n    width: 260px;\r\n    height: 260px;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    margin-bottom: 32px;\r\n  }\r\n\r\n  \/* Orbit rings *\/\r\n  .ring {\r\n    position: absolute;\r\n    border-radius: 50%;\r\n    border: 1px solid;\r\n    top: 50%;\r\n    left: 50%;\r\n  }\r\n\r\n  .ring-1 {\r\n    width: 260px; height: 260px;\r\n    margin-left: -130px; margin-top: -130px;\r\n    border-color: rgba(192, 96, 20, 0.5);\r\n    box-shadow: 0 0 8px rgba(192,96,20,0.3), inset 0 0 8px rgba(192,96,20,0.1);\r\n    animation: rotateRing1 18s linear infinite;\r\n  }\r\n  .ring-2 {\r\n    width: 200px; height: 200px;\r\n    margin-left: -100px; margin-top: -100px;\r\n    border-color: rgba(11, 60, 73, 0.8);\r\n    box-shadow: 0 0 12px rgba(11,60,73,0.5), inset 0 0 6px rgba(11,60,73,0.2);\r\n    animation: rotateRing2 12s linear infinite reverse;\r\n  }\r\n  .ring-3 {\r\n    width: 148px; height: 148px;\r\n    margin-left: -74px; margin-top: -74px;\r\n    border-color: rgba(192, 96, 20, 0.35);\r\n    box-shadow: 0 0 6px rgba(192,96,20,0.25);\r\n    animation: rotateRing3 8s linear infinite;\r\n  }\r\n\r\n  @keyframes rotateRing1 { to { transform: rotate(360deg); } }\r\n  @keyframes rotateRing2 { to { transform: rotate(360deg); } }\r\n  @keyframes rotateRing3 { to { transform: rotate(360deg); } }\r\n\r\n  \/* Orbital dots on rings *\/\r\n  .ring::after, .ring::before {\r\n    content: '';\r\n    position: absolute;\r\n    border-radius: 50%;\r\n    background: #C06014;\r\n    box-shadow: 0 0 8px 3px rgba(192,96,20,0.9);\r\n  }\r\n  .ring-1::after  { width: 8px; height: 8px; top: -4px; left: 50%; margin-left: -4px; }\r\n  .ring-1::before { width: 5px; height: 5px; bottom: -2.5px; right: 30%; background: rgba(192,96,20,0.6); box-shadow: 0 0 6px 2px rgba(192,96,20,0.5); }\r\n  .ring-2::after  { width: 6px; height: 6px; top: 20%; right: -3px; }\r\n  .ring-2::before { width: 4px; height: 4px; bottom: 15%; left: -2px; background: #0B3C49; box-shadow: 0 0 6px 2px rgba(11,60,73,0.8); }\r\n  .ring-3::after  { width: 5px; height: 5px; top: -2.5px; right: 25%; }\r\n  .ring-3::before { width: 3px; height: 3px; bottom: -1.5px; left: 20%; background: rgba(192,96,20,0.7); box-shadow: 0 0 4px rgba(192,96,20,0.7); }\r\n\r\n  \/* Core *\/\r\n  .core {\r\n    position: absolute;\r\n    width: 90px;\r\n    height: 90px;\r\n    border-radius: 50%;\r\n    background: radial-gradient(circle at 35% 35%, rgba(255,160,80,0.3), rgba(192,96,20,0.15) 60%, rgba(11,60,73,0.1));\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    z-index: 5;\r\n    cursor: pointer;\r\n    animation: corePulse 3s ease-in-out infinite;\r\n    transition: filter 0.3s ease;\r\n  }\r\n\r\n  .core-border {\r\n    position: absolute;\r\n    inset: 0;\r\n    border-radius: 50%;\r\n    border: 1.5px solid rgba(192,96,20,0.6);\r\n    box-shadow:\r\n      0 0 20px rgba(192,96,20,0.4),\r\n      0 0 40px rgba(192,96,20,0.2),\r\n      inset 0 0 20px rgba(192,96,20,0.1);\r\n  }\r\n\r\n  .core:hover {\r\n    filter: brightness(1.4);\r\n    animation-play-state: paused;\r\n  }\r\n\r\n  @keyframes corePulse {\r\n    0%, 100% { transform: scale(1); filter: drop-shadow(0 0 12px rgba(192,96,20,0.6)); }\r\n    50% { transform: scale(1.06); filter: drop-shadow(0 0 22px rgba(192,96,20,0.9)); }\r\n  }\r\n\r\n  \/* Email SVG icon *\/\r\n  .email-icon {\r\n    width: 38px;\r\n    height: 28px;\r\n    z-index: 6;\r\n    filter: drop-shadow(0 0 8px rgba(255,200,120,0.9));\r\n  }\r\n\r\n  \/* Energy wave *\/\r\n  .wave {\r\n    position: absolute;\r\n    border-radius: 50%;\r\n    border: 1px solid rgba(192,96,20,0.6);\r\n    top: 50%; left: 50%;\r\n    transform: translate(-50%, -50%) scale(0.4);\r\n    opacity: 0;\r\n    pointer-events: none;\r\n    animation: waveExpand 3.5s ease-out infinite;\r\n  }\r\n  .wave:nth-child(2) { animation-delay: 1.2s; }\r\n  .wave:nth-child(3) { animation-delay: 2.4s; }\r\n\r\n  @keyframes waveExpand {\r\n    0%   { width: 90px;  height: 90px;  opacity: 0.8; transform: translate(-50%, -50%); }\r\n    100% { width: 280px; height: 280px; opacity: 0;   transform: translate(-50%, -50%); }\r\n  }\r\n\r\n  \/* Zodiac symbols *\/\r\n  .zodiac {\r\n    position: absolute;\r\n    font-size: 14px;\r\n    color: rgba(192,96,20,0.55);\r\n    text-shadow: 0 0 6px rgba(192,96,20,0.4);\r\n    pointer-events: none;\r\n    animation: floatZodiac var(--dur, 6s) ease-in-out infinite;\r\n    font-family: serif;\r\n  }\r\n\r\n  @keyframes floatZodiac {\r\n    0%, 100% { opacity: 0.2; transform: translate(0, 0) scale(1); }\r\n    50%       { opacity: 0.7; transform: translate(var(--tx, 4px), var(--ty, -6px)) scale(1.1); }\r\n  }\r\n\r\n  \/* Canvas for particles *\/\r\n  #particleCanvas {\r\n    position: absolute;\r\n    top: 0; left: 0;\r\n    width: 100%; height: 100%;\r\n    pointer-events: none;\r\n    z-index: 1;\r\n  }\r\n\r\n  \/* Text content *\/\r\n  .content {\r\n    position: relative;\r\n    z-index: 6;\r\n    text-align: center;\r\n  }\r\n\r\n  .heading {\r\n    font-family: 'Montserrat', sans-serif;\r\n    font-weight: 700;\r\n    font-size: 1.2rem;\r\n    letter-spacing: 0.35em;\r\n    color: #FFFFFF;\r\n    text-shadow:\r\n      0 0 10px rgba(192,96,20,0.5),\r\n      0 0 30px rgba(192,96,20,0.2);\r\n    margin-bottom: 10px;\r\n  }\r\n\r\n  .divider {\r\n    width: 60px;\r\n    height: 1px;\r\n    background: linear-gradient(90deg, transparent, rgba(192,96,20,0.7), transparent);\r\n    margin: 0 auto 12px;\r\n  }\r\n\r\n  .email-link {\r\n    font-family: 'Montserrat', sans-serif;\r\n    font-weight: 700;\r\n    font-size: 0.7rem;\r\n    letter-spacing: 0.12em;\r\n    color: rgba(255,255,255,0.85);\r\n    text-decoration: none;\r\n    text-transform: uppercase;\r\n    text-shadow: 0 0 8px rgba(192,96,20,0.3);\r\n    transition: all 0.3s ease;\r\n    display: block;\r\n  }\r\n\r\n  .email-link:hover {\r\n    color: #FFFFFF;\r\n    text-shadow: 0 0 16px rgba(192,96,20,0.8), 0 0 32px rgba(192,96,20,0.4);\r\n    letter-spacing: 0.16em;\r\n  }\r\n<\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div class=\"section\" id=\"section\">\r\n  <canvas id=\"particleCanvas\"><\/canvas>\r\n  <div class=\"bg-glow\"><\/div>\r\n\r\n  <div class=\"orbit-system\" id=\"orbitSystem\">\r\n    <!-- Energy waves -->\r\n    <div class=\"wave\"><\/div>\r\n    <div class=\"wave\"><\/div>\r\n    <div class=\"wave\"><\/div>\r\n\r\n    <!-- Rings -->\r\n    <div class=\"ring ring-1\"><\/div>\r\n    <div class=\"ring ring-2\"><\/div>\r\n    <div class=\"ring ring-3\"><\/div>\r\n\r\n    <!-- Zodiac symbols -->\r\n    <span class=\"zodiac\" style=\"top:8%;right:12%;--dur:7s;--tx:5px;--ty:-4px;\">\u2653<\/span>\r\n    <span class=\"zodiac\" style=\"top:15%;left:8%;--dur:9s;--tx:-4px;--ty:-6px;\">\u2652<\/span>\r\n    <span class=\"zodiac\" style=\"bottom:10%;right:10%;--dur:6s;--tx:3px;--ty:5px;\">\u2650<\/span>\r\n    <span class=\"zodiac\" style=\"bottom:12%;left:12%;--dur:8s;--tx:-5px;--ty:4px;\">\u264e<\/span>\r\n    <span class=\"zodiac\" style=\"top:45%;left:2%;--dur:10s;--tx:-3px;--ty:-3px;font-size:11px;\">\u264b<\/span>\r\n    <span class=\"zodiac\" style=\"top:40%;right:2%;--dur:7.5s;--tx:4px;--ty:2px;font-size:11px;\">\u264a<\/span>\r\n\r\n    <!-- Core -->\r\n    <div class=\"core\" id=\"core\">\r\n      <div class=\"core-border\"><\/div>\r\n      <svg class=\"email-icon\" viewBox=\"0 0 38 28\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\r\n        <rect x=\"1\" y=\"1\" width=\"36\" height=\"26\" rx=\"3\" stroke=\"white\" stroke-width=\"1.8\"\/>\r\n        <path d=\"M1 4L19 17L37 4\" stroke=\"white\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/>\r\n      <\/svg>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"content\">\r\n    <div class=\"heading\">EMAIL<\/div>\r\n    <div class=\"divider\"><\/div>\r\n    <a class=\"email-link\" href=\"mailto:psychicreadinginlondon@gmail.com\">\r\n      psychicreadinginlondon@gmail.com\r\n    <\/a>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\n  const canvas = document.getElementById('particleCanvas');\r\n  const ctx = canvas.getContext('2d');\r\n  const section = document.getElementById('section');\r\n  const core = document.getElementById('core');\r\n\r\n  let mouse = { x: -999, y: -999 };\r\n  let centerX, centerY;\r\n  let particles = [];\r\n  const PARTICLE_COUNT = 55;\r\n\r\n  function resize() {\r\n    canvas.width  = section.offsetWidth;\r\n    canvas.height = section.offsetHeight;\r\n    centerX = canvas.width  \/ 2;\r\n    centerY = canvas.height \/ 2;\r\n  }\r\n  resize();\r\n  window.addEventListener('resize', () => { resize(); initParticles(); });\r\n\r\n  \/* \u2500\u2500 Orbital particles \u2500\u2500 *\/\r\n  class Particle {\r\n    constructor() { this.reset(); }\r\n    reset() {\r\n      const orbits = [130, 100, 74];\r\n      this.orbit  = orbits[Math.floor(Math.random() * orbits.length)] + (Math.random() - 0.5) * 22;\r\n      this.angle  = Math.random() * Math.PI * 2;\r\n      this.speed  = (0.003 + Math.random() * 0.007) * (Math.random() < 0.5 ? 1 : -1);\r\n      this.size   = 1.2 + Math.random() * 2;\r\n      this.alpha  = 0.3 + Math.random() * 0.7;\r\n      this.hue    = 20  + Math.random() * 30;\r\n      this.phase  = Math.random() * Math.PI * 2;\r\n      this.twinkleSpeed = 0.02 + Math.random() * 0.04;\r\n    }\r\n    update(mx, my) {\r\n      this.angle += this.speed;\r\n      this.phase += this.twinkleSpeed;\r\n      const px = centerX + Math.cos(this.angle) * this.orbit;\r\n      const py = centerY + Math.sin(this.angle) * this.orbit;\r\n      const dx = px - mx, dy = py - my;\r\n      const dist = Math.sqrt(dx * dx + dy * dy);\r\n      if (dist < 70) {\r\n        const push = (70 - dist) \/ 70;\r\n        this.angle += push * 0.04 * (Math.random() < 0.5 ? 1 : -1);\r\n      }\r\n    }\r\n    draw() {\r\n      const x = centerX + Math.cos(this.angle) * this.orbit;\r\n      const y = centerY + Math.sin(this.angle) * this.orbit;\r\n      const twinkle = 0.5 + 0.5 * Math.sin(this.phase);\r\n      ctx.save();\r\n      ctx.globalAlpha = this.alpha * twinkle;\r\n      const grd = ctx.createRadialGradient(x, y, 0, x, y, this.size * 2.5);\r\n      grd.addColorStop(0,   `hsla(${this.hue}, 90%, 70%, 1)`);\r\n      grd.addColorStop(0.4, `hsla(${this.hue}, 80%, 55%, 0.6)`);\r\n      grd.addColorStop(1,   'transparent');\r\n      ctx.fillStyle = grd;\r\n      ctx.beginPath();\r\n      ctx.arc(x, y, this.size * 2.5, 0, Math.PI * 2);\r\n      ctx.fill();\r\n      ctx.restore();\r\n    }\r\n  }\r\n\r\n  \/* \u2500\u2500 Sparkle burst particles \u2500\u2500 *\/\r\n  class Sparkle {\r\n    constructor() { this.reset(); }\r\n    reset() {\r\n      const angle = Math.random() * Math.PI * 2;\r\n      const orbit = 40 + Math.random() * 18;\r\n      this.x = centerX + Math.cos(angle) * orbit;\r\n      this.y = centerY + Math.sin(angle) * orbit;\r\n      const speed = 0.4 + Math.random() * 0.8;\r\n      const dir   = angle + (Math.random() - 0.5) * 1.2;\r\n      this.vx   = Math.cos(dir) * speed;\r\n      this.vy   = Math.sin(dir) * speed;\r\n      this.life  = 1;\r\n      this.decay = 0.015 + Math.random() * 0.025;\r\n      this.size  = 0.8 + Math.random() * 1.5;\r\n    }\r\n    update() {\r\n      this.x  += this.vx;\r\n      this.y  += this.vy;\r\n      this.life -= this.decay;\r\n      this.vx *= 0.97;\r\n      this.vy *= 0.97;\r\n    }\r\n    draw() {\r\n      ctx.save();\r\n      ctx.globalAlpha   = this.life * 0.8;\r\n      ctx.fillStyle     = `rgba(255, 160, 60, ${this.life})`;\r\n      ctx.shadowBlur    = 6;\r\n      ctx.shadowColor   = 'rgba(192,96,20,0.9)';\r\n      ctx.beginPath();\r\n      ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\r\n      ctx.fill();\r\n      ctx.restore();\r\n    }\r\n  }\r\n\r\n  function initParticles() {\r\n    particles = [];\r\n    for (let i = 0; i < PARTICLE_COUNT; i++) particles.push(new Particle());\r\n  }\r\n  initParticles();\r\n\r\n  let sparkles = [];\r\n  let sparkleTimer = 0;\r\n\r\n  function animate() {\r\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n\r\n    particles.forEach(p => { p.update(mouse.x, mouse.y); p.draw(); });\r\n\r\n    sparkleTimer++;\r\n    if (sparkleTimer % 4 === 0 && sparkles.length < 30) sparkles.push(new Sparkle());\r\n    sparkles = sparkles.filter(s => s.life > 0);\r\n    sparkles.forEach(s => { s.update(); s.draw(); });\r\n\r\n    requestAnimationFrame(animate);\r\n  }\r\n  animate();\r\n\r\n  \/* \u2500\u2500 Input events \u2500\u2500 *\/\r\n  document.addEventListener('mousemove', e => {\r\n    const rect = canvas.getBoundingClientRect();\r\n    mouse.x = e.clientX - rect.left;\r\n    mouse.y = e.clientY - rect.top;\r\n  });\r\n\r\n  document.addEventListener('touchmove', e => {\r\n    const rect = canvas.getBoundingClientRect();\r\n    mouse.x = e.touches[0].clientX - rect.left;\r\n    mouse.y = e.touches[0].clientY - rect.top;\r\n  }, { passive: true });\r\n\r\n  core.addEventListener('mouseenter', () => {\r\n    for (let i = 0; i < 15; i++) sparkles.push(new Sparkle());\r\n  });\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4e33563 e-flex e-con-boxed e-con e-parent\" data-id=\"4e33563\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-8cc2247 e-con-full e-flex e-con e-child\" data-id=\"8cc2247\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6365967 elementor-widget elementor-widget-image\" data-id=\"6365967\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"tel:+447438562563\">\n\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"800\" height=\"800\" src=\"https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group261-Photoroom-1024x1024.webp\" class=\"attachment-large size-large wp-image-747\" alt=\"\" srcset=\"https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group261-Photoroom-1024x1024.webp 1024w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group261-Photoroom-300x300.webp 300w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group261-Photoroom-150x150.webp 150w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group261-Photoroom-768x768.webp 768w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group261-Photoroom.webp 1408w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1314c0f e-con-full e-flex e-con e-child\" data-id=\"1314c0f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3271e39 elementor-widget elementor-widget-image\" data-id=\"3271e39\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<a href=\"tel:+447438562563\">\n\t\t\t\t\t\t\t<img decoding=\"async\" width=\"800\" height=\"838\" src=\"https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group252-1-977x1024.webp\" class=\"attachment-large size-large wp-image-749\" alt=\"\" srcset=\"https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group252-1-977x1024.webp 977w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group252-1-286x300.webp 286w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group252-1-768x805.webp 768w, https:\/\/panditjaydev.co.uk\/wp-content\/uploads\/2026\/04\/Group252-1.webp 1344w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/>\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-155623a e-flex e-con-boxed e-con e-parent\" data-id=\"155623a\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7d208fa elementor-widget elementor-widget-html\" data-id=\"7d208fa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\"\/>\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"\/>\r\n<title>Terra-Prime<\/title>\r\n<style>\r\n \r\n  #c{display:block;width:100%;height:100%;}\r\n  .sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);}\r\n\r\n  #ui-top{\r\n    position:absolute;top:14px;left:50%;transform:translateX(-50%);\r\n    text-align:center;pointer-events:none;z-index:5;\r\n  }\r\n  #ui-top .title{\r\n    font-family:'Courier New',monospace;font-size:clamp(8px,2.5vw,11px);\r\n    letter-spacing:0.25em;color:#F1D1B5;\r\n  }\r\n  #ui-top .sub{\r\n    font-family:'Courier New',monospace;font-size:clamp(7px,2vw,9px);\r\n    letter-spacing:0.15em;color:#F1D1B5;margin-top:2px;\r\n  }\r\n\r\n  #hint{\r\n    position:absolute;bottom:14px;left:50%;transform:translateX(-50%);\r\n    font-family:'Courier New',monospace;font-size:clamp(7px,2vw,9px);\r\n    color:#F1D1B5;letter-spacing:0.10em;white-space:nowrap;\r\n    pointer-events:none;transition:opacity 0.5s;z-index:5;\r\n  }\r\n  @media(max-width:480px){\r\n    #hint{font-size:7px;letter-spacing:0.06em;bottom:10px;}\r\n  }\r\n\r\n  \/* ---- MAP OVERLAY ---- *\/\r\n  #map-overlay{\r\n    position:absolute;inset:0;background:rgba(0,0,0,0.22);\r\n    opacity:0;pointer-events:none;transition:opacity 0.6s;\r\n    display:flex;flex-direction:column;align-items:center;justify-content:center;\r\n    padding:16px;z-index:20;\r\n  }\r\n  #map-overlay.active{opacity:1;pointer-events:all;}\r\n  #map-overlay .lock-label{\r\n    font-family:'Courier New',monospace;font-size:clamp(8px,2.5vw,15px);\r\n    color:rgba(100,220,255,0.7);letter-spacing:0.2em;margin-bottom:10px;\r\n  }\r\n  #map-wrapper{\r\n    border:1px solid rgba(100,220,255,0.3);border-radius:8px;\r\n    overflow:hidden;width:min(500px,calc(100vw - 12px));\r\n    height:min(380px,calc(100vh - 180px));position:relative;\r\n  }\r\n  #map-frame{\r\n    border:none;opacity:0;transition:opacity 1s;\r\n    width:100%;height:100%;\r\n  }\r\n  #map-loader{\r\n    position:absolute;inset:0;display:flex;align-items:center;justify-content:center;\r\n    font-family:'Courier New',monospace;font-size:11px;color:rgba(100,220,255,0.5);\r\n  }\r\n  #map-overlay .address{\r\n    margin-top:12px;font-family:'Courier New',monospace;\r\n    font-size:clamp(7px,2vw,10px);\r\n    color:rgba(100,220,255,0.6);letter-spacing:0.10em;text-align:center;\r\n  }\r\n  #close-map{\r\n    margin-top:12px;font-family:'Courier New',monospace;font-size:clamp(8px,2vw,9px);\r\n    color:rgba(100,220,255,0.5);background:transparent;\r\n    border:1px solid rgba(100,220,255,0.25);padding:8px 24px;\r\n    letter-spacing:0.12em;cursor:pointer;border-radius:4px;\r\n    touch-action:manipulation;\r\n  }\r\n  #close-map:hover,#close-map:active{background:rgba(100,220,255,0.08);}\r\n\r\n  \/* ---- BOTTOM IMAGE SLOT ---- *\/\r\n  #bottom-image{\r\n    position:absolute;bottom:0;left:50%;transform:translateX(-50%);\r\n    width:min(360px,90vw);pointer-events:none;z-index:0;\r\n  }\r\n  #bottom-image img{width:100%;display:block;mix-blend-mode:screen;}\r\n\r\n  \/* pinch-zoom hint badge on mobile *\/\r\n  #mobile-hint{\r\n    display:none;\r\n    position:absolute;bottom:36px;left:50%;transform:translateX(-50%);\r\n    font-family:'Courier New',monospace;font-size:7px;\r\n    color:rgba(241,209,181,0.5);letter-spacing:0.08em;\r\n    pointer-events:none;z-index:5;white-space:nowrap;\r\n  }\r\n  @media(max-width:600px){#mobile-hint{display:block;}}\r\n<\/style>\r\n<\/head>\r\n<body>\r\n<div id=\"root\">\r\n  <h2 class=\"sr-only\">Terra-Prime interactive 3D globe with light rays pointing to London<\/h2>\r\n  <canvas id=\"c\"><\/canvas>\r\n\r\n  <div id=\"ui-top\">\r\n    <div class=\"title\">\u2014 LOCATE PANDIT JI \u2014<\/div>\r\n    <div class=\"sub\">OUR CELESTIAL HUB<\/div>\r\n  <\/div>\r\n\r\n  <div id=\"hint\">SCROLL TO ZOOM \u00b7 DRAG TO ROTATE \u00b7 CLICK PIN FOR MAP<\/div>\r\n  <div id=\"mobile-hint\">PINCH TO ZOOM \u00b7 DRAG TO ROTATE \u00b7 TAP PIN FOR MAP<\/div>\r\n\r\n  <div id=\"bottom-image\">\r\n    <img decoding=\"async\" src=\"\"\/>\r\n  <\/div>\r\n\r\n  <div id=\"map-overlay\">\r\n    <div class=\"lock-label\">\u25c8 LOCATION LOCKED<\/div>\r\n    <div id=\"map-wrapper\">\r\n      <iframe id=\"map-frame\" src=\"\" loading=\"lazy\"><\/iframe>\r\n      <div id=\"map-loader\">LOADING MAP...<\/div>\r\n    <\/div>\r\n    <div class=\"address\">17 THE BROADWAY \u00b7 LONDON UB1 1JR \u00b7 UNITED KINGDOM<\/div>\r\n    <button id=\"close-map\">CLOSE \u2715<\/button>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"><\/script>\r\n<script>\r\n(function(){\r\n\r\nconst canvas = document.getElementById('c');\r\nconst root   = document.getElementById('root');\r\nconst W = () => root.clientWidth;\r\nconst H = () => root.clientHeight;\r\nconst isMobile = () => W() < 600;\r\n\r\n\/* \u2500\u2500 RENDERER \u2500\u2500 *\/\r\nconst renderer = new THREE.WebGLRenderer({canvas, antialias:true, alpha:true});\r\nrenderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\r\nrenderer.setClearColor(0x000000, 0);\r\nrenderer.setSize(W(), H());\r\n\r\nconst scene  = new THREE.Scene();\r\nconst camera = new THREE.PerspectiveCamera(45, W()\/H(), 0.1, 1000);\r\n\r\n\/\/ responsive initial zoom\r\nfunction getBaseZoom(){ return isMobile() ? 4.2 : 3.5; }\r\ncamera.position.set(0, 0, getBaseZoom());\r\n\r\nconst clock = new THREE.Clock();\r\n\r\n\/* \u2500\u2500 GLOBE \u2500\u2500 *\/\r\nconst globeGeo = new THREE.SphereGeometry(1, 64, 64);\r\nconst globeMat = new THREE.MeshPhongMaterial({\r\n  color: 0x1a4a6e,\r\n  specular: new THREE.Color(0x226688),\r\n  shininess: 15,\r\n});\r\nnew THREE.TextureLoader().load(\r\n  'https:\/\/unpkg.com\/three-globe\/example\/img\/earth-blue-marble.jpg',\r\n  tex => { globeMat.map = tex; globeMat.needsUpdate = true; }\r\n);\r\nconst globe = new THREE.Mesh(globeGeo, globeMat);\r\nscene.add(globe);\r\n\r\nconst atmMat = new THREE.MeshPhongMaterial({\r\n  color:0x44aaff, transparent:true, opacity:0.08,\r\n  side:THREE.FrontSide, depthWrite:false\r\n});\r\nscene.add(new THREE.Mesh(new THREE.SphereGeometry(1.04,64,64), atmMat));\r\n\r\n\/* \u2500\u2500 LIGHTS \u2500\u2500 *\/\r\nscene.add(new THREE.AmbientLight(0x223355, 0.6));\r\nconst sun = new THREE.DirectionalLight(0xffffff, 1.2);\r\nsun.position.set(5, 3, 5);\r\nscene.add(sun);\r\nconst rim = new THREE.DirectionalLight(0x4488ff, 0.4);\r\nrim.position.set(-5, -1, -3);\r\nscene.add(rim);\r\n\r\n\/* \u2500\u2500 ORBIT RINGS \u2500\u2500 *\/\r\nfunction makeRing(r, tilt, col) {\r\n  const pts = [];\r\n  for(let i = 0; i <= 128; i++){\r\n    const a = i\/128*Math.PI*2;\r\n    pts.push(new THREE.Vector3(r*Math.cos(a), 0, r*Math.sin(a)));\r\n  }\r\n  const line = new THREE.Line(\r\n    new THREE.BufferGeometry().setFromPoints(pts),\r\n    new THREE.LineBasicMaterial({color:col, transparent:true, opacity:0.5})\r\n  );\r\n  line.rotation.x = tilt;\r\n  return line;\r\n}\r\nconst rings = [\r\n  makeRing(1.38, Math.PI*0.18, 0x44ccff),\r\n  makeRing(1.55, Math.PI*0.42, 0x66aaff),\r\n  makeRing(1.72, Math.PI*0.68, 0x3388ff),\r\n];\r\nrings.forEach(r => scene.add(r));\r\n\r\nconst orbDots = rings.map((ring, i) => {\r\n  const dot = new THREE.Mesh(\r\n    new THREE.SphereGeometry(0.018, 8, 8),\r\n    new THREE.MeshBasicMaterial({color:[0xffee66,0x44ffcc,0xee88ff][i]})\r\n  );\r\n  ring.add(dot);\r\n  return { dot, r:[1.38,1.55,1.72][i], speed:[0.4,0.25,0.18][i], angle:Math.random()*Math.PI*2 };\r\n});\r\n\r\n\/* \u2500\u2500 LONDON PIN \u2500\u2500 *\/\r\nconst lat = 51.5127 * Math.PI\/180;\r\nconst lon = -0.3545 * Math.PI\/180;\r\nconst pinPos = new THREE.Vector3(\r\n  Math.cos(lat)*Math.sin(lon),\r\n  Math.sin(lat),\r\n  Math.cos(lat)*Math.cos(lon)\r\n).normalize();\r\n\r\nconst pin = new THREE.Mesh(\r\n  new THREE.SphereGeometry(0.022, 12, 12),\r\n  new THREE.MeshBasicMaterial({color:0xff4444})\r\n);\r\npin.position.copy(pinPos);\r\nglobe.add(pin);\r\n\r\nconst pulseMat = new THREE.MeshBasicMaterial({\r\n  color:0xff6644, transparent:true, opacity:0.8, side:THREE.DoubleSide\r\n});\r\nconst pulseRing = new THREE.Mesh(new THREE.RingGeometry(0.03,0.05,32), pulseMat);\r\npulseRing.position.copy(pinPos.clone().multiplyScalar(1.002));\r\npulseRing.lookAt(pinPos.clone().multiplyScalar(2));\r\nglobe.add(pulseRing);\r\n\r\n\/* \u2500\u2500 STARS \u2500\u2500 *\/\r\nconst starPos = [];\r\nfor(let i = 0; i < 2000; i++){\r\n  starPos.push((Math.random()-0.5)*100,(Math.random()-0.5)*100,(Math.random()-0.5)*100);\r\n}\r\nconst starGeo = new THREE.BufferGeometry();\r\nstarGeo.setAttribute('position', new THREE.Float32BufferAttribute(starPos, 3));\r\nscene.add(new THREE.Points(starGeo,\r\n  new THREE.PointsMaterial({color:0xffffff, size:0.08, transparent:true, opacity:0.6})\r\n));\r\n\r\n\/* \u2500\u2500 LIGHT RAYS \u2500\u2500 *\/\r\nconst raysCanvas = document.createElement('canvas');\r\nraysCanvas.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:4;';\r\nroot.appendChild(raysCanvas);\r\n\r\nconst NUM_RAYS = 28;\r\nconst rayData = Array.from({length:NUM_RAYS}, (_, i) => ({\r\n  phase:  Math.random() * Math.PI * 2,\r\n  speed:  0.4 + Math.random() * 0.8,\r\n  width:  0.5 + Math.random() * 2.2,\r\n  spread: -50 + i * (100\/(NUM_RAYS-1)),\r\n  len:    0.35 + Math.random() * 0.45,\r\n  hue:    160 + Math.random() * 60,\r\n  delay:  Math.random() * Math.PI * 2,\r\n}));\r\n\r\nfunction drawRays(t) {\r\n  const rc  = raysCanvas;\r\n  rc.width  = root.clientWidth;\r\n  rc.height = root.clientHeight;\r\n  const ctx = rc.getContext('2d');\r\n  ctx.clearRect(0, 0, rc.width, rc.height);\r\n\r\n  const ox = rc.width \/ 2;\r\n  const oy = rc.height + 30;\r\n\r\n  for(let i = 0; i < NUM_RAYS; i++){\r\n    const d = rayData[i];\r\n    const flicker = 0.12\r\n      + 0.10 * Math.sin(t * d.speed + d.phase)\r\n      + 0.05 * Math.sin(t * d.speed * 2.3 + d.delay);\r\n\r\n    const centerAngle = (d.spread - 90) * Math.PI \/ 180;\r\n    const rayLength   = rc.height * d.len;\r\n    const tipX = ox + Math.cos(centerAngle) * rayLength;\r\n    const tipY = oy + Math.sin(centerAngle) * rayLength;\r\n    const baseW  = 4 + d.width * 8;\r\n    const perpX  = Math.cos(centerAngle + Math.PI\/2);\r\n    const perpY  = Math.sin(centerAngle + Math.PI\/2);\r\n\r\n    const grad = ctx.createLinearGradient(ox, oy, tipX, tipY);\r\n    const h = d.hue;\r\n    grad.addColorStop(0,    `hsla(${h},100%,90%,${flicker*0.9})`);\r\n    grad.addColorStop(0.15, `hsla(${h},100%,80%,${flicker*0.7})`);\r\n    grad.addColorStop(0.5,  `hsla(${h},90%,70%,${flicker*0.35})`);\r\n    grad.addColorStop(1,    `hsla(${h},80%,60%,0)`);\r\n\r\n    ctx.beginPath();\r\n    ctx.moveTo(ox + perpX*baseW, oy + perpY*baseW);\r\n    ctx.lineTo(tipX, tipY);\r\n    ctx.lineTo(ox - perpX*baseW, oy - perpY*baseW);\r\n    ctx.closePath();\r\n    ctx.fillStyle = grad;\r\n    ctx.fill();\r\n  }\r\n\r\n  const coreAngle   = (-72) * Math.PI \/ 180;\r\n  const coreLen     = rc.height * 0.55;\r\n  const coreTipX    = ox + Math.cos(coreAngle) * coreLen;\r\n  const coreTipY    = oy + Math.sin(coreAngle) * coreLen;\r\n  const coreFlicker = 0.6 + 0.3 * Math.sin(t * 4);\r\n\r\n  const coreGrad = ctx.createLinearGradient(ox, oy, coreTipX, coreTipY);\r\n  coreGrad.addColorStop(0,   `rgba(150,255,220,${coreFlicker*0.95})`);\r\n  coreGrad.addColorStop(0.1, `rgba(100,255,200,${coreFlicker*0.75})`);\r\n  coreGrad.addColorStop(0.4, `rgba(60,220,180,${coreFlicker*0.4})`);\r\n  coreGrad.addColorStop(1,   `rgba(0,255,180,0)`);\r\n\r\n  const perpCX = Math.cos(coreAngle + Math.PI\/2);\r\n  const perpCY = Math.sin(coreAngle + Math.PI\/2);\r\n  ctx.beginPath();\r\n  ctx.moveTo(ox + perpCX*3.5, oy + perpCY*3.5);\r\n  ctx.lineTo(coreTipX, coreTipY);\r\n  ctx.lineTo(ox - perpCX*3.5, oy - perpCY*3.5);\r\n  ctx.closePath();\r\n  ctx.fillStyle = coreGrad;\r\n  ctx.fill();\r\n\r\n  const srcGlow = ctx.createRadialGradient(ox, oy, 0, ox, oy, 80);\r\n  srcGlow.addColorStop(0, `rgba(100,255,220,${0.25 + 0.1*Math.sin(t*3)})`);\r\n  srcGlow.addColorStop(1, 'rgba(0,255,180,0)');\r\n  ctx.beginPath();\r\n  ctx.arc(ox, oy, 80, 0, Math.PI*2);\r\n  ctx.fillStyle = srcGlow;\r\n  ctx.fill();\r\n}\r\n\r\n\/* \u2500\u2500 INTERACTION \u2500\u2500 *\/\r\nlet drag = false, lastX = 0, lastY = 0;\r\nlet rotY = 0, rotX = 0;\r\nlet zoom = getBaseZoom(), targetZoom = getBaseZoom(), zoomPhase = 'normal';\r\nlet autoRotate = true;\r\n\r\n\/\/ \u2500\u2500 Mouse \u2500\u2500\r\ncanvas.addEventListener('mousedown', e => {\r\n  drag = true; lastX = e.clientX; lastY = e.clientY; autoRotate = false;\r\n});\r\nwindow.addEventListener('mouseup',  () => { drag = false; setTimeout(()=>autoRotate=true, 2000); });\r\nwindow.addEventListener('mousemove', e => {\r\n  if(!drag) return;\r\n  rotY += (e.clientX - lastX) * 0.005;\r\n  rotX += (e.clientY - lastY) * 0.005;\r\n  rotX = Math.max(-1.2, Math.min(1.2, rotX));\r\n  lastX = e.clientX; lastY = e.clientY;\r\n});\r\n\r\n\/\/ \u2500\u2500 Touch: drag + pinch-to-zoom \u2500\u2500\r\nlet pinchDist0 = null;\r\nlet zoom0 = getBaseZoom();\r\n\r\ncanvas.addEventListener('touchstart', e => {\r\n  autoRotate = false;\r\n  if(e.touches.length === 1){\r\n    drag = true;\r\n    lastX = e.touches[0].clientX;\r\n    lastY = e.touches[0].clientY;\r\n  } else if(e.touches.length === 2){\r\n    drag = false;\r\n    pinchDist0 = Math.hypot(\r\n      e.touches[0].clientX - e.touches[1].clientX,\r\n      e.touches[0].clientY - e.touches[1].clientY\r\n    );\r\n    zoom0 = targetZoom;\r\n  }\r\n}, {passive:true});\r\n\r\ncanvas.addEventListener('touchmove', e => {\r\n  if(e.touches.length === 1 && drag){\r\n    rotY += (e.touches[0].clientX - lastX) * 0.005;\r\n    rotX += (e.touches[0].clientY - lastY) * 0.005;\r\n    rotX = Math.max(-1.2, Math.min(1.2, rotX));\r\n    lastX = e.touches[0].clientX;\r\n    lastY = e.touches[0].clientY;\r\n  } else if(e.touches.length === 2 && pinchDist0 !== null){\r\n    const dist = Math.hypot(\r\n      e.touches[0].clientX - e.touches[1].clientX,\r\n      e.touches[0].clientY - e.touches[1].clientY\r\n    );\r\n    const scale = pinchDist0 \/ dist;\r\n    targetZoom = Math.max(0.5, Math.min(4.5, zoom0 * scale));\r\n    document.getElementById('hint').style.opacity = '0';\r\n    if(targetZoom < 1.4 && zoomPhase === 'normal'){\r\n      zoomPhase = 'entering';\r\n      setTimeout(openMap, 700);\r\n    }\r\n  }\r\n}, {passive:true});\r\n\r\ncanvas.addEventListener('touchend', e => {\r\n  if(e.touches.length < 2) pinchDist0 = null;\r\n  if(e.touches.length === 0){\r\n    drag = false;\r\n    setTimeout(()=>autoRotate=true, 2000);\r\n  }\r\n}, {passive:true});\r\n\r\n\/\/ \u2500\u2500 Wheel zoom (desktop) \u2500\u2500\r\ncanvas.addEventListener('wheel', e => {\r\n  e.preventDefault();\r\n  targetZoom = Math.max(0.5, Math.min(4.5, targetZoom + e.deltaY * 0.005));\r\n  document.getElementById('hint').style.opacity = '0';\r\n  if(targetZoom < 1.4 && zoomPhase === 'normal'){\r\n    zoomPhase = 'entering';\r\n    setTimeout(openMap, 700);\r\n  }\r\n}, {passive:false});\r\n\r\n\/\/ \u2500\u2500 Click \/ tap pin \u2500\u2500\r\ncanvas.addEventListener('click', e => {\r\n  const rect = canvas.getBoundingClientRect();\r\n  const mx = ((e.clientX-rect.left)\/rect.width)*2 - 1;\r\n  const my = -((e.clientY-rect.top)\/rect.height)*2 + 1;\r\n  const ray = new THREE.Raycaster();\r\n  ray.setFromCamera({x:mx, y:my}, camera);\r\n  if(ray.intersectObject(pin, false).length) openMap();\r\n});\r\n\r\nfunction openMap(){\r\n  const ov = document.getElementById('map-overlay');\r\n  ov.classList.add('active');\r\n  const frame = document.getElementById('map-frame');\r\n  if(!frame.src || frame.src === window.location.href){\r\n    frame.src = 'https:\/\/www.openstreetmap.org\/export\/embed.html?bbox=-0.3745%2C51.5027%2C-0.3345%2C51.5227&layer=cyclemap&marker=51.5127%2C-0.3545';\r\n    frame.onload = () => {\r\n      frame.style.opacity = '1';\r\n      document.getElementById('map-loader').style.display = 'none';\r\n    };\r\n  }\r\n}\r\n\r\ndocument.getElementById('close-map').addEventListener('click', () => {\r\n  document.getElementById('map-overlay').classList.remove('active');\r\n  targetZoom = getBaseZoom();\r\n  zoomPhase  = 'normal';\r\n});\r\n\r\nwindow.addEventListener('resize', () => {\r\n  renderer.setSize(W(), H());\r\n  camera.aspect = W() \/ H();\r\n  camera.updateProjectionMatrix();\r\n  \/\/ recalibrate zoom on orientation change\r\n  const bz = getBaseZoom();\r\n  if(Math.abs(targetZoom - zoom) < 0.1) { targetZoom = bz; zoom = bz; }\r\n});\r\n\r\n\/* \u2500\u2500 ANIMATION LOOP \u2500\u2500 *\/\r\nfunction animate(){\r\n  requestAnimationFrame(animate);\r\n  const t = clock.getElapsedTime();\r\n\r\n  zoom += (targetZoom - zoom) * 0.05;\r\n  camera.position.z = zoom;\r\n\r\n  if(autoRotate) rotY += 0.003;\r\n  globe.rotation.y = rotY;\r\n  globe.rotation.x = rotX;\r\n\r\n  orbDots.forEach(od => {\r\n    od.angle += od.speed * 0.01;\r\n    od.dot.position.set(od.r*Math.cos(od.angle), 0, od.r*Math.sin(od.angle));\r\n  });\r\n\r\n  pin.scale.setScalar(0.9 + 0.2*Math.sin(t*4));\r\n  pulseMat.opacity = 0.5 + 0.4*Math.sin(t*3);\r\n  pulseRing.scale.setScalar(0.8 + 0.6*((Math.sin(t*2)+1)\/2));\r\n  rings.forEach((r,i) => { r.material.opacity = 0.35 + 0.18*Math.sin(t*1.2 + i*1.1); });\r\n\r\n  renderer.render(scene, camera);\r\n  drawRays(t);\r\n}\r\nanimate();\r\n\r\nsetTimeout(() => { document.getElementById('hint').style.opacity = '0'; }, 5000);\r\n\r\n})();\r\n<\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Contact Us Cosmic Mobile Orbit \u2653 \u2652 \u2650 \u264e \u264b \u264a MOBILE +44 7438 562563 Cosmic Email Orbit \u2653 \u2652 \u2650 \u264e \u264b \u264a EMAIL psychicreadinginlondon@gmail.com Terra-Prime Terra-Prime interactive 3D globe with light rays pointing to London \u2014 LOCATE PANDIT JI \u2014 OUR CELESTIAL HUB SCROLL TO ZOOM \u00b7 DRAG TO ROTATE \u00b7 CLICK PIN [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-594","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/594","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=594"}],"version-history":[{"count":76,"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/594\/revisions"}],"predecessor-version":[{"id":814,"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/594\/revisions\/814"}],"wp:attachment":[{"href":"https:\/\/panditjaydev.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}