"use client"; // ============================================================================= // Novarix Networks — Homepage // ============================================================================= // // This file controls the LAYOUT and STYLING of the homepage. // All editable TEXT lives in `/content.ts` at the project root. // // How this file is organised, top to bottom: // 1. Imports + setup // 2. Site shell (background gradient + ambient orbs + grid) // 3. Header (logo + navigation) // 4. Hero (big headline + buttons) // 5. Services (three cards under "What we do") // 6. How we engage (three cards under "Working with us") // 7. Contact (the dark contact card) // 8. Footer (company details + copyright) // // Each section is marked with a clear comment header you can search for. // The "use client" line at the top tells Next.js this page runs in the // browser (needed for the mouse-tracking glow). // ============================================================================= import Image from "next/image"; import Link from "next/link"; import React, { useMemo, useState } from "react"; import { site } from "@/content"; import { openCookieBanner } from "@/components/CookieBanner"; // Type for the mouse-pointer position used to move the background glow. type PointerState = { x: number; y: number }; export default function HomePage() { // --------------------------------------------------------------------------- // STATE // --------------------------------------------------------------------------- // pointer — the mouse position (in % of page width/height). Used by the // soft glow that follows the cursor in the background. // --------------------------------------------------------------------------- const [pointer, setPointer] = useState({ x: 50, y: 22 }); const [copiedEmail, setCopiedEmail] = useState(false); // --------------------------------------------------------------------------- // BACKGROUND POSITION // Translates the current mouse pointer into two CSS variables (--mx, --my) // that the .site-shell background gradient reads. Memoised so React doesn't // rebuild the style object on every render. // --------------------------------------------------------------------------- const backgroundStyle = useMemo( () => ({ ["--mx"]: `${pointer.x}%`, ["--my"]: `${pointer.y}%`, }) as React.CSSProperties, [pointer.x, pointer.y] ); async function copyContactEmail() { try { await navigator.clipboard.writeText(site.contact.email); setCopiedEmail(true); window.setTimeout(() => setCopiedEmail(false), 1800); } catch { setCopiedEmail(false); } } return (
{ const rect = event.currentTarget.getBoundingClientRect(); const x = ((event.clientX - rect.left) / rect.width) * 100; const y = ((event.clientY - rect.top) / rect.height) * 100; setPointer({ x, y }); }} > {/* ------------------------------------------------------------------- AMBIENT LAYER Two soft floating "orbs" and a faint grid behind everything. Purely decorative. All styles live in globals.css under .ambient-orb / .ambient-grid. Sits at z-index -10 so it's under the page content. ------------------------------------------------------------------- */}
); }