diff --git a/src/index.css b/src/index.css
index d72a363..3b5461d 100644
--- a/src/index.css
+++ b/src/index.css
@@ -5,15 +5,15 @@
:root {
/* @colorThemes/lightTheme/grayNavyBlue */
- --background: #ffffff;
- --card: #f8f9fa;
- --foreground: #111827;
- --primary-cta: #6366f1;
+ --background: #050505;
+ --card: #111111;
+ --foreground: #ffffff;
+ --primary-cta: #7c3aed;
--primary-cta-text: #ffffff;
- --secondary-cta: #e0e7ff;
- --secondary-cta-text: #4f46e5;
- --accent: #6b7280;
- --background-accent: #f3f4f6;
+ --secondary-cta: #1a1a1a;
+ --secondary-cta-text: #7c3aed;
+ --accent: #a3a3a3;
+ --background-accent: #0f0f0f;
/* @layout/border-radius/rounded */
--radius: 1.5rem;
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx
index 9bfe142..eea2292 100644
--- a/src/pages/HomePage.tsx
+++ b/src/pages/HomePage.tsx
@@ -5,7 +5,6 @@
// become component refs.
import React from 'react';
-import HeroSection from './HomePage/sections/Hero';
import AboutSection from './HomePage/sections/About';
import ServicesSection from './HomePage/sections/Services';
import TestimonialsSection from './HomePage/sections/Testimonials';
@@ -14,10 +13,11 @@ import FaqSection from './HomePage/sections/Faq';
import ContactSection from './HomePage/sections/Contact';
-import MetricsSection from './HomePage/sections/Metrics';export default function HomePage(): React.JSX.Element {
+import MetricsSection from './HomePage/sections/Metrics';
+import HeroWebglSection from './HomePage/sections/HeroWebgl';export default function HomePage(): React.JSX.Element {
return (
<>
-
+
diff --git a/src/pages/HomePage/sections/Hero.tsx b/src/pages/HomePage/sections/Hero.tsx
deleted file mode 100644
index 2891a83..0000000
--- a/src/pages/HomePage/sections/Hero.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-/* eslint-disable */
-// @ts-nocheck — generated by catalog-eject; runtime-correct but TS strict-mode false-positives on inlined catalog body
-import Button from "@/components/ui/Button";
-import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot";
-import TextAnimation from "@/components/ui/TextAnimation";
-import ImageOrVideo from "@/components/ui/ImageOrVideo";
-import AvatarGroup from "@/components/ui/AvatarGroup";
-
-const avatarsSrc = [
- "http://img.b2bpic.net/free-photo/smiling-man-wearing-white-shirt_23-2152009541.jpg",
- "http://img.b2bpic.net/free-photo/young-businesswoman-portrait-office_1262-1506.jpg",
- "http://img.b2bpic.net/free-photo/emotional-young-bearded-man-asking-something-isolated-dark-wall_140725-97014.jpg",
- "http://img.b2bpic.net/free-photo/crazy-hero-happy-expression_1194-4140.jpg"
-];
-const primaryButton = {
- text: "Zistiť viac",
- href: "#services"
-};
-const secondaryButton = {
- text: "Kontaktovať nás",
- href: "#contact"
-};
-const names = [
- "Google",
- "Microsoft",
- "Amazon",
- "Apple",
- "Tesla",
- "Adobe"
-];
-
-type HeroCenteredLogosProps = {
- avatarsSrc: string[];
- avatarText: string;
- title: string;
- description: string;
- primaryButton: { text: string; href: string };
- secondaryButton: { text: string; href: string };
- names: string[];
- hideMedia?: boolean;
- textAnimation: "slide-up" | "fade-blur" | "fade";
-} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
-
-const HeroInline = () => {
- return (
-
-
- {!undefined && (
-
- )}
-
-
-
-
-
- {[...names, ...names, ...names, ...names].map((name, index) => (
-
- {name}
-
- ))}
-
-
-
- );
-};
-
-export default function HeroSection() {
- return (
-
-
-
- );
-}
diff --git a/src/pages/HomePage/sections/HeroWebgl.tsx b/src/pages/HomePage/sections/HeroWebgl.tsx
new file mode 100644
index 0000000..5bf4d12
--- /dev/null
+++ b/src/pages/HomePage/sections/HeroWebgl.tsx
@@ -0,0 +1,212 @@
+import { useEffect, useRef, useState } from "react";
+import { motion } from "motion/react";
+import Button from "@/components/ui/Button";
+
+export default function HeroWebglSection() {
+ const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
+ const canvasRef = useRef(null);
+ const mouseRef = useRef({ x: typeof window !== 'undefined' ? window.innerWidth / 2 : 0, y: typeof window !== 'undefined' ? window.innerHeight / 2 : 0 });
+
+ useEffect(() => {
+ const updateMousePosition = (e: MouseEvent) => {
+ setMousePosition({ x: e.clientX, y: e.clientY });
+ mouseRef.current = { x: e.clientX, y: e.clientY };
+ };
+ window.addEventListener("mousemove", updateMousePosition);
+ return () => window.removeEventListener("mousemove", updateMousePosition);
+ }, []);
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+ const gl = canvas.getContext("webgl");
+ if (!gl) return;
+
+ const vertexShaderSource = `
+ attribute vec2 position;
+ void main() {
+ gl_Position = vec4(position, 0.0, 1.0);
+ }
+ `;
+
+ const fragmentShaderSource = `
+ precision highp float;
+ uniform vec2 u_resolution;
+ uniform float u_time;
+ uniform vec2 u_mouse;
+
+ void main() {
+ vec2 st = gl_FragCoord.xy / u_resolution.xy;
+ vec2 mouse = u_mouse / u_resolution.xy;
+ mouse.y = 1.0 - mouse.y;
+
+ float dist = distance(st, mouse);
+ float blob = smoothstep(0.8, 0.0, dist);
+
+ vec3 bg = vec3(0.02, 0.02, 0.02);
+ vec3 accent = vec3(0.48, 0.22, 0.92); // #7c3aed
+
+ float noise = fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.03;
+
+ float wave = sin(st.x * 5.0 + u_time * 0.5) * cos(st.y * 5.0 + u_time * 0.5) * 0.15;
+
+ vec3 color = mix(bg, accent, blob * 0.4 + wave);
+ color += noise;
+
+ gl_FragColor = vec4(color, 1.0);
+ }
+ `;
+
+ const compileShader = (type: number, source: string) => {
+ const shader = gl.createShader(type);
+ if (!shader) return null;
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
+ console.error(gl.getShaderInfoLog(shader));
+ gl.deleteShader(shader);
+ return null;
+ }
+ return shader;
+ };
+
+ const vertexShader = compileShader(gl.VERTEX_SHADER, vertexShaderSource);
+ const fragmentShader = compileShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
+
+ if (!vertexShader || !fragmentShader) return;
+
+ const program = gl.createProgram();
+ if (!program) return;
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+ console.error(gl.getProgramInfoLog(program));
+ return;
+ }
+
+ gl.useProgram(program);
+
+ const positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ const positions = new Float32Array([
+ -1.0, -1.0,
+ 1.0, -1.0,
+ -1.0, 1.0,
+ -1.0, 1.0,
+ 1.0, -1.0,
+ 1.0, 1.0,
+ ]);
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+
+ const positionLocation = gl.getAttribLocation(program, "position");
+ gl.enableVertexAttribArray(positionLocation);
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
+
+ const resolutionLocation = gl.getUniformLocation(program, "u_resolution");
+ const timeLocation = gl.getUniformLocation(program, "u_time");
+ const mouseLocation = gl.getUniformLocation(program, "u_mouse");
+
+ let animationFrameId: number;
+ const startTime = performance.now();
+
+ const render = () => {
+ const width = canvas.clientWidth;
+ const height = canvas.clientHeight;
+ if (canvas.width !== width || canvas.height !== height) {
+ canvas.width = width;
+ canvas.height = height;
+ gl.viewport(0, 0, width, height);
+ }
+
+ gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
+ gl.uniform1f(timeLocation, (performance.now() - startTime) / 1000.0);
+ gl.uniform2f(mouseLocation, mouseRef.current.x, mouseRef.current.y);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ animationFrameId = requestAnimationFrame(render);
+ };
+
+ render();
+
+ return () => {
+ cancelAnimationFrame(animationFrameId);
+ gl.deleteProgram(program);
+ };
+ }, []);
+
+ const headline = "WE BUILD LOUD IDEAS";
+ const letters = headline.split("");
+
+ return (
+
+ {/* WebGL Background */}
+
+
+ {/* Grain Overlay */}
+
+
+ {/* Custom Cursor */}
+
+
+
+
+
+ {letters.map((letter, i) => (
+
+ {letter}
+
+ ))}
+
+
+
+ A flagship digital experience. We craft award-winning brands and high-performance platforms.
+
+
+
+
+
+
+
+ {/* Scroll Down Indicator */}
+
+ Scroll
+
+
+
+ );
+}
\ No newline at end of file