Initial Commit
Commit pertama, memindahkan repository dari github ke gitea.
This commit is contained in:
commit
13a47fbebf
41 files changed
+12327
No files matched your search
@@ -0,0 +1,190 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Shield, Sparkles, Cpu, Eye, Code, Compass } from "lucide-react";
|
||||
|
||||
export default function About() {
|
||||
const pillars = [
|
||||
{
|
||||
icon: Shield,
|
||||
title: "Radical Autonomy",
|
||||
description:
|
||||
"We are 100% self-directed. Every hour in our studio is dedicated to original research, bespoke engineering, and crafting immersive experiences.",
|
||||
badge: "Sovereign IP",
|
||||
accent: "from-cyan-500/20 to-blue-500/10",
|
||||
border: "border-cyan-500/30",
|
||||
},
|
||||
{
|
||||
icon: Cpu,
|
||||
title: "Relentless Engineering",
|
||||
description:
|
||||
"From low-latency native algorithms to custom GLSL shaders and responsive spatial architectures, our software is engineered for speed, stability, and longevity.",
|
||||
badge: "Deep Tech",
|
||||
accent: "from-purple-500/20 to-indigo-500/10",
|
||||
border: "border-purple-500/30",
|
||||
},
|
||||
{
|
||||
icon: Sparkles,
|
||||
title: "Artistic Depth",
|
||||
description:
|
||||
"Games and software shouldn't just be functional—they should carry soul. We handcraft atmospheric aesthetics, celestial soundscapes, and intuitive interaction rituals.",
|
||||
badge: "Bespoke Art",
|
||||
accent: "from-pink-500/20 to-rose-500/10",
|
||||
border: "border-pink-500/30",
|
||||
},
|
||||
{
|
||||
icon: Eye,
|
||||
title: "Long-Horizon Vision",
|
||||
description:
|
||||
"We build digital artifacts that endure. Rather than following transient hype cycles or rushed deliverables, we invest in foundational systems and timeless experiences.",
|
||||
badge: "Decade Mindset",
|
||||
accent: "from-indigo-500/20 to-cyan-500/10",
|
||||
border: "border-indigo-500/30",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="about" className="relative py-28 overflow-hidden">
|
||||
{/* Background radial accent */}
|
||||
<div className="absolute top-1/2 left-0 w-96 h-96 bg-indigo-600/10 rounded-full blur-[140px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col items-center text-center max-w-3xl mx-auto mb-20 space-y-4">
|
||||
<div className="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full glass-panel border border-indigo-500/30 text-xs font-mono text-indigo-300">
|
||||
<Compass className="w-3.5 h-3.5 text-indigo-400" />
|
||||
<span>ORIGIN & MISSION</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-black tracking-tight text-white">
|
||||
Forged in the Pursuit of <br />
|
||||
<span className="text-gradient-nebula">Creative Sovereignty.</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-base sm:text-lg text-slate-400 leading-relaxed pt-2">
|
||||
Aghatis Studio was established with a singular conviction: the most resonant
|
||||
software and interactive worlds are crafted with unwavering focus, deep curiosity,
|
||||
and total creative sovereignty.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Narrative Feature Row: Manifesto statement */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-stretch mb-16">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.7 }}
|
||||
className="lg:col-span-7 glass-panel-glow p-8 sm:p-10 rounded-3xl relative overflow-hidden flex flex-col justify-between"
|
||||
>
|
||||
<div className="absolute top-0 right-0 p-8 opacity-10 pointer-events-none">
|
||||
<Code className="w-48 h-48 text-cyan-400" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-6 relative z-10">
|
||||
<div className="text-xs font-mono tracking-widest text-cyan-400 uppercase">
|
||||
// THE STUDIO NARRATIVE
|
||||
</div>
|
||||
<h3 className="text-2xl sm:text-3xl font-bold text-white leading-snug">
|
||||
The Craft of an Independent Product Lab.
|
||||
</h3>
|
||||
<p className="text-slate-300 leading-relaxed text-sm sm:text-base">
|
||||
At <span className="text-cyan-300 font-semibold">Aghatis Studio</span>, our mission is purposeful:
|
||||
we design, build, and publish our own digital products. By channeling our entire team's energy
|
||||
into in-house intellectual property, we maintain complete creative control over every mechanic, interface, and artistic decision.
|
||||
</p>
|
||||
<p className="text-slate-400 leading-relaxed text-sm sm:text-base">
|
||||
Every line of code, geometric asset, and algorithmic pipeline we author belongs to a cohesive creative ecosystem.
|
||||
This focused environment grants us the freedom to polish mechanics until they shine, engineer tools with
|
||||
uncompromising standards, and publish digital experiences that leave a lasting impression.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-white/10 flex items-center justify-between text-xs font-mono text-slate-400">
|
||||
<span>FOUNDED IN INDEPENDENCE</span>
|
||||
<span className="text-cyan-400">PURE IN-HOUSE IP</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Quote / Philosophy card */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.7, delay: 0.1 }}
|
||||
className="lg:col-span-5 glass-card p-8 sm:p-10 rounded-3xl flex flex-col justify-between border-indigo-500/20 bg-gradient-to-b from-indigo-950/30 to-purple-950/10"
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="w-10 h-10 rounded-xl bg-cyan-400/10 border border-cyan-400/30 flex items-center justify-center text-cyan-400">
|
||||
<Sparkles className="w-5 h-5" />
|
||||
</div>
|
||||
<blockquote className="text-lg sm:text-xl font-medium text-slate-200 italic leading-relaxed">
|
||||
“We measure our success by the elegance of our architecture, the atmosphere of our worlds, and the enduring quality of the software and games we release into the universe.”
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-white/10 flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-gradient-to-tr from-cyan-400 to-indigo-500 flex items-center justify-center text-slate-950 font-bold text-xs">
|
||||
AS
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-xs font-mono font-bold text-white tracking-wider">
|
||||
AGHATIS CORE LAB
|
||||
</div>
|
||||
<div className="text-[11px] font-mono text-slate-400">
|
||||
CREATIVE ARCHITECTURE COUNCIL
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Pillars Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{pillars.map((pillar, i) => {
|
||||
const Icon = pillar.icon;
|
||||
return (
|
||||
<motion.div
|
||||
key={pillar.title}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: i * 0.1 }}
|
||||
className="glass-card p-6 sm:p-7 rounded-2xl flex flex-col justify-between group hover:border-cyan-400/40 relative overflow-hidden"
|
||||
>
|
||||
<div className={`absolute top-0 right-0 w-28 h-28 bg-gradient-to-bl ${pillar.accent} rounded-bl-full pointer-events-none opacity-40 group-hover:opacity-100 transition-opacity`} />
|
||||
|
||||
<div className="space-y-4 relative z-10">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="w-10 h-10 rounded-xl bg-white/5 border border-white/10 flex items-center justify-center text-cyan-400 group-hover:scale-110 transition-transform">
|
||||
<Icon className="w-5 h-5" />
|
||||
</div>
|
||||
<span className="text-[10px] font-mono uppercase px-2 py-0.5 rounded-full bg-white/5 border border-white/10 text-slate-400">
|
||||
{pillar.badge}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h4 className="text-lg font-bold text-white group-hover:text-cyan-300 transition-colors">
|
||||
{pillar.title}
|
||||
</h4>
|
||||
|
||||
<p className="text-xs sm:text-sm text-slate-400 leading-relaxed">
|
||||
{pillar.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 pt-4 border-t border-white/5 flex items-center justify-between text-[11px] font-mono text-slate-400">
|
||||
<span>PILLAR 0{i + 1}</span>
|
||||
<span className="text-cyan-400 font-mono">NOMINAL</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
"use client";
|
||||
|
||||
import React, { useMemo, useRef } from "react";
|
||||
import { Canvas, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
// 1. Refined, clean Starfield (neat, elegant points of light)
|
||||
function StarField({ count = 650 }: { count?: number }) {
|
||||
const pointsRef = useRef<THREE.Points>(null!);
|
||||
|
||||
const [positions, colors] = useMemo(() => {
|
||||
const pos = new Float32Array(count * 3);
|
||||
const col = new Float32Array(count * 3);
|
||||
|
||||
const colorWhite = new THREE.Color("#ffffff");
|
||||
const colorIcy = new THREE.Color("#93c5fd");
|
||||
const colorSilver = new THREE.Color("#e2e8f0");
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const radius = 30 + Math.random() * 80;
|
||||
const theta = Math.random() * 2 * Math.PI;
|
||||
const phi = Math.acos(2 * Math.random() - 1);
|
||||
|
||||
pos[i * 3] = radius * Math.sin(phi) * Math.cos(theta);
|
||||
pos[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);
|
||||
pos[i * 3 + 2] = radius * Math.cos(phi);
|
||||
|
||||
const r = Math.random();
|
||||
const chosen = r > 0.7 ? colorIcy : r > 0.3 ? colorSilver : colorWhite;
|
||||
|
||||
col[i * 3] = chosen.r;
|
||||
col[i * 3 + 1] = chosen.g;
|
||||
col[i * 3 + 2] = chosen.b;
|
||||
}
|
||||
|
||||
return [pos, col];
|
||||
}, [count]);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (!pointsRef.current) return;
|
||||
pointsRef.current.rotation.y += delta * 0.005;
|
||||
pointsRef.current.rotation.x += delta * 0.002;
|
||||
|
||||
const targetX = (state.pointer.x * Math.PI) / 60;
|
||||
const targetY = (state.pointer.y * Math.PI) / 60;
|
||||
pointsRef.current.rotation.y += (targetX - pointsRef.current.rotation.y) * 0.02;
|
||||
pointsRef.current.rotation.x += (-targetY - pointsRef.current.rotation.x) * 0.02;
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={pointsRef}>
|
||||
<bufferGeometry>
|
||||
<bufferAttribute attach="attributes-position" args={[positions, 3]} />
|
||||
<bufferAttribute attach="attributes-color" args={[colors, 3]} />
|
||||
</bufferGeometry>
|
||||
<pointsMaterial
|
||||
size={0.7}
|
||||
vertexColors
|
||||
transparent
|
||||
opacity={0.8}
|
||||
sizeAttenuation
|
||||
depthWrite={false}
|
||||
blending={THREE.AdditiveBlending}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Bright, Glowing Background Planet (Astraea - Upper Right)
|
||||
function BackgroundPlanetAstraea() {
|
||||
const groupRef = useRef<THREE.Group>(null!);
|
||||
const planetRef = useRef<THREE.Mesh>(null!);
|
||||
const atmosphereRef = useRef<THREE.Mesh>(null!);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (planetRef.current) {
|
||||
planetRef.current.rotation.y += delta * 0.05;
|
||||
}
|
||||
if (atmosphereRef.current) {
|
||||
atmosphereRef.current.rotation.y -= delta * 0.03;
|
||||
}
|
||||
if (groupRef.current) {
|
||||
// Subtle floating parallax
|
||||
const targetX = 16 + (state.pointer.x * 2.5);
|
||||
const targetY = 9 + (state.pointer.y * 2.0);
|
||||
groupRef.current.position.x += (targetX - groupRef.current.position.x) * 0.02;
|
||||
groupRef.current.position.y += (targetY - groupRef.current.position.y) * 0.02;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group ref={groupRef} position={[16, 9, -16]}>
|
||||
{/* Bright Planet Core Sphere */}
|
||||
<mesh ref={planetRef}>
|
||||
<sphereGeometry args={[4.2, 48, 48]} />
|
||||
<meshStandardMaterial
|
||||
color="#38bdf8"
|
||||
emissive="#0284c7"
|
||||
emissiveIntensity={0.85}
|
||||
roughness={0.25}
|
||||
metalness={0.7}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Radiant Atmospheric Halo Rim */}
|
||||
<mesh ref={atmosphereRef}>
|
||||
<sphereGeometry args={[4.6, 32, 32]} />
|
||||
<meshBasicMaterial
|
||||
color="#7dd3fc"
|
||||
transparent
|
||||
opacity={0.35}
|
||||
side={THREE.BackSide}
|
||||
blending={THREE.AdditiveBlending}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Outer Luminous Glow Aura Ring */}
|
||||
<mesh rotation={[Math.PI / 3, 0.4, 0]}>
|
||||
<ringGeometry args={[4.8, 6.8, 48]} />
|
||||
<meshBasicMaterial
|
||||
color="#38bdf8"
|
||||
transparent
|
||||
opacity={0.22}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Bright, Glowing Background Planet (Kore - Lower Left with Ring)
|
||||
function BackgroundPlanetKore() {
|
||||
const groupRef = useRef<THREE.Group>(null!);
|
||||
const planetRef = useRef<THREE.Mesh>(null!);
|
||||
const ringRef = useRef<THREE.Mesh>(null!);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (planetRef.current) {
|
||||
planetRef.current.rotation.y += delta * 0.04;
|
||||
}
|
||||
if (ringRef.current) {
|
||||
ringRef.current.rotation.z += delta * 0.02;
|
||||
}
|
||||
if (groupRef.current) {
|
||||
// Gentle floating parallax
|
||||
const targetX = -18 - (state.pointer.x * 3.0);
|
||||
const targetY = -12 - (state.pointer.y * 2.5);
|
||||
groupRef.current.position.x += (targetX - groupRef.current.position.x) * 0.02;
|
||||
groupRef.current.position.y += (targetY - groupRef.current.position.y) * 0.02;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group ref={groupRef} position={[-18, -12, -22]}>
|
||||
{/* Bright Violet Core Planet */}
|
||||
<mesh ref={planetRef}>
|
||||
<sphereGeometry args={[5.5, 48, 48]} />
|
||||
<meshStandardMaterial
|
||||
color="#a855f7"
|
||||
emissive="#6366f1"
|
||||
emissiveIntensity={0.75}
|
||||
roughness={0.3}
|
||||
metalness={0.8}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Atmospheric Halo */}
|
||||
<mesh>
|
||||
<sphereGeometry args={[5.9, 32, 32]} />
|
||||
<meshBasicMaterial
|
||||
color="#c084fc"
|
||||
transparent
|
||||
opacity={0.3}
|
||||
side={THREE.BackSide}
|
||||
blending={THREE.AdditiveBlending}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Luminous Majestic Planetary Ring */}
|
||||
<mesh ref={ringRef} rotation={[Math.PI / 2.3, 0.35, 0]}>
|
||||
<ringGeometry args={[6.8, 10.2, 64]} />
|
||||
<meshStandardMaterial
|
||||
color="#c084fc"
|
||||
emissive="#a855f7"
|
||||
emissiveIntensity={0.6}
|
||||
transparent
|
||||
opacity={0.45}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Distant Luminous Stellar Moon Orb
|
||||
function DistantLuminousOrb() {
|
||||
const orbRef = useRef<THREE.Mesh>(null!);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (!orbRef.current) return;
|
||||
const t = state.clock.getElapsedTime();
|
||||
orbRef.current.position.y = 14 + Math.sin(t * 0.8) * 0.6;
|
||||
orbRef.current.position.x = -8 + Math.cos(t * 0.5) * 0.8;
|
||||
});
|
||||
|
||||
return (
|
||||
<mesh ref={orbRef} position={[-8, 14, -18]}>
|
||||
<sphereGeometry args={[1.2, 24, 24]} />
|
||||
<meshStandardMaterial
|
||||
color="#34d399"
|
||||
emissive="#10b981"
|
||||
emissiveIntensity={1.2}
|
||||
roughness={0.1}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
export default function CosmicGalaxy() {
|
||||
return (
|
||||
<div className="fixed inset-0 pointer-events-none z-0 overflow-hidden">
|
||||
<Canvas
|
||||
camera={{ position: [0, 0, 32], fov: 50 }}
|
||||
dpr={[1, 1.5]}
|
||||
gl={{ antialias: true, alpha: true, powerPreference: "high-performance" }}
|
||||
className="w-full h-full"
|
||||
>
|
||||
<color attach="background" args={["#0a0a12"]} />
|
||||
|
||||
{/* Cinematic Starlight Illumination */}
|
||||
<ambientLight intensity={0.5} />
|
||||
<directionalLight position={[20, 20, 10]} intensity={1.8} color="#e0f2fe" />
|
||||
<directionalLight position={[-20, -15, -5]} intensity={1.0} color="#c084fc" />
|
||||
|
||||
{/* Clean, Neat Starfield */}
|
||||
<StarField count={650} />
|
||||
|
||||
{/* Bright Circular Planet-Like Objects in the Background */}
|
||||
<BackgroundPlanetAstraea />
|
||||
<BackgroundPlanetKore />
|
||||
<DistantLuminousOrb />
|
||||
</Canvas>
|
||||
|
||||
{/* Atmospheric depth vignettes (subtle gradient, no harsh boxes) */}
|
||||
<div className="absolute inset-0 bg-radial from-transparent via-[#0a0a12]/30 to-[#0a0a12] pointer-events-none" />
|
||||
|
||||
{/* Soft circular glowing light fountains behind the planets */}
|
||||
<div className="absolute -top-10 right-10 w-96 h-96 bg-cyan-500/10 rounded-full blur-[100px] pointer-events-none" />
|
||||
<div className="absolute -bottom-10 left-10 w-[450px] h-[450px] bg-purple-600/10 rounded-full blur-[120px] pointer-events-none" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const CosmicGalaxy = dynamic(() => import("./CosmicGalaxy"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export default function CosmicGalaxyDynamic() {
|
||||
return <CosmicGalaxy />;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
"use client";
|
||||
|
||||
import React, { useRef } from "react";
|
||||
import { Canvas, useFrame } from "@react-three/fiber";
|
||||
import { Float } from "@react-three/drei";
|
||||
import * as THREE from "three";
|
||||
|
||||
function CosmicArtifact() {
|
||||
const groupRef = useRef<THREE.Group>(null!);
|
||||
const ring1Ref = useRef<THREE.Mesh>(null!);
|
||||
const ring2Ref = useRef<THREE.Mesh>(null!);
|
||||
const ring3Ref = useRef<THREE.Mesh>(null!);
|
||||
const coreRef = useRef<THREE.Mesh>(null!);
|
||||
const outerGeomRef = useRef<THREE.Mesh>(null!);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (!groupRef.current) return;
|
||||
|
||||
// Dual-axis rotation for the rings (gyroscope / celestial sphere effect)
|
||||
if (ring1Ref.current) {
|
||||
ring1Ref.current.rotation.x += delta * 0.4;
|
||||
ring1Ref.current.rotation.y += delta * 0.2;
|
||||
}
|
||||
if (ring2Ref.current) {
|
||||
ring2Ref.current.rotation.y += delta * 0.35;
|
||||
ring2Ref.current.rotation.z += delta * 0.25;
|
||||
}
|
||||
if (ring3Ref.current) {
|
||||
ring3Ref.current.rotation.z += delta * 0.3;
|
||||
ring3Ref.current.rotation.x += delta * 0.15;
|
||||
}
|
||||
|
||||
// Core pulsing & rotation
|
||||
if (coreRef.current) {
|
||||
coreRef.current.rotation.y += delta * 0.5;
|
||||
const t = state.clock.getElapsedTime();
|
||||
const scale = 1 + Math.sin(t * 2) * 0.05;
|
||||
coreRef.current.scale.set(scale, scale, scale);
|
||||
}
|
||||
|
||||
// Outer wireframe geodesic
|
||||
if (outerGeomRef.current) {
|
||||
outerGeomRef.current.rotation.y -= delta * 0.15;
|
||||
outerGeomRef.current.rotation.x += delta * 0.08;
|
||||
}
|
||||
|
||||
// Interactive pointer sway
|
||||
const targetX = (state.pointer.x * Math.PI) / 8;
|
||||
const targetY = (state.pointer.y * Math.PI) / 8;
|
||||
groupRef.current.rotation.y += (targetX - groupRef.current.rotation.y) * 0.05;
|
||||
groupRef.current.rotation.x += (-targetY - groupRef.current.rotation.x) * 0.05;
|
||||
});
|
||||
|
||||
return (
|
||||
<Float speed={2} rotationIntensity={0.6} floatIntensity={1}>
|
||||
<group ref={groupRef}>
|
||||
{/* Core glowing sphere */}
|
||||
<mesh ref={coreRef}>
|
||||
<sphereGeometry args={[1.2, 32, 32]} />
|
||||
<meshStandardMaterial
|
||||
color="#38bdf8"
|
||||
emissive="#6366f1"
|
||||
emissiveIntensity={0.8}
|
||||
roughness={0.15}
|
||||
metalness={0.9}
|
||||
wireframe={false}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Inner light source */}
|
||||
<pointLight color="#38bdf8" intensity={4} distance={8} />
|
||||
<pointLight color="#a855f7" intensity={3} distance={10} position={[0, -2, 0]} />
|
||||
|
||||
{/* Outer wireframe icosahedron/geodesic */}
|
||||
<mesh ref={outerGeomRef}>
|
||||
<icosahedronGeometry args={[2.0, 1]} />
|
||||
<meshBasicMaterial
|
||||
color="#818cf8"
|
||||
wireframe
|
||||
transparent
|
||||
opacity={0.3}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Celestial Orbital Ring 1 */}
|
||||
<mesh ref={ring1Ref}>
|
||||
<torusGeometry args={[2.5, 0.025, 16, 100]} />
|
||||
<meshStandardMaterial
|
||||
color="#38bdf8"
|
||||
emissive="#38bdf8"
|
||||
emissiveIntensity={1.5}
|
||||
roughness={0.1}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Celestial Orbital Ring 2 (Cross tilt) */}
|
||||
<mesh ref={ring2Ref} rotation={[Math.PI / 3, 0, 0]}>
|
||||
<torusGeometry args={[3.0, 0.02, 16, 100]} />
|
||||
<meshStandardMaterial
|
||||
color="#c084fc"
|
||||
emissive="#a855f7"
|
||||
emissiveIntensity={1.3}
|
||||
roughness={0.1}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Celestial Orbital Ring 3 (Outer edge) */}
|
||||
<mesh ref={ring3Ref} rotation={[-Math.PI / 4, Math.PI / 6, 0]}>
|
||||
<torusGeometry args={[3.4, 0.015, 16, 120]} />
|
||||
<meshStandardMaterial
|
||||
color="#67e8f9"
|
||||
emissive="#06b6d4"
|
||||
emissiveIntensity={1.0}
|
||||
roughness={0.1}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Orbital Starlight Satellite Node 1 */}
|
||||
<mesh position={[2.6, 0.4, 0]}>
|
||||
<sphereGeometry args={[0.08, 16, 16]} />
|
||||
<meshBasicMaterial color="#38bdf8" />
|
||||
</mesh>
|
||||
|
||||
{/* Orbital Starlight Satellite Node 2 */}
|
||||
<mesh position={[-2.2, 1.8, 0.5]}>
|
||||
<sphereGeometry args={[0.07, 16, 16]} />
|
||||
<meshBasicMaterial color="#f472b6" />
|
||||
</mesh>
|
||||
|
||||
{/* Orbital Starlight Satellite Node 3 */}
|
||||
<mesh position={[0.8, -2.8, -0.6]}>
|
||||
<sphereGeometry args={[0.09, 16, 16]} />
|
||||
<meshBasicMaterial color="#a78bfa" />
|
||||
</mesh>
|
||||
</group>
|
||||
</Float>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HeroCosmicOrb() {
|
||||
return (
|
||||
<div className="relative w-full h-[380px] sm:h-[450px] lg:h-[550px] flex items-center justify-center">
|
||||
{/* Background radial glow */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<div className="w-64 h-64 sm:w-80 sm:h-80 bg-indigo-500/20 rounded-full blur-[80px]" />
|
||||
<div className="w-48 h-48 sm:w-60 sm:h-60 bg-cyan-400/20 rounded-full blur-[60px]" />
|
||||
</div>
|
||||
|
||||
<Canvas
|
||||
camera={{ position: [0, 0, 7.5], fov: 45 }}
|
||||
dpr={[1, 1.5]}
|
||||
gl={{ antialias: true, alpha: true }}
|
||||
className="w-full h-full cursor-grab active:cursor-grabbing"
|
||||
>
|
||||
<ambientLight intensity={0.4} />
|
||||
<directionalLight position={[10, 10, 5]} intensity={1.5} color="#e0e7ff" />
|
||||
<directionalLight position={[-10, -10, -5]} intensity={0.8} color="#c084fc" />
|
||||
<CosmicArtifact />
|
||||
</Canvas>
|
||||
|
||||
{/* Holographic coordinates overlay badge */}
|
||||
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 sm:left-6 sm:translate-x-0 px-3 py-1 rounded-full glass-panel border border-cyan-500/20 flex items-center gap-2 pointer-events-none text-[11px] text-cyan-300 font-mono tracking-wider shadow-lg">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-cyan-400 animate-pulse" />
|
||||
<span>CORE ARTIFACT // AG-01 ACTIVE</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
"use client";
|
||||
|
||||
import React, { useRef, useMemo, useState } from "react";
|
||||
import { Canvas, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
// 1. Central Star (Helios / Core Sun) with radiant corona
|
||||
function CentralStar() {
|
||||
const sunRef = useRef<THREE.Mesh>(null!);
|
||||
const coronaRef = useRef<THREE.Mesh>(null!);
|
||||
const flareRef = useRef<THREE.Mesh>(null!);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
const t = state.clock.getElapsedTime();
|
||||
if (sunRef.current) {
|
||||
sunRef.current.rotation.y += delta * 0.2;
|
||||
const pulse = 1 + Math.sin(t * 2.5) * 0.03;
|
||||
sunRef.current.scale.set(pulse, pulse, pulse);
|
||||
}
|
||||
if (coronaRef.current) {
|
||||
coronaRef.current.rotation.y -= delta * 0.15;
|
||||
coronaRef.current.rotation.z += delta * 0.08;
|
||||
const pulse2 = 1.2 + Math.cos(t * 1.8) * 0.05;
|
||||
coronaRef.current.scale.set(pulse2, pulse2, pulse2);
|
||||
}
|
||||
if (flareRef.current) {
|
||||
flareRef.current.rotation.z -= delta * 0.2;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group>
|
||||
{/* Intense Core Sun */}
|
||||
<mesh ref={sunRef}>
|
||||
<sphereGeometry args={[0.75, 32, 32]} />
|
||||
<meshStandardMaterial
|
||||
color="#38bdf8"
|
||||
emissive="#60a5fa"
|
||||
emissiveIntensity={2.5}
|
||||
roughness={0.2}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Atmospheric Corona Layer */}
|
||||
<mesh ref={coronaRef}>
|
||||
<sphereGeometry args={[0.95, 24, 24]} />
|
||||
<meshBasicMaterial
|
||||
color="#818cf8"
|
||||
transparent
|
||||
opacity={0.3}
|
||||
wireframe
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Solar Flare Halo Disk */}
|
||||
<mesh ref={flareRef} rotation={[Math.PI / 2, 0, 0]}>
|
||||
<ringGeometry args={[0.9, 1.45, 32]} />
|
||||
<meshBasicMaterial
|
||||
color="#38bdf8"
|
||||
transparent
|
||||
opacity={0.2}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Radiant Solar Lights */}
|
||||
<pointLight color="#67e8f9" intensity={4} distance={20} decay={2} />
|
||||
<pointLight color="#c084fc" intensity={2.5} distance={15} position={[0, 1, 0]} decay={2} />
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Orbital Path Ring (crisp, faint geometric trajectory)
|
||||
function OrbitTrack({ radius, color = "#475569" }: { radius: number; color?: string }) {
|
||||
const lineGeometry = useMemo(() => {
|
||||
const points: THREE.Vector3[] = [];
|
||||
const segments = 120;
|
||||
for (let i = 0; i <= segments; i++) {
|
||||
const theta = (i / segments) * Math.PI * 2;
|
||||
points.push(new THREE.Vector3(Math.cos(theta) * radius, 0, Math.sin(theta) * radius));
|
||||
}
|
||||
return new THREE.BufferGeometry().setFromPoints(points);
|
||||
}, [radius]);
|
||||
|
||||
return (
|
||||
<primitive object={new THREE.Line(
|
||||
lineGeometry,
|
||||
new THREE.LineBasicMaterial({ color, transparent: true, opacity: 0.3 })
|
||||
)} />
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Orbiting Planet with optional Rings & Moons
|
||||
interface PlanetProps {
|
||||
name: string;
|
||||
radius: number;
|
||||
size: number;
|
||||
speed: number;
|
||||
color: string;
|
||||
emissive?: string;
|
||||
hasRings?: boolean;
|
||||
ringRadius?: [number, number];
|
||||
ringColor?: string;
|
||||
hasMoon?: boolean;
|
||||
initialAngle?: number;
|
||||
onHover?: (name: string | null) => void;
|
||||
}
|
||||
|
||||
function Planet({
|
||||
name,
|
||||
radius,
|
||||
size,
|
||||
speed,
|
||||
color,
|
||||
emissive = "#000000",
|
||||
hasRings = false,
|
||||
ringRadius = [1.2, 1.8],
|
||||
ringColor = "#c084fc",
|
||||
hasMoon = false,
|
||||
initialAngle = 0,
|
||||
onHover,
|
||||
}: PlanetProps) {
|
||||
const planetGroupRef = useRef<THREE.Group>(null!);
|
||||
const planetMeshRef = useRef<THREE.Mesh>(null!);
|
||||
const moonGroupRef = useRef<THREE.Group>(null!);
|
||||
const angleRef = useRef(initialAngle);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
angleRef.current += delta * speed * 0.35;
|
||||
const x = Math.cos(angleRef.current) * radius;
|
||||
const z = Math.sin(angleRef.current) * radius;
|
||||
|
||||
if (planetGroupRef.current) {
|
||||
planetGroupRef.current.position.set(x, 0, z);
|
||||
}
|
||||
if (planetMeshRef.current) {
|
||||
planetMeshRef.current.rotation.y += delta * 1.2;
|
||||
}
|
||||
if (moonGroupRef.current) {
|
||||
moonGroupRef.current.rotation.y += delta * 2.5;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group ref={planetGroupRef}>
|
||||
{/* The Planet Sphere */}
|
||||
<mesh
|
||||
ref={planetMeshRef}
|
||||
onPointerOver={(e) => {
|
||||
e.stopPropagation();
|
||||
onHover?.(name);
|
||||
}}
|
||||
onPointerOut={() => onHover?.(null)}
|
||||
>
|
||||
<sphereGeometry args={[size, 24, 24]} />
|
||||
<meshStandardMaterial
|
||||
color={color}
|
||||
emissive={emissive}
|
||||
emissiveIntensity={0.6}
|
||||
roughness={0.3}
|
||||
metalness={0.7}
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Planetary Rings */}
|
||||
{hasRings && (
|
||||
<mesh rotation={[Math.PI / 2.5, 0.2, 0]}>
|
||||
<ringGeometry args={[size * ringRadius[0], size * ringRadius[1], 48]} />
|
||||
<meshStandardMaterial
|
||||
color={ringColor}
|
||||
emissive={ringColor}
|
||||
emissiveIntensity={0.5}
|
||||
transparent
|
||||
opacity={0.65}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
)}
|
||||
|
||||
{/* Orbiting Moon */}
|
||||
{hasMoon && (
|
||||
<group ref={moonGroupRef}>
|
||||
<mesh position={[size * 1.9, 0.15, 0]}>
|
||||
<sphereGeometry args={[size * 0.28, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
color="#e2e8f0"
|
||||
emissive="#94a3b8"
|
||||
emissiveIntensity={0.4}
|
||||
roughness={0.5}
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
)}
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Asteroid Belt (subtle, clean, not overcrowded)
|
||||
function AsteroidBelt({ count = 180, innerR = 3.4, outerR = 4.2 }: { count?: number; innerR?: number; outerR?: number }) {
|
||||
const beltRef = useRef<THREE.Points>(null!);
|
||||
|
||||
const [positions, colors] = useMemo(() => {
|
||||
const pos = new Float32Array(count * 3);
|
||||
const col = new Float32Array(count * 3);
|
||||
const colorA = new THREE.Color("#94a3b8");
|
||||
const colorB = new THREE.Color("#38bdf8");
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const r = innerR + Math.random() * (outerR - innerR);
|
||||
const theta = Math.random() * Math.PI * 2;
|
||||
const y = (Math.random() - 0.5) * 0.3;
|
||||
|
||||
pos[i * 3] = Math.cos(theta) * r;
|
||||
pos[i * 3 + 1] = y;
|
||||
pos[i * 3 + 2] = Math.sin(theta) * r;
|
||||
|
||||
const c = Math.random() > 0.4 ? colorA : colorB;
|
||||
col[i * 3] = c.r;
|
||||
col[i * 3 + 1] = c.g;
|
||||
col[i * 3 + 2] = c.b;
|
||||
}
|
||||
|
||||
return [pos, col];
|
||||
}, [count, innerR, outerR]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (beltRef.current) {
|
||||
beltRef.current.rotation.y += delta * 0.06;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={beltRef}>
|
||||
<bufferGeometry>
|
||||
<bufferAttribute attach="attributes-position" args={[positions, 3]} />
|
||||
<bufferAttribute attach="attributes-color" args={[colors, 3]} />
|
||||
</bufferGeometry>
|
||||
<pointsMaterial
|
||||
size={0.045}
|
||||
vertexColors
|
||||
transparent
|
||||
opacity={0.55}
|
||||
sizeAttenuation
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
}
|
||||
|
||||
// 5. Composite Solar System Scene with smooth interactive tilt
|
||||
function SolarSystemScene({ onHoverPlanet }: { onHoverPlanet: (name: string | null) => void }) {
|
||||
const systemRef = useRef<THREE.Group>(null!);
|
||||
|
||||
useFrame((state) => {
|
||||
if (!systemRef.current) return;
|
||||
// Subtle interactive tilt following pointer
|
||||
const targetRotX = 0.55 + (state.pointer.y * Math.PI) / 24;
|
||||
const targetRotY = -0.25 + (state.pointer.x * Math.PI) / 20;
|
||||
systemRef.current.rotation.x += (targetRotX - systemRef.current.rotation.x) * 0.04;
|
||||
systemRef.current.rotation.y += (targetRotY - systemRef.current.rotation.y) * 0.04;
|
||||
});
|
||||
|
||||
return (
|
||||
<group ref={systemRef} rotation={[0.55, -0.25, 0]}>
|
||||
{/* Central Star */}
|
||||
<CentralStar />
|
||||
|
||||
{/* Planetary Tracks — calibrated so outermost radius is 6.4 */}
|
||||
<OrbitTrack radius={1.7} color="#38bdf8" />
|
||||
<OrbitTrack radius={2.7} color="#818cf8" />
|
||||
<OrbitTrack radius={5.0} color="#c084fc" />
|
||||
<OrbitTrack radius={6.4} color="#34d399" />
|
||||
|
||||
{/* Asteroid Belt between Orbit II and Orbit III */}
|
||||
<AsteroidBelt count={190} innerR={3.5} outerR={4.3} />
|
||||
|
||||
{/* Planet 1: Chronos (Molten amber rocky core) */}
|
||||
<Planet
|
||||
name="CHRONOS // ORBIT I (TIME ENGINE)"
|
||||
radius={1.7}
|
||||
size={0.16}
|
||||
speed={1.5}
|
||||
color="#fb923c"
|
||||
emissive="#ea580c"
|
||||
initialAngle={0.5}
|
||||
onHover={onHoverPlanet}
|
||||
/>
|
||||
|
||||
{/* Planet 2: Aetheria (Teal Gem with Moon) */}
|
||||
<Planet
|
||||
name="AETHERIA // ORBIT II (FLAGSHIP SECTOR)"
|
||||
radius={2.7}
|
||||
size={0.25}
|
||||
speed={1.0}
|
||||
color="#22d3ee"
|
||||
emissive="#0891b2"
|
||||
hasMoon={true}
|
||||
initialAngle={2.2}
|
||||
onHover={onHoverPlanet}
|
||||
/>
|
||||
|
||||
{/* Planet 3: Nebula-IX (Ringed Gas Giant) */}
|
||||
<Planet
|
||||
name="NEBULA-IX // ORBIT III (CREATIVE GAS GIANT)"
|
||||
radius={5.0}
|
||||
size={0.42}
|
||||
speed={0.55}
|
||||
color="#a855f7"
|
||||
emissive="#7e22ce"
|
||||
hasRings={true}
|
||||
ringRadius={[1.3, 1.9]}
|
||||
ringColor="#c084fc"
|
||||
hasMoon={true}
|
||||
initialAngle={4.1}
|
||||
onHover={onHoverPlanet}
|
||||
/>
|
||||
|
||||
{/* Planet 4: Void-Zero (Outer Starlight World) */}
|
||||
<Planet
|
||||
name="VOID-ZERO // ORBIT IV (DEEP EXPERIMENTAL)"
|
||||
radius={6.4}
|
||||
size={0.3}
|
||||
speed={0.35}
|
||||
color="#34d399"
|
||||
emissive="#059669"
|
||||
hasMoon={true}
|
||||
initialAngle={5.6}
|
||||
onHover={onHoverPlanet}
|
||||
/>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HeroSolarSystem() {
|
||||
const [hoveredPlanet, setHoveredPlanet] = useState<string | null>(null);
|
||||
|
||||
return (
|
||||
<div className="relative w-full aspect-square max-w-[540px] max-h-[540px] sm:max-h-[580px] flex items-center justify-center select-none mx-auto overflow-visible">
|
||||
{/* Background soft ambient radial lighting */}
|
||||
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
||||
<div className="w-64 h-64 sm:w-80 sm:h-80 bg-cyan-500/10 rounded-full blur-[80px]" />
|
||||
<div className="w-56 h-56 sm:w-72 sm:h-72 bg-purple-600/10 rounded-full blur-[80px]" />
|
||||
</div>
|
||||
|
||||
{/*
|
||||
Camera position: [0, 11, 16] with fov: 42
|
||||
At distance ~19.4, visible height is 15.6 units and width is >18 units.
|
||||
Outermost orbit radius is 6.4 (diameter 12.8).
|
||||
-> 100% Guaranteed ZERO CROPPING at all angles.
|
||||
*/}
|
||||
<Canvas
|
||||
camera={{ position: [0, 11, 16], fov: 42 }}
|
||||
dpr={[1, 1.5]}
|
||||
gl={{ antialias: true, alpha: true }}
|
||||
className="w-full h-full cursor-grab active:cursor-grabbing overflow-visible"
|
||||
>
|
||||
<ambientLight intensity={0.4} />
|
||||
<directionalLight position={[10, 15, 10]} intensity={1.2} color="#ffffff" />
|
||||
<directionalLight position={[-10, -10, -5]} intensity={0.6} color="#818cf8" />
|
||||
<SolarSystemScene onHoverPlanet={setHoveredPlanet} />
|
||||
</Canvas>
|
||||
|
||||
{/* Interactive HUD Telemetry Card */}
|
||||
<div className="absolute bottom-2 left-1/2 -translate-x-1/2 sm:left-2 sm:translate-x-0 glass-panel px-3.5 py-1.5 rounded-xl border border-cyan-500/30 flex items-center gap-2.5 text-[11px] font-mono tracking-wider shadow-[0_0_20px_rgba(56,189,248,0.2)] pointer-events-none">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="w-2 h-2 rounded-full bg-cyan-400 animate-ping" />
|
||||
<span className="text-cyan-300 font-bold">AGHATIS ORBITAL</span>
|
||||
</div>
|
||||
<span className="text-slate-500">|</span>
|
||||
<span className="text-slate-300">
|
||||
{hoveredPlanet ? (
|
||||
<span className="text-cyan-400 font-bold">{hoveredPlanet}</span>
|
||||
) : (
|
||||
"4 ACTIVE ORBITS • TILT TO EXPLORE"
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Orbit Speed & System Badge */}
|
||||
<div className="absolute top-2 right-2 hidden sm:flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-indigo-950/40 border border-indigo-500/30 text-[10px] font-mono text-indigo-300">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-indigo-400" />
|
||||
<span>SIMULATION: 1.0X</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Terminal, Gamepad2, Sparkles, Orbit, CheckCircle2, Compass } from "lucide-react";
|
||||
|
||||
export default function StudioCreed() {
|
||||
const softwareFocus = [
|
||||
{
|
||||
title: "Local-First & High Performance",
|
||||
desc: "We build native, low-latency tools compiled in Rust and WebGPU that respect cognitive flow and user data sovereignty.",
|
||||
},
|
||||
{
|
||||
title: "Tactile Spatial Interfaces",
|
||||
desc: "Re-imagining workstations and creative pipelines with fluid, cockpit-inspired spatial ergonomics.",
|
||||
},
|
||||
{
|
||||
title: "Zero-Bloat Engineering",
|
||||
desc: "Every binary is optimized for minimal memory footprint, instant boot times, and decades-long utility.",
|
||||
},
|
||||
{
|
||||
title: "Tools for Deep Thinkers & Creators",
|
||||
desc: "Software designed from the ground up for technical artists, developers, and focused thinkers.",
|
||||
},
|
||||
];
|
||||
|
||||
const gamesFocus = [
|
||||
{
|
||||
title: "Atmospheric & Narrative Immersion",
|
||||
desc: "Evocative interstellar worlds driven by rich speculative fiction, tactile acoustics, and memorable art direction.",
|
||||
},
|
||||
{
|
||||
title: "Kinetic & Physics-First Mechanics",
|
||||
desc: "Crafting gameplay rooted in Newtonian motion, orbital dynamics, and tactile interactive feedback.",
|
||||
},
|
||||
{
|
||||
title: "Standalone, Complete Experiences",
|
||||
desc: "Crafting finished artistic works that respect player time—no predatory loops, just pure interactive craft.",
|
||||
},
|
||||
{
|
||||
title: "Original Audiovisual Synthesis",
|
||||
desc: "Bespoke procedural audio engines and dynamic synthesizer soundtracks that react in real-time.",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="creed" className="relative py-28 overflow-hidden">
|
||||
{/* Background radial glow */}
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[700px] h-[500px] bg-indigo-600/10 rounded-full blur-[180px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col items-center text-center max-w-3xl mx-auto mb-20 space-y-4">
|
||||
<div className="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full glass-panel border border-cyan-500/30 text-xs font-mono text-cyan-300">
|
||||
<Compass className="w-3.5 h-3.5 text-cyan-400" />
|
||||
<span>STUDIO CREED & CRAFT PHILOSOPHY</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-black tracking-tight text-white">
|
||||
Where Our Energy Goes: <br />
|
||||
<span className="text-gradient-cyan">The Pursuit of Pure Craft.</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-base sm:text-lg text-slate-400 leading-relaxed pt-2">
|
||||
Aghatis Studio exists to invent, polish, and publish original software products and immersive interactive worlds.
|
||||
Our roadmap is driven entirely by craftsmanship, curiosity, and product excellence.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Side-by-side Dual Focus Arena */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 items-stretch">
|
||||
|
||||
{/* Column 1: Software & Tools Focus */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
className="glass-panel-glow p-8 sm:p-10 rounded-3xl relative overflow-hidden flex flex-col justify-between border-cyan-500/30 bg-gradient-to-b from-cyan-950/20 via-slate-950/60 to-black/80"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between pb-4 border-b border-white/10">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-cyan-400/10 border border-cyan-400/30 flex items-center justify-center text-cyan-400">
|
||||
<Terminal className="w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold font-mono text-white">
|
||||
SOFTWARE & CREATIVE TOOLS
|
||||
</h3>
|
||||
<span className="text-[11px] font-mono text-cyan-300">
|
||||
SYSTEMS, WORKSTATIONS & PIPELINES
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<span className="w-2.5 h-2.5 rounded-full bg-cyan-400 shadow-[0_0_10px_#38bdf8]" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{softwareFocus.map((item, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="p-4 rounded-2xl bg-white/5 border border-white/5 flex items-start gap-3.5 hover:border-cyan-400/20 transition-colors"
|
||||
>
|
||||
<CheckCircle2 className="w-4 h-4 text-cyan-400 shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white font-mono">
|
||||
{item.title}
|
||||
</h4>
|
||||
<p className="text-xs text-slate-300 leading-relaxed mt-1">
|
||||
{item.desc}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-white/10 text-xs font-mono text-cyan-300 flex items-center gap-2">
|
||||
<Sparkles className="w-4 h-4 text-cyan-400" />
|
||||
<span>Engineered to empower creators with speed, clarity, and precision.</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Column 2: Games & Interactive Media Focus */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6, delay: 0.1 }}
|
||||
className="glass-card p-8 sm:p-10 rounded-3xl relative overflow-hidden flex flex-col justify-between border-purple-500/30 bg-gradient-to-b from-purple-950/20 via-slate-950/60 to-black/80"
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between pb-4 border-b border-white/10">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-purple-500/10 border border-purple-500/30 flex items-center justify-center text-purple-400">
|
||||
<Gamepad2 className="w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-bold font-mono text-white">
|
||||
ATMOSPHERIC GAMES
|
||||
</h3>
|
||||
<span className="text-[11px] font-mono text-purple-300">
|
||||
WORLDS, PHYSICS & NARRATIVE
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<span className="w-2.5 h-2.5 rounded-full bg-purple-400 shadow-[0_0_10px_#a855f7]" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{gamesFocus.map((item, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="p-4 rounded-2xl bg-white/5 border border-white/5 flex items-start gap-3.5 hover:border-purple-400/20 transition-colors"
|
||||
>
|
||||
<CheckCircle2 className="w-4 h-4 text-purple-400 shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<h4 className="text-sm font-bold text-white font-mono">
|
||||
{item.title}
|
||||
</h4>
|
||||
<p className="text-xs text-slate-300 leading-relaxed mt-1">
|
||||
{item.desc}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-6 border-t border-white/10 text-xs font-mono text-purple-300 flex items-center gap-2">
|
||||
<Orbit className="w-4 h-4 text-purple-400" />
|
||||
<span>Handcrafted interactive universes built with artistic depth and soul.</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Central Creed Statement */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
className="mt-12 p-8 rounded-2xl glass-panel text-center max-w-4xl mx-auto border border-white/10 relative overflow-hidden"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-cyan-500/5 to-transparent pointer-events-none" />
|
||||
<p className="text-sm sm:text-base font-mono text-slate-200 tracking-wide leading-relaxed">
|
||||
“Our commitment is simple: build products of enduring depth, craft experiences we are fiercely proud of, and explore the outer boundaries of software and interactive art.”
|
||||
</p>
|
||||
<div className="mt-4 text-xs font-mono text-cyan-400 uppercase tracking-widest">
|
||||
— AGHATIS STUDIO CORE TENET
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Layers, Terminal, Gamepad2, FlaskConical, ArrowUpRight, CheckCircle2 } from "lucide-react";
|
||||
|
||||
export default function CoreFocus() {
|
||||
const [activeTrack, setActiveTrack] = useState<number>(0);
|
||||
|
||||
const tracks = [
|
||||
{
|
||||
id: "software",
|
||||
number: "01",
|
||||
title: "Software Products",
|
||||
category: "CREATIVE & DEVELOPER TOOLS",
|
||||
icon: Terminal,
|
||||
tagline: "High-performance utilities engineered for creators, coders, and deep-focus thinkers.",
|
||||
description:
|
||||
"We build standalone software tools that respect user attention and privacy. Our software stack emphasizes local-first execution, instantaneous boot times, minimal memory footprints, and fluid spatial aesthetics.",
|
||||
stack: ["Rust", "TypeScript", "WebGPU", "Local-First SQLite", "Tauri", "Custom GLSL"],
|
||||
principles: [
|
||||
"Zero telemetry bloat or intrusive subscription traps",
|
||||
"Deterministic local-first file system workflows",
|
||||
"Sub-16ms latency interface responsiveness",
|
||||
"Minimalist spatial design inspired by cockpit HUDs",
|
||||
],
|
||||
currentInitiatives: [
|
||||
{ name: "NebulaFlow", stage: "Public Alpha", note: "Real-time visual node graph for generative coders" },
|
||||
{ name: "Voidwalker OS", stage: "Prototype", note: "Ultra-distraction-free spatial terminal" },
|
||||
],
|
||||
accentColor: "from-cyan-500 to-blue-600",
|
||||
pillBorder: "border-cyan-500/30 text-cyan-400 bg-cyan-500/10",
|
||||
glowColor: "rgba(56, 189, 248, 0.15)",
|
||||
},
|
||||
{
|
||||
id: "games",
|
||||
number: "02",
|
||||
title: "Original Games",
|
||||
category: "ATMOSPHERIC & INDIE TITLES",
|
||||
icon: Gamepad2,
|
||||
tagline: "Evocative, mechanics-first game experiences set in interstellar and surreal realities.",
|
||||
description:
|
||||
"Our games emphasize tactile physics, memorable soundscapes, and evocative storytelling. We reject predatory monetization and live-service treadmills—focusing exclusively on handcrafted, complete experiences that respect the player's time.",
|
||||
stack: ["Godot Engine", "Custom C++ GDExtension", "Bespoke Shaders", "FMOD / WebAudio", "Procreate / Blender"],
|
||||
principles: [
|
||||
"Uncompromising, single-purchase complete artistic vision",
|
||||
"Kinetic, physics-grounded flight and orbital mechanics",
|
||||
"Original dynamic synthesizer soundtracks and reactive foley",
|
||||
"Rich speculative sci-fi lore and evocative environmental narrative",
|
||||
],
|
||||
currentInitiatives: [
|
||||
{ name: "Aetheria: Chrono Drift", stage: "In Active Dev", note: "Tactical sci-fi flight RPG with time-dilation" },
|
||||
{ name: "Singularity Pulse", stage: "Playable Slice", note: "Hypnotic orbital defense rhythm-strategy" },
|
||||
],
|
||||
accentColor: "from-purple-500 to-pink-600",
|
||||
pillBorder: "border-purple-500/30 text-purple-400 bg-purple-500/10",
|
||||
glowColor: "rgba(168, 85, 247, 0.15)",
|
||||
},
|
||||
{
|
||||
id: "lab",
|
||||
number: "03",
|
||||
title: "Experimental Lab",
|
||||
category: "CREATIVE COMPUTING & R&D",
|
||||
icon: FlaskConical,
|
||||
tagline: "Unconstrained research in procedural systems, audio synthesis, and algorithmic art.",
|
||||
description:
|
||||
"The Aghatis Lab is our continuous skunkworks playground. Here we prototype procedural cosmos generators, WebAudio modular synths, chaotic attractor simulations, and emergent artificial life models that inform our core products.",
|
||||
stack: ["Three.js / R3F", "GLSL Compute", "Web Audio API", "WebAssembly", "Generative Math"],
|
||||
principles: [
|
||||
"Rapid computational sketches without commercial pressure",
|
||||
"Algorithmic exploration of celestial mathematics & fractals",
|
||||
"Open prototypes released to the creative technology community",
|
||||
"Direct R&D incubator for upcoming software & game mechanics",
|
||||
],
|
||||
currentInitiatives: [
|
||||
{ name: "ChromaSynth", stage: "Lab Sandbox", note: "Audio-reactive procedural geometry synthesizer" },
|
||||
{ name: "Project Event Horizon", stage: "R&D Prototype", note: "Planetary terrain generation via compute shaders" },
|
||||
],
|
||||
accentColor: "from-emerald-500 to-cyan-500",
|
||||
pillBorder: "border-emerald-500/30 text-emerald-400 bg-emerald-500/10",
|
||||
glowColor: "rgba(16, 185, 129, 0.15)",
|
||||
},
|
||||
];
|
||||
|
||||
const current = tracks[activeTrack];
|
||||
|
||||
return (
|
||||
<section id="focus" className="relative py-28 overflow-hidden">
|
||||
{/* Background ambient lighting */}
|
||||
<div className="absolute top-1/3 right-0 w-[500px] h-[500px] bg-purple-600/10 rounded-full blur-[160px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col items-center text-center max-w-3xl mx-auto mb-16 space-y-4">
|
||||
<div className="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full glass-panel border border-cyan-500/30 text-xs font-mono text-cyan-300">
|
||||
<Layers className="w-3.5 h-3.5 text-cyan-400" />
|
||||
<span>OPERATIONAL TRACKS</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-black tracking-tight text-white">
|
||||
Three Dedicated Arenas of <br />
|
||||
<span className="text-gradient-cyan">In-House Creation.</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-base sm:text-lg text-slate-400 leading-relaxed pt-2">
|
||||
Every project inside Aghatis Studio originates from one of three symbiotic disciplines,
|
||||
channeling our entire focus into original software, atmospheric games, and computational experiments.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Track Selector Tabs */}
|
||||
<div className="flex flex-wrap items-center justify-center gap-3 mb-12">
|
||||
{tracks.map((track, idx) => {
|
||||
const Icon = track.icon;
|
||||
const isSelected = activeTrack === idx;
|
||||
return (
|
||||
<button
|
||||
key={track.id}
|
||||
onClick={() => setActiveTrack(idx)}
|
||||
className={`flex items-center gap-3 px-5 py-3 rounded-2xl font-mono text-xs uppercase tracking-wider transition-all duration-300 cursor-pointer ${
|
||||
isSelected
|
||||
? "glass-panel-glow border-cyan-400/50 text-white shadow-[0_0_25px_rgba(56,189,248,0.25)] scale-[1.02]"
|
||||
: "glass-card text-slate-400 hover:text-slate-200 hover:border-white/20"
|
||||
}`}
|
||||
>
|
||||
<span className="text-slate-400 font-bold">{track.number}</span>
|
||||
<Icon className={`w-4 h-4 ${isSelected ? "text-cyan-400" : "text-slate-400"}`} />
|
||||
<span className="font-semibold">{track.title}</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Active Track Deep Dive Display */}
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={current.id}
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -15 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
className="glass-panel-glow p-8 sm:p-12 rounded-3xl relative overflow-hidden border border-white/10"
|
||||
style={{
|
||||
boxShadow: `0 0 60px -15px ${current.glowColor}`,
|
||||
}}
|
||||
>
|
||||
{/* Ambient accent top bar */}
|
||||
<div className={`absolute top-0 left-0 right-0 h-1.5 bg-gradient-to-r ${current.accentColor}`} />
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-10">
|
||||
|
||||
{/* Left Column: Track Philosophy & Overview */}
|
||||
<div className="lg:col-span-7 space-y-6">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className={`px-2.5 py-1 rounded-md text-[11px] font-mono tracking-widest uppercase border ${current.pillBorder}`}>
|
||||
TRACK {current.number} // {current.category}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h3 className="text-2xl sm:text-3xl lg:text-4xl font-extrabold text-white leading-tight">
|
||||
{current.tagline}
|
||||
</h3>
|
||||
|
||||
<p className="text-slate-300 text-sm sm:text-base leading-relaxed">
|
||||
{current.description}
|
||||
</p>
|
||||
|
||||
{/* Principles checklist */}
|
||||
<div className="space-y-3 pt-4">
|
||||
<div className="text-xs font-mono uppercase tracking-wider text-slate-400">
|
||||
// CORE ARCHITECTURAL COMMITMENTS
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
{current.principles.map((principle, i) => (
|
||||
<div key={i} className="flex items-start gap-2.5 text-xs text-slate-300">
|
||||
<CheckCircle2 className="w-4 h-4 text-cyan-400 shrink-0 mt-0.5" />
|
||||
<span>{principle}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stack Badges */}
|
||||
<div className="pt-4">
|
||||
<div className="text-xs font-mono uppercase tracking-wider text-slate-400 mb-2.5">
|
||||
// TECHNICAL ENGINE & TOOLCHAIN
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{current.stack.map((tech) => (
|
||||
<span
|
||||
key={tech}
|
||||
className="px-3 py-1 rounded-lg text-xs font-mono bg-white/5 border border-white/10 text-slate-300 hover:border-cyan-400/40 hover:text-white transition-colors"
|
||||
>
|
||||
{tech}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Column: Active In-Forge Projects in this track */}
|
||||
<div className="lg:col-span-5 flex flex-col justify-between space-y-6 bg-black/40 p-6 sm:p-8 rounded-2xl border border-white/5">
|
||||
<div>
|
||||
<div className="flex items-center justify-between pb-4 border-b border-white/10">
|
||||
<span className="text-xs font-mono uppercase tracking-wider text-slate-300 font-semibold">
|
||||
IN THE FORGE (CURRENT IP)
|
||||
</span>
|
||||
<span className="w-2 h-2 rounded-full bg-cyan-400 animate-ping" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-4 mt-6">
|
||||
{current.currentInitiatives.map((item, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="glass-card p-4 rounded-xl border-white/5 hover:border-cyan-500/30 group"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-1.5">
|
||||
<h4 className="text-sm font-bold text-white font-mono group-hover:text-cyan-300 transition-colors">
|
||||
{item.name}
|
||||
</h4>
|
||||
<span className="text-[10px] font-mono uppercase px-2 py-0.5 rounded bg-indigo-500/20 text-indigo-300 border border-indigo-400/30">
|
||||
{item.stage}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-slate-400">
|
||||
{item.note}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Direct quick jump CTA */}
|
||||
<a
|
||||
href="#portfolio"
|
||||
className="w-full flex items-center justify-center gap-2 py-3 px-4 rounded-xl font-mono text-xs uppercase tracking-wider font-semibold text-white glass-panel hover:border-cyan-400/50 hover:bg-white/10 transition-all duration-200 group"
|
||||
>
|
||||
<span>View All Works in Showcase</span>
|
||||
<ArrowUpRight className="w-4 h-4 text-cyan-400 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Sparkles,
|
||||
ArrowRight,
|
||||
Check,
|
||||
Radio,
|
||||
Globe,
|
||||
Shield,
|
||||
} from "lucide-react";
|
||||
|
||||
export default function Footer() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [subscribed, setSubscribed] = useState(false);
|
||||
|
||||
const handleSubscribe = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (email.trim().length > 3) {
|
||||
setSubscribed(true);
|
||||
setEmail("");
|
||||
}
|
||||
};
|
||||
|
||||
const socialLinks = [
|
||||
{
|
||||
name: "GitHub",
|
||||
href: "https://github.com",
|
||||
svg: (
|
||||
<svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
|
||||
<path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.53 1.032 1.53 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "X (Twitter)",
|
||||
href: "https://x.com",
|
||||
svg: (
|
||||
<svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
|
||||
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Discord",
|
||||
href: "https://discord.com",
|
||||
svg: (
|
||||
<svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
|
||||
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994.021-.041.001-.09-.041-.106a13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.929 1.793 8.18 1.793 12.061 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.894.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.028zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Steam",
|
||||
href: "https://store.steampowered.com",
|
||||
svg: (
|
||||
<svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
|
||||
<path d="M12 2a10 10 0 0 0-10 10c0 4.767 3.339 8.75 7.828 9.742l3.418-4.992a3.02 3.02 0 0 1-.246-.145l-4.524 1.86a2.022 2.022 0 0 1-2.476-2.476l1.86-4.524a3 3 0 0 1 4.14-4.14l4.524-1.86a2.02 2.02 0 0 1 2.476 2.476l-1.86 4.524c.063.078.113.162.15.251l4.992-3.418A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "itch.io",
|
||||
href: "https://itch.io",
|
||||
svg: (
|
||||
<svg className="w-4 h-4 fill-current" viewBox="0 0 24 24">
|
||||
<path d="M2.5 5.5v2.2c0 .9.7 1.8 1.6 1.8.9 0 1.6-.9 1.6-1.8V5.5H2.5zm4.8 0v2.2c0 .9.7 1.8 1.6 1.8.9 0 1.6-.9 1.6-1.8V5.5H7.3zm4.8 0v2.2c0 .9.7 1.8 1.6 1.8.9 0 1.6-.9 1.6-1.8V5.5h-3.2zm4.8 0v2.2c0 .9.7 1.8 1.6 1.8.9 0 1.6-.9 1.6-1.8V5.5h-3.2zm4.8 0v2.2c0 .9.7 1.8 1.6 1.8.9 0 1.6-.9 1.6-1.8V5.5h-3.2zM2 11.5c0 1.7 1.1 3.2 2.7 3.5v5.5c0 .8.7 1.5 1.5 1.5h11.6c.8 0 1.5-.7 1.5-1.5V15c1.6-.3 2.7-1.8 2.7-3.5H2zm7 3h6v2H9v-2z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<footer className="relative border-t border-white/10 bg-[#08080f] pt-20 pb-12 overflow-hidden">
|
||||
{/* Background ambient lighting */}
|
||||
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-[600px] h-[300px] bg-indigo-500/10 rounded-full blur-[140px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
{/* Top Section: Newsletter Transmissions */}
|
||||
<div className="glass-panel p-8 sm:p-12 rounded-3xl border border-white/10 mb-16 relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-80 h-80 bg-cyan-500/10 rounded-full blur-[100px] pointer-events-none" />
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 items-center">
|
||||
<div className="lg:col-span-7 space-y-3">
|
||||
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-cyan-500/10 border border-cyan-400/20 text-[11px] font-mono text-cyan-300">
|
||||
<Radio className="w-3 h-3 text-cyan-400 animate-pulse" />
|
||||
<span>FREQUENCY DISPATCH // DIRECT FEED</span>
|
||||
</div>
|
||||
<h3 className="text-2xl sm:text-3xl font-extrabold text-white font-mono">
|
||||
Join the Aghatis Orbital Transmissions
|
||||
</h3>
|
||||
<p className="text-sm text-slate-400 max-w-xl">
|
||||
Receive confidential dispatches on original software alpha testing, closed game playtests, and deep-dive engineering devlogs. Zero marketing spam.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="lg:col-span-5">
|
||||
{subscribed ? (
|
||||
<div className="p-4 rounded-2xl bg-cyan-950/40 border border-cyan-400/30 flex items-center gap-3 text-xs font-mono text-cyan-300">
|
||||
<Check className="w-5 h-5 text-cyan-400" />
|
||||
<span>SIGNAL LOCKED. You are registered for upcoming playtests.</span>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubscribe} className="flex flex-col sm:flex-row gap-3">
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="[email protected]"
|
||||
required
|
||||
className="flex-1 px-4 py-3 rounded-xl bg-white/5 border border-white/15 text-white placeholder-slate-500 text-xs font-mono focus:outline-none focus:border-cyan-400 transition-colors"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="px-6 py-3 rounded-xl bg-gradient-to-r from-cyan-400 to-indigo-400 text-slate-950 font-mono text-xs uppercase tracking-wider font-bold hover:opacity-90 transition-opacity flex items-center justify-center gap-2 shrink-0 cursor-pointer shadow-lg"
|
||||
>
|
||||
<span>Tune In</span>
|
||||
<ArrowRight className="w-3.5 h-3.5 text-slate-950" />
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Middle Section: Studio Details & Links */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-12 gap-10 pb-16 border-b border-white/10">
|
||||
|
||||
{/* Col 1: Studio Brand */}
|
||||
<div className="lg:col-span-5 space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-lg bg-gradient-to-tr from-cyan-400 to-indigo-500 flex items-center justify-center text-slate-950 font-black text-xs">
|
||||
AS
|
||||
</div>
|
||||
<span className="font-mono font-bold tracking-widest text-lg text-white">
|
||||
AGHATIS STUDIO
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-xs text-slate-400 leading-relaxed max-w-sm">
|
||||
An independent product laboratory crafting original software, atmospheric games,
|
||||
and experimental systems. Dedicated exclusively to our own in-house creative universe.
|
||||
</p>
|
||||
<div className="flex items-center gap-2 text-xs font-mono text-cyan-400 pt-2">
|
||||
<span className="w-2 h-2 rounded-full bg-cyan-400 animate-ping" />
|
||||
<span>ORBITAL BEACON: ACTIVE // SECTOR 01</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Col 2: Navigation */}
|
||||
<div className="lg:col-span-2 space-y-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-wider text-white font-bold">
|
||||
NAVIGATION
|
||||
</h4>
|
||||
<ul className="space-y-2 text-xs font-mono text-slate-400">
|
||||
<li>
|
||||
<a href="#about" className="hover:text-cyan-300 transition-colors">
|
||||
Studio Narrative
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#focus" className="hover:text-cyan-300 transition-colors">
|
||||
Core Tracks
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#portfolio" className="hover:text-cyan-300 transition-colors">
|
||||
Product Fleet
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#creed" className="hover:text-cyan-300 transition-colors">
|
||||
Sovereign Creed
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin" className="text-cyan-400 hover:text-cyan-300 transition-colors flex items-center gap-1">
|
||||
<span>Admin Cockpit</span>
|
||||
<span className="text-[9px] px-1 rounded bg-cyan-500/20">DB</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Col 3: Product Tracks */}
|
||||
<div className="lg:col-span-2 space-y-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-wider text-white font-bold">
|
||||
PORTFOLIO
|
||||
</h4>
|
||||
<ul className="space-y-2 text-xs font-mono text-slate-400">
|
||||
<li>
|
||||
<a href="#portfolio" className="hover:text-cyan-300 transition-colors">
|
||||
Aetheria: Chrono Drift
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#portfolio" className="hover:text-cyan-300 transition-colors">
|
||||
NebulaFlow
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#portfolio" className="hover:text-cyan-300 transition-colors">
|
||||
Voidwalker OS
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#portfolio" className="hover:text-cyan-300 transition-colors">
|
||||
ChromaSynth Lab
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Col 4: Transmissions & Socials */}
|
||||
<div className="lg:col-span-3 space-y-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-wider text-white font-bold">
|
||||
CHANNELS
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2 pt-1">
|
||||
{socialLinks.map((link) => (
|
||||
<a
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="p-2.5 rounded-xl glass-card text-slate-400 hover:text-white hover:border-cyan-400/50 hover:bg-white/5 transition-all"
|
||||
aria-label={link.name}
|
||||
>
|
||||
{link.svg}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<p className="text-[11px] font-mono text-slate-400 pt-2">
|
||||
PGP Encrypted Public Key: 0x8F4E...91A
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Bottom Bar & Implicit In-House Studio Disclaimer */}
|
||||
<div className="pt-8 flex flex-col md:flex-row items-center justify-between gap-6">
|
||||
|
||||
{/* Studio Focus Charter */}
|
||||
<div className="flex items-start sm:items-center gap-3 text-xs font-mono text-slate-400 max-w-2xl">
|
||||
<Shield className="w-4 h-4 text-cyan-400 shrink-0 mt-0.5 sm:mt-0" />
|
||||
<p>
|
||||
<strong className="text-slate-300">STUDIO CHARTER:</strong> An independent product laboratory dedicated to engineering high-performance creative software and publishing atmospheric, narrative-driven games.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="text-xs font-mono text-slate-400 shrink-0">
|
||||
© 2026 Aghatis Studio. All rights reserved.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { motion } from "framer-motion";
|
||||
import { ArrowRight, Terminal, Sparkles, Orbit } from "lucide-react";
|
||||
|
||||
// Dynamically import 3D Hero Solar System with sleek animated fallback
|
||||
const HeroSolarSystem = dynamic(
|
||||
() => import("../canvas/HeroSolarSystem"),
|
||||
{
|
||||
ssr: false,
|
||||
loading: () => (
|
||||
<div className="relative w-full h-[400px] sm:h-[480px] lg:h-[540px] flex items-center justify-center">
|
||||
{/* Animated CSS Solar System Loading State */}
|
||||
<div className="relative w-72 h-72 sm:w-96 sm:h-96 flex items-center justify-center">
|
||||
{/* Central Sun Glow */}
|
||||
<div className="w-16 h-16 rounded-full bg-gradient-to-tr from-cyan-400 to-indigo-500 shadow-[0_0_50px_#38bdf8] animate-pulse" />
|
||||
|
||||
{/* Orbit Track 1 */}
|
||||
<div className="absolute w-36 h-36 rounded-full border border-cyan-500/30 animate-[spin_6s_linear_infinite]">
|
||||
<div className="w-3 h-3 rounded-full bg-amber-400 shadow-[0_0_10px_#fbbf24] -translate-x-1.5" />
|
||||
</div>
|
||||
|
||||
{/* Orbit Track 2 */}
|
||||
<div className="absolute w-56 h-56 rounded-full border border-indigo-500/30 animate-[spin_10s_linear_infinite]">
|
||||
<div className="w-4 h-4 rounded-full bg-cyan-400 shadow-[0_0_12px_#38bdf8] -translate-x-2" />
|
||||
</div>
|
||||
|
||||
{/* Orbit Track 3 */}
|
||||
<div className="absolute w-80 h-80 rounded-full border border-purple-500/25 animate-[spin_16s_linear_infinite]">
|
||||
<div className="w-5 h-5 rounded-full bg-purple-400 shadow-[0_0_15px_#c084fc] -translate-x-2.5" />
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-4 px-3 py-1 rounded-full glass-panel text-[11px] font-mono text-cyan-300">
|
||||
CONNECTING STELLAR TELEMETRY...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
export default function Hero() {
|
||||
const telemetryStats = [
|
||||
{ label: "IP Ownership", value: "100%", subtext: "In-House Creations" },
|
||||
{ label: "Product Focus", value: "Pure IP", subtext: "Dedicated In-House Pipeline" },
|
||||
{ label: "Active Tracks", value: "3", subtext: "Software, Games, Lab" },
|
||||
{ label: "Studio State", value: "Autonomous", subtext: "Self-Sovereign Roadmap" },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="relative min-h-[92vh] pt-28 sm:pt-32 pb-20 flex flex-col justify-center overflow-hidden">
|
||||
{/* Decorative cosmic glow halos */}
|
||||
<div className="absolute top-1/4 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[400px] bg-gradient-to-tr from-indigo-500/10 via-purple-500/10 to-cyan-500/10 blur-[130px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 w-full">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-8 items-start">
|
||||
|
||||
{/* Left Column: Brand Statement & Typography */}
|
||||
<div className="lg:col-span-6 space-y-6 text-center lg:text-left">
|
||||
|
||||
{/* Main Headline */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.7 }}
|
||||
className="space-y-3"
|
||||
>
|
||||
<h1 className="text-4xl sm:text-5xl lg:text-6xl xl:text-7xl font-black tracking-tight leading-[1.08]">
|
||||
Synthesizing <br />
|
||||
<span className="text-gradient-cyan">Original Software</span> <br />
|
||||
<span className="text-white">& Interactive Worlds.</span>
|
||||
</h1>
|
||||
<p className="text-base sm:text-lg lg:text-xl text-slate-400 font-normal max-w-2xl mx-auto lg:mx-0 leading-relaxed pt-2">
|
||||
Aghatis Studio operates exclusively as an autonomous product laboratory.
|
||||
We engineer bespoke software tools, forge atmospheric indie games,
|
||||
and explore experimental computational frontiers with relentless dedication to craft.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Core Capability Chips */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 15 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.7, delay: 0.15 }}
|
||||
className="flex flex-wrap items-center justify-center lg:justify-start gap-2 pt-1"
|
||||
>
|
||||
{[
|
||||
"GPU Shaders & WebGPU",
|
||||
"Kinetic Orbital Physics",
|
||||
"Local-First Architectures",
|
||||
"Procedural Audio Engines",
|
||||
].map((chip) => (
|
||||
<span
|
||||
key={chip}
|
||||
className="px-2.5 py-1 rounded-md text-[11px] font-mono bg-white/5 border border-white/10 text-slate-300 hover:border-cyan-400/40 hover:text-white transition-colors"
|
||||
>
|
||||
{chip}
|
||||
</span>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
{/* Call to Actions */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.7, delay: 0.2 }}
|
||||
className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4 pt-2"
|
||||
>
|
||||
<a
|
||||
href="#portfolio"
|
||||
className="w-full sm:w-auto px-7 py-3.5 rounded-xl font-mono text-xs uppercase tracking-widest font-bold text-slate-950 bg-gradient-to-r from-cyan-400 via-sky-300 to-indigo-300 hover:opacity-95 shadow-[0_0_30px_rgba(56,189,248,0.4)] transition-all duration-300 flex items-center justify-center gap-2 group hover:scale-[1.02] active:scale-95"
|
||||
>
|
||||
<Sparkles className="w-4 h-4 text-slate-950" />
|
||||
<span>Explore Fleet</span>
|
||||
<ArrowRight className="w-4 h-4 text-slate-950 group-hover:translate-x-1 transition-transform" />
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="#creed"
|
||||
className="w-full sm:w-auto px-6 py-3.5 rounded-xl font-mono text-xs uppercase tracking-widest font-semibold text-slate-300 hover:text-white glass-panel hover:border-indigo-500/50 transition-all duration-300 flex items-center justify-center gap-2 group"
|
||||
>
|
||||
<Terminal className="w-4 h-4 text-indigo-400" />
|
||||
<span>The Studio Creed</span>
|
||||
</a>
|
||||
</motion.div>
|
||||
|
||||
{/* Studio Focus Badge */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
className="pt-2 text-xs font-mono text-slate-400 flex items-center justify-center lg:justify-start gap-2"
|
||||
>
|
||||
<Orbit className="w-3.5 h-3.5 text-indigo-400" />
|
||||
<span>Dedicated strictly to researching, building, and publishing our own product ecosystem.</span>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Right Column: 3D Solar System Visualization (Full Frustum Uncropped, Raised to Align with Headline) */}
|
||||
<div className="lg:col-span-6 relative flex items-center justify-center lg:-mt-10 xl:-mt-14">
|
||||
<HeroSolarSystem />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Telemetry Stats Bar */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
className="mt-16 sm:mt-20 pt-8 border-t border-white/10"
|
||||
>
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-6 sm:gap-8">
|
||||
{telemetryStats.map((stat, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="glass-card p-5 rounded-2xl relative overflow-hidden group hover:border-cyan-500/30"
|
||||
>
|
||||
<div className="absolute top-0 left-0 w-12 h-1 bg-gradient-to-r from-cyan-400 to-indigo-500 group-hover:w-full transition-all duration-500" />
|
||||
<div className="text-2xl sm:text-3xl font-black font-mono tracking-tight text-white group-hover:text-cyan-300 transition-colors">
|
||||
{stat.value}
|
||||
</div>
|
||||
<div className="text-xs font-mono uppercase tracking-wider text-slate-300 mt-1">
|
||||
{stat.label}
|
||||
</div>
|
||||
<div className="text-[11px] font-mono text-slate-400 mt-1">
|
||||
{stat.subtext}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Sparkles, Menu, X, Compass, Layers, ShieldCheck, Box } from "lucide-react";
|
||||
import CosmicAudioToggle from "../ui/CosmicAudioToggle";
|
||||
|
||||
export default function Navbar() {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setScrolled(window.scrollY > 20);
|
||||
};
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
const navLinks = [
|
||||
{ name: "About", href: "#about", icon: Compass },
|
||||
{ name: "Core Tracks", href: "#focus", icon: Layers },
|
||||
{ name: "Showcase", href: "#portfolio", icon: Box },
|
||||
{ name: "Studio Creed", href: "#creed", icon: ShieldCheck },
|
||||
];
|
||||
|
||||
return (
|
||||
<header
|
||||
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
||||
scrolled
|
||||
? "py-3 bg-[#0a0a12]/80 backdrop-blur-xl border-b border-white/10 shadow-[0_4px_30px_rgba(0,0,0,0.5)]"
|
||||
: "py-5 bg-transparent"
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between">
|
||||
{/* Brand Logo */}
|
||||
<a
|
||||
href="#"
|
||||
className="flex items-center gap-3 group focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-400 rounded-lg p-1"
|
||||
>
|
||||
<div className="relative flex items-center justify-center w-10 h-10 rounded-xl bg-gradient-to-br from-indigo-500/20 via-purple-500/10 to-cyan-500/20 border border-white/15 group-hover:border-cyan-400/50 transition-colors shadow-inner">
|
||||
<span className="w-2.5 h-2.5 rounded-full bg-cyan-400 group-hover:scale-125 transition-transform shadow-[0_0_12px_#38bdf8]" />
|
||||
<div className="absolute inset-0 rounded-xl border border-indigo-500/30 group-hover:rotate-45 transition-transform duration-500 pointer-events-none" />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-extrabold tracking-widest text-lg text-white group-hover:text-cyan-200 transition-colors">
|
||||
AGHATIS
|
||||
</span>
|
||||
<span className="text-[10px] font-mono tracking-widest uppercase px-1.5 py-0.5 rounded bg-indigo-500/15 border border-indigo-400/20 text-indigo-300">
|
||||
STUDIO
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-[10px] font-mono text-slate-400 tracking-wider">
|
||||
ORIGINAL IP LAB
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{/* Desktop Navigation Links */}
|
||||
<nav className="hidden md:flex items-center gap-1 glass-panel px-4 py-1.5 rounded-full border border-white/10">
|
||||
{navLinks.map((link) => (
|
||||
<a
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
className="px-3.5 py-1.5 text-xs font-mono uppercase tracking-wider text-slate-300 hover:text-white rounded-full hover:bg-white/5 transition-all duration-200"
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* Right actions: Audio Toggle, Live Status & CTA */}
|
||||
<div className="hidden sm:flex items-center gap-3">
|
||||
<CosmicAudioToggle />
|
||||
|
||||
{/* In-house status pill */}
|
||||
<div className="hidden lg:flex items-center gap-2 px-3 py-1.5 rounded-full bg-indigo-950/40 border border-indigo-500/20 text-[11px] font-mono text-indigo-200">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-indigo-400 animate-pulse" />
|
||||
<span>100% PRODUCT LAB</span>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="#portfolio"
|
||||
className="relative inline-flex items-center justify-center px-4 py-2 text-xs font-mono tracking-wider font-semibold uppercase text-slate-900 bg-gradient-to-r from-cyan-400 via-sky-300 to-indigo-300 rounded-lg shadow-[0_0_20px_rgba(56,189,248,0.35)] hover:shadow-[0_0_25px_rgba(56,189,248,0.6)] transition-all duration-300 hover:scale-[1.02] active:scale-95"
|
||||
>
|
||||
<Sparkles className="w-3.5 h-3.5 mr-1.5 text-slate-950" />
|
||||
Explore IP
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Button */}
|
||||
<div className="flex sm:hidden items-center gap-2">
|
||||
<CosmicAudioToggle />
|
||||
<button
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
className="p-2 rounded-lg glass-panel text-slate-300 hover:text-white focus:outline-none"
|
||||
aria-label="Toggle navigation menu"
|
||||
>
|
||||
{mobileMenuOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Drawer Menu */}
|
||||
<AnimatePresence>
|
||||
{mobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: "auto" }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
className="sm:hidden border-b border-white/10 bg-[#0a0a12]/95 backdrop-blur-2xl overflow-hidden"
|
||||
>
|
||||
<div className="px-6 py-6 space-y-4">
|
||||
<div className="flex items-center justify-between pb-3 border-b border-white/10 text-xs font-mono text-slate-400">
|
||||
<span>SECTOR // AGH-MOBILE-HUD</span>
|
||||
<span className="text-cyan-400">STATUS: NOMINAL</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
{navLinks.map((link) => {
|
||||
const Icon = link.icon;
|
||||
return (
|
||||
<a
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
className="flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-mono text-slate-300 hover:text-white hover:bg-white/5 transition-colors"
|
||||
>
|
||||
<Icon className="w-4 h-4 text-cyan-400" />
|
||||
<span>{link.name}</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<a
|
||||
href="#portfolio"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
className="w-full flex items-center justify-center gap-2 px-4 py-3 text-xs font-mono uppercase tracking-wider font-semibold text-slate-950 bg-gradient-to-r from-cyan-400 to-indigo-400 rounded-lg shadow-lg"
|
||||
>
|
||||
<Sparkles className="w-4 h-4 text-slate-950" />
|
||||
Explore Original IP
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="text-[11px] font-mono text-center text-slate-400 pt-2 border-t border-white/5">
|
||||
Independent Product Studio • Original Software & Games
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,501 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import {
|
||||
Sparkles,
|
||||
ArrowUpRight,
|
||||
Gamepad2,
|
||||
Terminal,
|
||||
FlaskConical,
|
||||
X,
|
||||
ExternalLink,
|
||||
Cpu,
|
||||
Layers,
|
||||
Calendar,
|
||||
ShieldCheck,
|
||||
} from "lucide-react";
|
||||
|
||||
interface Product {
|
||||
id: string;
|
||||
title: string;
|
||||
category: "software" | "games" | "lab";
|
||||
categoryLabel: string;
|
||||
tagline: string;
|
||||
status: string;
|
||||
statusType: "active" | "alpha" | "prototype" | "upcoming";
|
||||
releaseTarget: string;
|
||||
description: string;
|
||||
longDescription: string;
|
||||
features: string[];
|
||||
stack: string[];
|
||||
accentGradient: string;
|
||||
borderGlow: string;
|
||||
icon: typeof Gamepad2;
|
||||
}
|
||||
|
||||
export default function Portfolio() {
|
||||
const [filter, setFilter] = useState<string>("all");
|
||||
const [selectedProduct, setSelectedProduct] = useState<Product | null>(null);
|
||||
const [productsList, setProductsList] = useState<Product[]>([]);
|
||||
|
||||
React.useEffect(() => {
|
||||
setProductsList(initialProducts);
|
||||
async function fetchFromDB() {
|
||||
try {
|
||||
const res = await fetch("/api/projects");
|
||||
if (res.ok) {
|
||||
const json = await res.json();
|
||||
if (json.success && Array.isArray(json.data) && json.data.length > 0) {
|
||||
interface ApiProject {
|
||||
id: string;
|
||||
title: string;
|
||||
category: "software" | "games" | "lab";
|
||||
categoryLabel: string;
|
||||
tagline: string;
|
||||
status: string;
|
||||
statusType: "active" | "alpha" | "prototype" | "upcoming";
|
||||
releaseTarget: string;
|
||||
description: string;
|
||||
longDescription: string;
|
||||
features: string[];
|
||||
stack: string[];
|
||||
accentGradient: string;
|
||||
borderGlow: string;
|
||||
iconName: string;
|
||||
}
|
||||
|
||||
const mapped: Product[] = json.data.map((p: ApiProject) => ({
|
||||
...p,
|
||||
icon:
|
||||
p.iconName === "Gamepad2"
|
||||
? Gamepad2
|
||||
: p.iconName === "FlaskConical"
|
||||
? FlaskConical
|
||||
: Terminal,
|
||||
}));
|
||||
setProductsList(mapped);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Fallback silently to initial products
|
||||
}
|
||||
}
|
||||
fetchFromDB();
|
||||
}, []);
|
||||
|
||||
const initialProducts: Product[] = [
|
||||
{
|
||||
id: "aetheria",
|
||||
title: "Aetheria: Chrono Drift",
|
||||
category: "games",
|
||||
categoryLabel: "Tactical Flight RPG",
|
||||
tagline: "Atmospheric spaceflight RPG driven by Newtonian physics & relativistic time mechanics.",
|
||||
status: "In Active Dev",
|
||||
statusType: "active",
|
||||
releaseTarget: "Alpha 2027",
|
||||
description:
|
||||
"Pilot handcrafted atmospheric ships through uncharted cosmic sectors. Engage in tactical orbital maneuvers where time dilates with engine velocity.",
|
||||
longDescription:
|
||||
"Aetheria is our flagship narrative sci-fi title. Designed without live-service grind or predatory mechanics, it centers on contemplative space exploration, deep Newtonian flight kinematics, and an original interactive dark-ambient synth score.",
|
||||
features: [
|
||||
"True orbital mechanics and gravitational slingshots",
|
||||
"Non-linear stellar narrative with faction autonomy",
|
||||
"Zero-compromise single-player standalone artistic experience",
|
||||
"Procedurally synthesized nebula volumetric rendering",
|
||||
],
|
||||
stack: ["Godot 4.3", "C++ GDExtension", "Bespoke GLSL", "FMOD Sound Engine"],
|
||||
accentGradient: "from-cyan-500/20 via-blue-600/10 to-transparent",
|
||||
borderGlow: "hover:border-cyan-400/50 hover:shadow-[0_0_30px_rgba(56,189,248,0.25)]",
|
||||
icon: Gamepad2,
|
||||
},
|
||||
{
|
||||
id: "nebulaflow",
|
||||
title: "NebulaFlow",
|
||||
category: "software",
|
||||
categoryLabel: "Creative Shader Pipeline",
|
||||
tagline: "Node-based real-time GPU shader workbench & procedural VFX engine.",
|
||||
status: "Private Alpha",
|
||||
statusType: "alpha",
|
||||
releaseTarget: "Beta Q3 2027",
|
||||
description:
|
||||
"A high-performance visual coding environment for creative coders, game devs, and technical artists compiling directly to WGSL and GLSL.",
|
||||
longDescription:
|
||||
"NebulaFlow re-imagines real-time shader generation. Designed with a lightweight Rust core and a distraction-free spatial interface, it compiles visual nodes directly into native shaders at 120 FPS with instantaneous hot-reloading.",
|
||||
features: [
|
||||
"Instant compilation to WGSL, GLSL, and Metal Shading Language",
|
||||
"Deterministic local-first project workspace without cloud locks",
|
||||
"Live audio-reactive parameter modulation via WebAudio / ASIO",
|
||||
"Integrated raymarching and compute shader node library",
|
||||
],
|
||||
stack: ["Rust", "WebGPU", "Tauri", "TypeScript", "WGSL"],
|
||||
accentGradient: "from-purple-500/20 via-indigo-600/10 to-transparent",
|
||||
borderGlow: "hover:border-purple-400/50 hover:shadow-[0_0_30px_rgba(168,85,247,0.25)]",
|
||||
icon: Terminal,
|
||||
},
|
||||
{
|
||||
id: "voidwalker",
|
||||
title: "Voidwalker OS",
|
||||
category: "software",
|
||||
categoryLabel: "Spatial Workstation",
|
||||
tagline: "Distraction-free spatial terminal and local knowledge workstation for intense focus.",
|
||||
status: "Prototype",
|
||||
statusType: "prototype",
|
||||
releaseTarget: "Q4 2027",
|
||||
description:
|
||||
"An experimental desktop environment stripping away notification clutter in favor of an ergonomic cosmic workspace and local neural indexing.",
|
||||
longDescription:
|
||||
"Voidwalker replaces chaotic desktop windows with an infinite 2.5D orbital plane. Crafted for independent developers and creative writers who demand absolute cognitive quiet.",
|
||||
features: [
|
||||
"Local-first vector indexing over personal markdown & codebases",
|
||||
"Orbital workspace clustering with keyboard-centric navigation",
|
||||
"Sub-10ms input latency with custom GPU text rendering engine",
|
||||
"Zero tracking, zero analytics, zero telemetry overhead",
|
||||
],
|
||||
stack: ["Rust", "SQLite", "Vulkan / Metal", "Tree-Sitter"],
|
||||
accentGradient: "from-indigo-500/20 via-sky-600/10 to-transparent",
|
||||
borderGlow: "hover:border-indigo-400/50 hover:shadow-[0_0_30px_rgba(99,102,241,0.25)]",
|
||||
icon: Terminal,
|
||||
},
|
||||
{
|
||||
id: "singularity-pulse",
|
||||
title: "Singularity Pulse",
|
||||
category: "games",
|
||||
categoryLabel: "Kinetic Rhythm-Strategy",
|
||||
tagline: "Orbital rhythm defense game where celestial gravitational waves dictate combat tempo.",
|
||||
status: "Playable Slice",
|
||||
statusType: "prototype",
|
||||
releaseTarget: "2027",
|
||||
description:
|
||||
"Defend dying binary stars from quantum anomalies by aligning resonant frequencies in time with an escalating electronic pulse.",
|
||||
longDescription:
|
||||
"Built at the intersection of rhythm gaming and orbital physics, Singularity Pulse challenges players to synchronize defensive shields with gravitational wave oscillations in real-time.",
|
||||
features: [
|
||||
"Dynamic sound-reactive procedural enemy generation",
|
||||
"Precise sub-millisecond input synchronization",
|
||||
"Full support for analog sticks, arcade sticks, and MIDI input",
|
||||
"Minimalist wireframe vector aesthetic inspired by 80s arcade radars",
|
||||
],
|
||||
stack: ["Godot", "WebAudio", "Procedural GLSL"],
|
||||
accentGradient: "from-pink-500/20 via-rose-600/10 to-transparent",
|
||||
borderGlow: "hover:border-pink-400/50 hover:shadow-[0_0_30px_rgba(244,63,94,0.25)]",
|
||||
icon: Gamepad2,
|
||||
},
|
||||
{
|
||||
id: "chromasynth",
|
||||
title: "ChromaSynth Lab",
|
||||
category: "lab",
|
||||
categoryLabel: "Spatial Sound Synthesis",
|
||||
tagline: "WebGPU audio-reactive 3D synthesis tool exploring geometric resonance.",
|
||||
status: "Public Experiment",
|
||||
statusType: "alpha",
|
||||
releaseTarget: "Live Now",
|
||||
description:
|
||||
"A browser-based generative instrument generating real-time higher-dimensional geometric manifolds modulated by live microphone and MIDI input.",
|
||||
longDescription:
|
||||
"ChromaSynth began as a weekend exploration in our experimental lab. It treats polyphonic audio frequencies as physical forces that deform complex geometric meshes in real time.",
|
||||
features: [
|
||||
"Modular 8-oscillator additive & FM synthesis engine",
|
||||
"Real-time 4D hypercube and manifold geometry projection",
|
||||
"Exportable high-res WebM / MP4 video stems for VJs",
|
||||
"Open-source computational code released for researchers",
|
||||
],
|
||||
stack: ["Three.js", "Web Audio API", "GLSL Compute", "WebAssembly"],
|
||||
accentGradient: "from-emerald-500/20 via-teal-600/10 to-transparent",
|
||||
borderGlow: "hover:border-emerald-400/50 hover:shadow-[0_0_30px_rgba(16,185,129,0.25)]",
|
||||
icon: FlaskConical,
|
||||
},
|
||||
{
|
||||
id: "event-horizon",
|
||||
title: "Project Event Horizon",
|
||||
category: "lab",
|
||||
categoryLabel: "Procedural Cosmos R&D",
|
||||
tagline: "Compute-shader planetary terrain synthesis & atmospheric Rayleigh scattering.",
|
||||
status: "R&D Prototype",
|
||||
statusType: "prototype",
|
||||
releaseTarget: "Continuous R&D",
|
||||
description:
|
||||
"Algorithmic generation of continental scale geological plates, biome micro-climates, and photorealistic atmospheric scattering.",
|
||||
longDescription:
|
||||
"The technological foundation for our future game worlds. Event Horizon runs entirely on GPU compute shaders to generate planet-scale terrain down to individual pebbles seamlessly.",
|
||||
features: [
|
||||
"Seamless transition from interplanetary orbit down to surface level",
|
||||
"Physical simulation of tectonic drift and erosion patterns",
|
||||
"Atmospheric volumetric cloud synthesis using 3D Worley noise",
|
||||
"Powers the underlying engine for upcoming Aghatis game titles",
|
||||
],
|
||||
stack: ["WGSL Compute", "Rust", "WebGPU"],
|
||||
accentGradient: "from-amber-500/20 via-orange-600/10 to-transparent",
|
||||
borderGlow: "hover:border-amber-400/50 hover:shadow-[0_0_30px_rgba(245,158,11,0.25)]",
|
||||
icon: FlaskConical,
|
||||
},
|
||||
];
|
||||
|
||||
const filteredProducts =
|
||||
filter === "all"
|
||||
? productsList
|
||||
: productsList.filter((p) => p.category === filter);
|
||||
|
||||
return (
|
||||
<section id="portfolio" className="relative py-28 overflow-hidden">
|
||||
{/* Background celestial glow */}
|
||||
<div className="absolute top-1/2 left-1/3 w-[600px] h-[600px] bg-cyan-600/10 rounded-full blur-[170px] pointer-events-none" />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col items-center text-center max-w-3xl mx-auto mb-16 space-y-4">
|
||||
<div className="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full glass-panel border border-indigo-500/30 text-xs font-mono text-indigo-300">
|
||||
<Sparkles className="w-3.5 h-3.5 text-indigo-400" />
|
||||
<span>ORIGINAL IP FLEET</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-black tracking-tight text-white">
|
||||
Proprietary Works & <br />
|
||||
<span className="text-gradient-cyan">Upcoming Titles.</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-base sm:text-lg text-slate-400 leading-relaxed pt-2">
|
||||
Every product showcased below is conceived, engineered, and published in-house
|
||||
as part of our permanent creative universe and software ecosystem.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Filter Controls */}
|
||||
<div className="flex flex-wrap items-center justify-center gap-2 sm:gap-3 mb-14">
|
||||
{[
|
||||
{ id: "all", label: "All Works (06)" },
|
||||
{ id: "software", label: "Software Products" },
|
||||
{ id: "games", label: "Original Games" },
|
||||
{ id: "lab", label: "Experimental Lab" },
|
||||
].map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setFilter(tab.id)}
|
||||
className={`px-4 py-2 rounded-xl font-mono text-xs uppercase tracking-wider transition-all duration-200 cursor-pointer ${
|
||||
filter === tab.id
|
||||
? "bg-cyan-500/20 border border-cyan-400/50 text-cyan-300 shadow-[0_0_15px_rgba(56,189,248,0.25)]"
|
||||
: "glass-card text-slate-400 hover:text-slate-200 hover:border-white/20"
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Products Grid */}
|
||||
<motion.div
|
||||
layout
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8"
|
||||
>
|
||||
<AnimatePresence>
|
||||
{filteredProducts.map((product) => {
|
||||
const Icon = product.icon;
|
||||
return (
|
||||
<motion.div
|
||||
layout
|
||||
key={product.id}
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className={`glass-card rounded-2xl flex flex-col justify-between overflow-hidden relative group cursor-pointer transition-all duration-300 ${product.borderGlow}`}
|
||||
onClick={() => setSelectedProduct(product)}
|
||||
>
|
||||
{/* Visual card header area with cosmetic cosmic pattern */}
|
||||
<div className={`relative h-44 w-full bg-gradient-to-b ${product.accentGradient} p-6 flex flex-col justify-between border-b border-white/5`}>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[10px] font-mono uppercase px-2.5 py-1 rounded-full bg-black/50 backdrop-blur-md border border-white/10 text-cyan-300">
|
||||
{product.categoryLabel}
|
||||
</span>
|
||||
<span className="text-[10px] font-mono uppercase px-2.5 py-1 rounded-full bg-indigo-950/60 border border-indigo-400/20 text-indigo-300 flex items-center gap-1.5">
|
||||
<span className="w-1.5 h-1.5 rounded-full bg-indigo-400 animate-pulse" />
|
||||
{product.status}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Centered stylized graphic watermark */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="w-12 h-12 rounded-2xl bg-black/40 border border-white/10 flex items-center justify-center text-cyan-400 group-hover:scale-110 transition-transform shadow-lg">
|
||||
<Icon className="w-6 h-6" />
|
||||
</div>
|
||||
<span className="text-[11px] font-mono text-slate-400">
|
||||
TARGET: {product.releaseTarget}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card Body */}
|
||||
<div className="p-6 space-y-4 flex-1 flex flex-col justify-between">
|
||||
<div>
|
||||
<h3 className="text-xl font-bold font-mono text-white group-hover:text-cyan-300 transition-colors">
|
||||
{product.title}
|
||||
</h3>
|
||||
<p className="text-xs font-mono text-cyan-400/80 mt-1">
|
||||
{product.tagline}
|
||||
</p>
|
||||
<p className="text-xs text-slate-400 leading-relaxed mt-3">
|
||||
{product.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4 pt-2">
|
||||
{/* Tech stack badges */}
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{product.stack.map((item) => (
|
||||
<span
|
||||
key={item}
|
||||
className="text-[10px] font-mono px-2 py-0.5 rounded bg-white/5 border border-white/10 text-slate-300"
|
||||
>
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Card Footer action */}
|
||||
<div className="pt-3 border-t border-white/5 flex items-center justify-between text-xs font-mono text-slate-400 group-hover:text-cyan-300 transition-colors">
|
||||
<span>INSPECT SPEC & ARCHITECTURE</span>
|
||||
<ArrowUpRight className="w-4 h-4 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
|
||||
{/* In-House Notice banner */}
|
||||
<div className="mt-16 p-6 rounded-2xl glass-panel border border-cyan-500/20 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<ShieldCheck className="w-5 h-5 text-cyan-400 shrink-0" />
|
||||
<div className="text-xs font-mono text-slate-300">
|
||||
<span className="font-bold text-white">AUTONOMOUS PRODUCT FLEET // </span>
|
||||
Every title and utility is designed, developed, and maintained by Aghatis Studio from initial prototype to continuous release.
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="#creed"
|
||||
className="shrink-0 text-xs font-mono text-cyan-400 hover:text-cyan-300 flex items-center gap-1 underline underline-offset-4"
|
||||
>
|
||||
<span>Read Studio Philosophy</span>
|
||||
<ArrowUpRight className="w-3.5 h-3.5" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Product Spec Detail Modal */}
|
||||
<AnimatePresence>
|
||||
{selectedProduct && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6">
|
||||
{/* Backdrop */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
onClick={() => setSelectedProduct(null)}
|
||||
className="absolute inset-0 bg-black/80 backdrop-blur-xl"
|
||||
/>
|
||||
|
||||
{/* Modal Dialog */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
transition={{ duration: 0.25 }}
|
||||
className="relative w-full max-w-2xl bg-[#0e0e1c] border border-cyan-500/30 rounded-3xl p-6 sm:p-8 shadow-[0_0_60px_rgba(56,189,248,0.2)] max-h-[90vh] overflow-y-auto z-10 space-y-6"
|
||||
>
|
||||
{/* Close Button */}
|
||||
<button
|
||||
onClick={() => setSelectedProduct(null)}
|
||||
className="absolute top-6 right-6 p-2 rounded-full glass-panel text-slate-400 hover:text-white transition-colors"
|
||||
aria-label="Close modal"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
|
||||
{/* Header */}
|
||||
<div className="space-y-2 pr-8">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-[11px] font-mono tracking-widest uppercase px-2.5 py-0.5 rounded bg-cyan-500/20 border border-cyan-400/30 text-cyan-300">
|
||||
{selectedProduct.categoryLabel}
|
||||
</span>
|
||||
<span className="text-[11px] font-mono uppercase px-2.5 py-0.5 rounded bg-indigo-500/20 border border-indigo-400/30 text-indigo-300">
|
||||
{selectedProduct.status}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-2xl sm:text-3xl font-extrabold text-white font-mono">
|
||||
{selectedProduct.title}
|
||||
</h3>
|
||||
<p className="text-sm font-mono text-cyan-400">
|
||||
{selectedProduct.tagline}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Overview & Narrative */}
|
||||
<div className="space-y-3 pt-2 border-t border-white/10">
|
||||
<h4 className="text-xs font-mono uppercase tracking-wider text-slate-400">
|
||||
// PRODUCT MANIFESTO & PHILOSOPHY
|
||||
</h4>
|
||||
<p className="text-sm text-slate-300 leading-relaxed">
|
||||
{selectedProduct.longDescription}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Architectural Highlights */}
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-wider text-slate-400">
|
||||
// KEY ARCHITECTURAL CAPABILITIES
|
||||
</h4>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2.5">
|
||||
{selectedProduct.features.map((feat, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="p-3 rounded-xl bg-white/5 border border-white/10 text-xs text-slate-300 flex items-start gap-2"
|
||||
>
|
||||
<Sparkles className="w-3.5 h-3.5 text-cyan-400 shrink-0 mt-0.5" />
|
||||
<span>{feat}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tech Stack */}
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-xs font-mono uppercase tracking-wider text-slate-400">
|
||||
// COMPILED STACK & RUNTIME
|
||||
</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedProduct.stack.map((item) => (
|
||||
<span
|
||||
key={item}
|
||||
className="px-3 py-1 rounded-lg text-xs font-mono bg-indigo-950/40 border border-indigo-500/30 text-indigo-200"
|
||||
>
|
||||
{item}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer Meta */}
|
||||
<div className="pt-4 border-t border-white/10 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-2 text-xs font-mono text-slate-400">
|
||||
<Calendar className="w-4 h-4 text-cyan-400" />
|
||||
<span>Target Deployment: {selectedProduct.releaseTarget}</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setSelectedProduct(null)}
|
||||
className="w-full sm:w-auto px-6 py-2.5 rounded-xl text-xs font-mono uppercase tracking-wider font-semibold bg-cyan-400 text-slate-950 hover:bg-cyan-300 transition-colors"
|
||||
>
|
||||
Close Specification
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Volume2, VolumeX } from "lucide-react";
|
||||
|
||||
export default function CosmicAudioToggle() {
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const audioCtxRef = useRef<AudioContext | null>(null);
|
||||
const masterGainRef = useRef<GainNode | null>(null);
|
||||
const osc1Ref = useRef<OscillatorNode | null>(null);
|
||||
const osc2Ref = useRef<OscillatorNode | null>(null);
|
||||
|
||||
const toggleSound = () => {
|
||||
if (isPlaying) {
|
||||
if (masterGainRef.current && audioCtxRef.current) {
|
||||
masterGainRef.current.gain.setTargetAtTime(
|
||||
0,
|
||||
audioCtxRef.current.currentTime,
|
||||
0.5
|
||||
);
|
||||
setTimeout(() => {
|
||||
setIsPlaying(false);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const AudioCtx =
|
||||
window.AudioContext ||
|
||||
(window as unknown as { webkitAudioContext: typeof AudioContext })
|
||||
.webkitAudioContext;
|
||||
const ctx = audioCtxRef.current || new AudioCtx();
|
||||
audioCtxRef.current = ctx;
|
||||
|
||||
if (ctx.state === "suspended") {
|
||||
ctx.resume();
|
||||
}
|
||||
|
||||
const masterGain = ctx.createGain();
|
||||
masterGain.gain.setValueAtTime(0, ctx.currentTime);
|
||||
masterGain.gain.linearRampToValueAtTime(0.08, ctx.currentTime + 1.5);
|
||||
masterGain.connect(ctx.destination);
|
||||
masterGainRef.current = masterGain;
|
||||
|
||||
// Lowpass filter for deep cosmic drone
|
||||
const filter = ctx.createBiquadFilter();
|
||||
filter.type = "lowpass";
|
||||
filter.frequency.setValueAtTime(140, ctx.currentTime);
|
||||
filter.Q.setValueAtTime(2, ctx.currentTime);
|
||||
filter.connect(masterGain);
|
||||
|
||||
// Oscillator 1: 55Hz sub drone
|
||||
const osc1 = ctx.createOscillator();
|
||||
osc1.type = "sine";
|
||||
osc1.frequency.setValueAtTime(55, ctx.currentTime);
|
||||
osc1.connect(filter);
|
||||
osc1.start();
|
||||
osc1Ref.current = osc1;
|
||||
|
||||
// Oscillator 2: 110.2Hz warm harmonic with slight detune
|
||||
const osc2 = ctx.createOscillator();
|
||||
osc2.type = "triangle";
|
||||
osc2.frequency.setValueAtTime(110.3, ctx.currentTime);
|
||||
const osc2Gain = ctx.createGain();
|
||||
osc2Gain.gain.setValueAtTime(0.03, ctx.currentTime);
|
||||
osc2.connect(osc2Gain);
|
||||
osc2Gain.connect(filter);
|
||||
osc2.start();
|
||||
osc2Ref.current = osc2;
|
||||
|
||||
setIsPlaying(true);
|
||||
} catch {
|
||||
// Fallback gracefully if Web Audio is blocked
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (audioCtxRef.current && audioCtxRef.current.state !== "closed") {
|
||||
try {
|
||||
audioCtxRef.current.close();
|
||||
} catch {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleSound}
|
||||
title={isPlaying ? "Mute Deep Space Ambience" : "Enable Deep Space Ambience"}
|
||||
className="flex items-center gap-2 px-3 py-1.5 rounded-full glass-panel hover:border-indigo-500/40 text-xs font-mono tracking-wider text-slate-300 transition-all duration-300 hover:text-white group"
|
||||
aria-label="Toggle Cosmic Soundscape"
|
||||
>
|
||||
{isPlaying ? (
|
||||
<>
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-cyan-400 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-2 w-2 bg-cyan-500"></span>
|
||||
</span>
|
||||
<Volume2 className="w-3.5 h-3.5 text-cyan-400 group-hover:scale-110 transition-transform" />
|
||||
<span className="hidden sm:inline text-[11px] text-cyan-300">AUDIO: RESONANCE ON</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<VolumeX className="w-3.5 h-3.5 text-slate-400 group-hover:scale-110 transition-transform" />
|
||||
<span className="hidden sm:inline text-[11px] text-slate-400">AUDIO: VOID</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user