Web Pages Hard
Ciber Portfolio
A cyberpunk-inspired portfolio website featuring neon city grid background with Three.js, scroll-velocity reactive effects, and immersive cyberpunk aesthetics with neon colors and motion systems.
Open in Lab
MCP
html css javascript threejs gsap lenis webgl
Targets: JS HTML
Code
:root {
color-scheme: dark;
--bg: #07060d;
--panel: rgba(12, 10, 20, 0.85);
--stroke: rgba(255, 255, 255, 0.12);
--text: #f6f1ff;
--muted: rgba(246, 241, 255, 0.6);
--neon-cyan: #2af1ff;
--neon-pink: #ff38c7;
--neon-yellow: #ffe14d;
--neon-purple: #8b4dff;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
font-family: "Rajdhani", sans-serif;
color: var(--text);
background: radial-gradient(circle at 10% 15%, rgba(42, 241, 255, 0.2), transparent 55%),
radial-gradient(circle at 90% 10%, rgba(255, 56, 199, 0.18), transparent 55%),
radial-gradient(circle at 20% 80%, rgba(255, 225, 77, 0.18), transparent 60%), #05040a;
overflow-x: hidden;
}
a {
color: inherit;
text-decoration: none;
}
#cyber-bg {
position: fixed;
inset: 0;
z-index: 0;
}
.noise {
position: fixed;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.2'/%3E%3C/svg%3E");
opacity: 0.25;
mix-blend-mode: screen;
pointer-events: none;
z-index: 1;
}
.scan {
position: fixed;
inset: 0;
background: repeating-linear-gradient(
180deg,
rgba(255, 255, 255, 0.04) 0,
rgba(255, 255, 255, 0.04) 1px,
transparent 1px,
transparent 4px
);
opacity: 0.35;
pointer-events: none;
z-index: 1;
transform: translateY(var(--scan-shift, 0px));
}
.header {
position: sticky;
top: 0;
z-index: 5;
display: flex;
justify-content: space-between;
align-items: center;
padding: 24px clamp(20px, 6vw, 80px);
background: rgba(6, 6, 12, 0.85);
backdrop-filter: blur(16px);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.brand {
display: flex;
align-items: center;
gap: 16px;
}
.sig {
width: 48px;
height: 48px;
border-radius: 12px;
background: linear-gradient(140deg, var(--neon-cyan), var(--neon-pink));
display: grid;
place-items: center;
color: #05040a;
font-family: "Oxanium", sans-serif;
font-weight: 700;
}
.brand-title {
margin: 0;
font-family: "Oxanium", sans-serif;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.brand-sub {
margin: 4px 0 0;
color: var(--muted);
font-size: 0.9rem;
}
.nav {
display: flex;
align-items: center;
gap: 20px;
text-transform: uppercase;
letter-spacing: 0.2em;
font-size: 0.65rem;
}
.nav a {
color: var(--muted);
}
.nav-cta {
padding: 0.5rem 1.1rem;
border-radius: 999px;
border: 1px solid rgba(255, 56, 199, 0.5);
background: rgba(255, 56, 199, 0.15);
color: var(--text);
}
.page {
position: relative;
z-index: 2;
padding: 0 clamp(20px, 6vw, 80px) 80px;
}
.hero {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 40px;
padding: 80px 0 40px;
}
.eyebrow {
font-family: "Oxanium", sans-serif;
letter-spacing: 0.4em;
text-transform: uppercase;
font-size: 0.7rem;
color: var(--neon-yellow);
}
.hero-copy h1 {
font-family: "Oxanium", sans-serif;
font-size: clamp(2.6rem, 5vw, 4.6rem);
margin: 16px 0;
}
.lead {
color: var(--muted);
line-height: 1.7;
max-width: 55ch;
}
.hero-actions {
display: flex;
gap: 14px;
margin-top: 24px;
flex-wrap: wrap;
}
.btn {
padding: 0.85rem 1.6rem;
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, 0.2);
background: transparent;
color: var(--text);
text-transform: uppercase;
letter-spacing: 0.18em;
font-size: 0.65rem;
cursor: pointer;
}
.btn.primary {
background: linear-gradient(120deg, rgba(42, 241, 255, 0.25), rgba(139, 77, 255, 0.4));
border-color: rgba(42, 241, 255, 0.6);
}
.btn.ghost {
border-color: rgba(255, 225, 77, 0.5);
}
.hero-stats {
margin-top: 24px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px;
}
.hero-stats div {
background: var(--panel);
border: 1px solid var(--stroke);
border-radius: 14px;
padding: 14px;
}
.hero-stats span {
display: block;
color: var(--muted);
font-size: 0.8rem;
}
.hero-panel {
display: grid;
gap: 18px;
}
.panel-card {
background: var(--panel);
border: 1px solid rgba(255, 56, 199, 0.2);
border-radius: 18px;
padding: 20px;
box-shadow: 0 0 30px rgba(255, 56, 199, 0.1);
}
.panel-title {
text-transform: uppercase;
letter-spacing: 0.25em;
font-size: 0.65rem;
color: var(--muted);
}
.ticker {
margin-top: 10px;
overflow: hidden;
border-top: 1px solid rgba(255, 255, 255, 0.08);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.ticker-track {
display: flex;
gap: 48px;
padding: 16px 0;
text-transform: uppercase;
letter-spacing: 0.35em;
font-family: "Oxanium", sans-serif;
font-size: 0.65rem;
color: var(--muted);
white-space: nowrap;
}
.section {
padding: 64px 0;
}
.section-header {
display: flex;
justify-content: space-between;
gap: 24px;
align-items: baseline;
}
.section-header p {
color: var(--muted);
}
.cards {
display: grid;
gap: 24px;
margin-top: 28px;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.card {
padding: 22px;
border-radius: 18px;
background: rgba(8, 10, 18, 0.85);
border: 1px solid rgba(42, 241, 255, 0.15);
box-shadow: 0 0 25px rgba(42, 241, 255, 0.12);
}
.card-tag {
font-family: "Oxanium", sans-serif;
letter-spacing: 0.3em;
font-size: 0.7rem;
color: var(--neon-yellow);
}
.card p {
color: var(--muted);
line-height: 1.6;
}
.card-meta {
display: flex;
justify-content: space-between;
font-size: 0.85rem;
color: var(--muted);
}
.split {
display: grid;
gap: 28px;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.panel {
padding: 26px;
background: rgba(10, 12, 20, 0.8);
border-radius: 18px;
border: 1px solid rgba(255, 56, 199, 0.18);
}
.panel ul {
margin: 16px 0 0;
padding-left: 18px;
color: var(--muted);
line-height: 1.7;
}
.chips {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 18px;
}
.chips span {
padding: 0.45rem 0.9rem;
border-radius: 999px;
border: 1px solid rgba(42, 241, 255, 0.35);
font-size: 0.75rem;
}
.stats {
display: grid;
gap: 24px;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
text-align: center;
}
.stats h2 {
font-family: "Oxanium", sans-serif;
font-size: 2.4rem;
margin: 0 0 8px;
color: var(--neon-cyan);
}
.lab-grid {
display: grid;
gap: 18px;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.lab-card {
padding: 18px;
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(8, 10, 18, 0.85);
}
.contact {
display: grid;
gap: 32px;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.contact-form {
display: grid;
gap: 16px;
}
.contact-form input,
.contact-form textarea {
background: rgba(6, 8, 14, 0.8);
border: 1px solid rgba(42, 241, 255, 0.2);
border-radius: 12px;
padding: 12px 14px;
color: var(--text);
font-size: 0.95rem;
}
.contact-form input:focus,
.contact-form textarea:focus {
outline: none;
border-color: var(--neon-cyan);
box-shadow: 0 0 18px rgba(42, 241, 255, 0.3);
}
@media (max-width: 900px) {
.header {
flex-direction: column;
align-items: flex-start;
}
.nav {
flex-wrap: wrap;
}
}
@media (max-width: 640px) {
.page {
padding: 0 18px 80px;
}
}const lenis = window.Lenis
? new Lenis({
smoothWheel: true,
smoothTouch: false,
lerp: 0.08,
})
: null;
const projects = [
{
id: "01",
title: "Night City Grid",
copy: "Realtime city telemetry dashboard with adaptive neon layers.",
tags: ["UI/UX", "2026"],
},
{
id: "02",
title: "Ghostwire Relay",
copy: "Cyberpunk launch site with kinetic typography and motion gates.",
tags: ["WebGL", "2025"],
},
{
id: "03",
title: "Synapse Archive",
copy: "Data storytelling interface for biotech intelligence.",
tags: ["Brand", "2025"],
},
{
id: "04",
title: "Signal Loom",
copy: "Identity system with neon typography and modular UI kits.",
tags: ["System", "2024"],
},
];
const abilities = [
"Realtime HUD systems",
"Motion-first UI choreography",
"Neon brand systems",
"3D dashboards and data overlays",
];
const skills = ["Figma", "Three.js", "GSAP", "Lenis", "WebGL", "TypeScript", "Framer"];
const stats = [
{ value: "12", label: "Years crafting motion-forward narratives." },
{ value: "38", label: "Launches for cyber-native brands." },
{ value: "94%", label: "Repeat collaboration rate." },
];
const lab = [
{ title: "Drift Ticker", desc: "Marquee speed reacts to Lenis velocity." },
{ title: "Neon Pulse", desc: "Ambient glow synced to scroll momentum." },
{ title: "City Grid", desc: "3D skyline driven by motion signals." },
];
const projectGrid = document.getElementById("project-cards");
const abilityList = document.getElementById("abilities-list");
const skillChips = document.getElementById("skill-chips");
const statsGrid = document.getElementById("stats-grid");
const labGrid = document.getElementById("lab-grid");
if (projectGrid) {
projectGrid.innerHTML = projects
.map(
(project) => `
<article class="card">
<div class="card-tag">${project.id}</div>
<h3>${project.title}</h3>
<p>${project.copy}</p>
<div class="card-meta">
<span>${project.tags[0]}</span>
<span>${project.tags[1]}</span>
</div>
</article>
`
)
.join("");
}
if (abilityList) {
abilityList.innerHTML = abilities.map((item) => `<li>${item}</li>`).join("");
}
if (skillChips) {
skillChips.innerHTML = skills.map((skill) => `<span>${skill}</span>`).join("");
}
if (statsGrid) {
statsGrid.innerHTML = stats
.map(
(stat) => `
<div>
<h2>${stat.value}</h2>
<p>${stat.label}</p>
</div>
`
)
.join("");
}
if (labGrid) {
labGrid.innerHTML = lab
.map(
(item) => `
<article class="lab-card">
<h3>${item.title}</h3>
<p>${item.desc}</p>
</article>
`
)
.join("");
}
let scrollVelocity = 0;
let tickerX = 0;
const tickerTrack = document.getElementById("tickerTrack");
function raf(time) {
if (lenis) lenis.raf(time);
scrollVelocity *= 0.9;
document.documentElement.style.setProperty("--scan-shift", `${scrollVelocity * 0.6}px`);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
if (lenis) {
lenis.on("scroll", ({ velocity }) => {
scrollVelocity = Math.max(Math.min(velocity, 40), -40);
});
}
if (tickerTrack) {
const loop = () => {
tickerX -= 0.35 + Math.abs(scrollVelocity) * 0.02;
tickerTrack.style.transform = `translateX(${tickerX}px)`;
if (Math.abs(tickerX) > tickerTrack.scrollWidth / 2) {
tickerX = 0;
}
requestAnimationFrame(loop);
};
loop();
}
if (window.gsap) {
gsap.from(".hero-copy", { opacity: 0, y: 30, duration: 1, ease: "power3.out" });
gsap.from(".hero-panel", { opacity: 0, x: 30, duration: 1, delay: 0.15, ease: "power3.out" });
gsap.utils.toArray(".card, .panel, .chips span, .stats div, .lab-card").forEach((item, index) => {
gsap.from(item, {
opacity: 0,
y: 24,
duration: 0.8,
delay: index * 0.04,
ease: "power2.out",
});
});
}
class NeonCity {
constructor(container) {
this.container = container;
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 200);
this.camera.position.set(0, 8, 24);
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
container.appendChild(this.renderer.domElement);
this.clock = new THREE.Clock();
this.city = new THREE.Group();
this.scene.add(this.city);
this.addLights();
this.buildGrid();
this.buildCity();
this.buildParticles();
this.bindEvents();
this.animate();
}
addLights() {
this.scene.add(new THREE.AmbientLight(0x8b4dff, 0.4));
const key = new THREE.DirectionalLight(0x2af1ff, 0.8);
key.position.set(10, 20, 10);
this.scene.add(key);
const rim = new THREE.DirectionalLight(0xff38c7, 0.6);
rim.position.set(-10, 8, -10);
this.scene.add(rim);
}
buildGrid() {
const size = 120;
const divisions = 30;
const grid = new THREE.GridHelper(size, divisions, 0x2af1ff, 0x2af1ff);
grid.material.opacity = 0.2;
grid.material.transparent = true;
grid.position.y = -2;
this.scene.add(grid);
}
buildCity() {
const blockMat = new THREE.MeshStandardMaterial({
color: 0x110b1f,
roughness: 0.4,
metalness: 0.6,
emissive: 0x2af1ff,
emissiveIntensity: 0.2,
});
for (let i = 0; i < 80; i++) {
const w = 0.6 + Math.random() * 1.4;
const h = 1 + Math.random() * 8;
const d = 0.6 + Math.random() * 1.4;
const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), blockMat.clone());
mesh.position.set((Math.random() - 0.5) * 30, h / 2 - 2, (Math.random() - 0.5) * 30);
mesh.material.emissiveIntensity = 0.2 + Math.random() * 0.6;
this.city.add(mesh);
}
}
buildParticles() {
const count = 220;
const positions = new Float32Array(count * 3);
for (let i = 0; i < count; i++) {
positions[i * 3] = (Math.random() - 0.5) * 40;
positions[i * 3 + 1] = Math.random() * 18;
positions[i * 3 + 2] = (Math.random() - 0.5) * 40;
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
const material = new THREE.PointsMaterial({ color: 0xff38c7, size: 0.08 });
this.particles = new THREE.Points(geometry, material);
this.scene.add(this.particles);
}
bindEvents() {
window.addEventListener("resize", () => this.onResize());
}
onResize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
animate() {
const t = this.clock.getElapsedTime();
const drift = scrollVelocity * 0.004;
this.city.rotation.y = t * 0.05 + drift;
this.city.position.z = Math.sin(t * 0.2) * 1.2;
this.particles.rotation.y = t * 0.08;
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(() => this.animate());
}
}
const bg = document.getElementById("cyber-bg");
if (bg && window.THREE) {
new NeonCity(bg);
}<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>CiberPulse 2077 Portfolio</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Oxanium:wght@300;400;600;700&family=Rajdhani:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="cyber-bg"></div>
<div class="noise" aria-hidden="true"></div>
<div class="scan" aria-hidden="true"></div>
<header class="header">
<div class="brand">
<span class="sig">CP</span>
<div>
<p class="brand-title">CiberPulse 2077</p>
<p class="brand-sub">Neon interface architect</p>
</div>
</div>
<nav class="nav">
<a href="#work">Work</a>
<a href="#abilities">Abilities</a>
<a href="#lab">Lab</a>
<a href="#contact" class="nav-cta">Contact</a>
</nav>
</header>
<main class="page">
<section class="hero">
<div class="hero-copy">
<p class="eyebrow">Night City Ops</p>
<h1>Neon systems, brutal clarity, and motion that never sleeps.</h1>
<p class="lead">
Cyberpunk-inspired product designer building tactical UI, kinetic brand systems, and
immersive dashboards. Lenis drives the drift. Three.js powers the neon city grid.
</p>
<div class="hero-actions">
<button class="btn primary">Jack In</button>
<button class="btn ghost">Download Creds</button>
</div>
<div class="hero-stats">
<div>
<span>Reputation</span>
<strong>98.4%</strong>
</div>
<div>
<span>Deploys</span>
<strong>64</strong>
</div>
<div>
<span>Signal</span>
<strong>Night Ops</strong>
</div>
</div>
</div>
<aside class="hero-panel">
<div class="panel-card">
<p class="panel-title">Active Contract</p>
<h3>Ghostwire Console</h3>
<p>Realtime command UI with tactical overlays and biometric sync.</p>
</div>
<div class="panel-card">
<p class="panel-title">Availability</p>
<h3>June → Sep 2026</h3>
<p>Focused partnerships for high-stakes launches.</p>
</div>
</aside>
</section>
<section class="ticker" aria-hidden="true">
<div class="ticker-track" id="tickerTrack">
<span>Lenis Drift Protocol</span>
<span>Neon Grid Engine</span>
<span>GSAP Motion Pass</span>
<span>Cyberpunk 2077 Interface</span>
</div>
</section>
<section class="section" id="work">
<div class="section-header">
<h2>Selected Work</h2>
<p>High-voltage systems for future-forward teams.</p>
</div>
<div class="cards" id="project-cards"></div>
</section>
<section class="section split" id="abilities">
<div class="panel">
<h2>Abilities</h2>
<ul id="abilities-list"></ul>
</div>
<div class="panel">
<h2>Neural Stack</h2>
<div class="chips" id="skill-chips"></div>
</div>
</section>
<section class="section stats" id="stats-grid"></section>
<section class="section" id="lab">
<div class="section-header">
<h2>Neon Lab</h2>
<p>Experiments synced to scroll velocity.</p>
</div>
<div class="lab-grid" id="lab-grid"></div>
</section>
<section class="section contact" id="contact">
<div>
<h2>Contact</h2>
<p>Need a new interface for the city? Send the signal.</p>
</div>
<form class="contact-form">
<input type="text" placeholder="Name" />
<input type="email" placeholder="Email" />
<textarea rows="4" placeholder="Project Brief"></textarea>
<button class="btn primary" type="button">Transmit</button>
</form>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/@studio-freight/lenis@1.0.42/bundled/lenis.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.min.js"></script>
<script src="script.js"></script>
</body>
</html>Ciber Portfolio
A cyberpunk-inspired portfolio website featuring a neon city grid background rendered in Three.js. The site includes scroll-velocity reactive effects, animated ticker, scan lines, and immersive cyberpunk aesthetics with neon cyan, pink, yellow, and purple color schemes.
How it works
The portfolio combines cyberpunk design with advanced web technologies:
- Three.js Neon City — 3D city grid with neon-lit buildings and particles
- Scroll Velocity Tracking — Lenis tracks scroll velocity to drive animations
- Reactive Effects — Scan lines and ticker speed react to scroll velocity
- Neon Aesthetics — Cyberpunk color palette with neon accents
- Motion Systems — GSAP animations for smooth transitions
Key features
- Three.js neon city background with 3D buildings
- Scroll-velocity reactive animations
- Animated ticker that speeds up with scroll
- Scan line effects synced to scroll
- Cyberpunk neon color scheme
- Noise texture overlay for authentic feel
- Smooth scroll with Lenis
- GSAP-powered animations
Technical details
The Three.js scene includes:
- Procedurally generated city blocks with neon emissive materials
- Particle system for atmospheric effects
- Grid helper for depth perception
- Dynamic lighting with neon colors
- Scroll-velocity driven rotation and movement
When to use it
- Cyberpunk-themed portfolios
- Game developer showcases
- Futuristic brand experiences
- Tech product presentations
- Creative developer portfolios
- Immersive web experiences