Загрузка...

Секция цен в стиле киберпанк: 3 интерактивные карточки, переключатель месяца/года, 3D-фон. Адаптивный дизайн на Tailwind CSS.
<div class="text-slate-200 antialiased min-h-screen flex flex-col items-center justify-center relative py-24 selection:bg-slate-500/20" style="font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; background: radial-gradient(circle at top center, #111827 0%, #020617 100%); overflow-x: hidden;">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<!-- Ambient Signal Flow Canvas -->
<div id="webgl-canvas" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 0; pointer-events: none; opacity: 1.0;"></div>
<div class="z-10 w-full max-w-6xl px-4 flex flex-col items-center">
<!-- Header -->
<div class="text-center mb-20 relative">
<h1 class="text-4xl md:text-5xl font-thin tracking-tight mb-10 text-white drop-shadow-sm">
Decentralized compute<br>for edge infrastructure
</h1>
<!-- Toggle -->
<div class="inline-flex items-center p-1 border border-slate-800/60 bg-slate-900/30 backdrop-blur-sm">
<button class="px-8 py-2.5 text-xs font-extralight tracking-wide text-white bg-slate-800/60 border border-slate-700/50 transition-all">
MONTHLY BILLING
</button>
<button class="px-8 py-2.5 text-xs font-extralight tracking-wide text-slate-500 hover:text-slate-300 transition-colors">
YEARLY COMMIT
</button>
</div>
</div>
<!-- Pricing Grid -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-6 w-full items-center relative z-10">
<!-- Background structural lines -->
<div class="absolute inset-0 pointer-events-none flex justify-center items-center opacity-40 z-0 hidden md:flex">
<div class="w-[800px] h-[800px] border border-slate-800/40 absolute"></div>
<div class="w-[600px] h-[600px] border border-slate-800/40 absolute"></div>
<div class="w-[1px] h-full bg-slate-800/40 absolute left-1/3"></div>
<div class="w-[1px] h-full bg-slate-800/40 absolute right-1/3"></div>
</div>
<!-- Card 1: Instance -->
<div class="relative p-8 pt-12 flex flex-col items-center text-center z-10 transition-all duration-500 hover:-translate-y-1 border border-slate-800/60 bg-slate-900/30 backdrop-blur-md group/card" onmousemove="window.updateMousePos(event, this)">
<!-- Flashlight Border Overlay -->
<div class="absolute inset-0 pointer-events-none opacity-0 group-hover/card:opacity-100 transition-opacity duration-300 z-50" style="padding: 1px; background: radial-gradient(400px circle at var(--mouse-x, 0px) var(--mouse-y, 0px), rgba(255,255,255,0.5) 0%, transparent 100%); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude;"></div>
<!-- Corner Indicators -->
<div class="absolute -top-[1px] -left-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<div class="absolute -top-[1px] -right-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<div class="absolute -bottom-[1px] -left-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<div class="absolute -bottom-[1px] -right-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<!-- Top Icon -->
<div class="absolute -top-6 left-1/2 -translate-x-1/2 w-12 h-12 flex items-center justify-center border border-slate-800/60 bg-slate-900 backdrop-blur-md group-hover/card:border-slate-600/60 transition-colors">
<div class="w-3 h-3 border border-slate-600 group-hover/card:border-slate-400 transition-colors"></div>
</div>
<span class="text-slate-400 text-xs font-extralight px-3 py-1 uppercase tracking-widest mb-6 border border-slate-800/60 group-hover/card:border-slate-700/60 transition-colors bg-slate-900/50">Instance</span>
<div class="flex items-baseline justify-center gap-1 mb-2">
<span class="text-5xl font-thin tracking-tight text-white">$25</span>
<span class="text-xs text-slate-500 font-extralight">/ MO</span>
</div>
<p class="text-sm text-slate-400 mb-8 font-extralight">For standalone micro-services</p>
<div class="w-full h-px mb-8 bg-gradient-to-r from-transparent via-slate-800/60 to-transparent group-hover/card:via-slate-700/60 transition-colors"></div>
<ul class="flex flex-col gap-4 w-full text-left mb-10">
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
25GB secure volume
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Standard REST endpoints
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Up to 4 parallel workers
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Basic observability
</li>
</ul>
<button class="mt-auto w-full py-3 transition-colors flex items-center justify-center gap-2 text-xs font-extralight tracking-wide group text-slate-300 hover:text-white border border-slate-800/60 hover:border-slate-700/60 hover:bg-slate-800/40 bg-slate-900/50">
<div class="w-1.5 h-1.5 border border-slate-500 group-hover:bg-slate-300 transition-colors"></div>
LAUNCH INSTANCE
</button>
</div>
<!-- Card 2: Swarm (Active) -->
<div class="relative p-8 pt-14 pb-12 md:-my-6 flex flex-col items-center text-center z-20 transition-all duration-500 hover:-translate-y-1 border border-slate-600/50 bg-slate-800/40 backdrop-blur-md hover:shadow-[0_0_40px_rgba(148,163,184,0.1)] group/card" onmousemove="window.updateMousePos(event, this)">
<!-- Flashlight Border Overlay -->
<div class="absolute inset-0 pointer-events-none opacity-0 group-hover/card:opacity-100 transition-opacity duration-300 z-50" style="padding: 1px; background: radial-gradient(400px circle at var(--mouse-x, 0px) var(--mouse-y, 0px), rgba(255,255,255,0.7) 0%, transparent 100%); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude;"></div>
<!-- Corner Indicators -->
<div class="absolute -top-[1px] -left-[1px] w-1 h-1 bg-slate-400/60"></div>
<div class="absolute -top-[1px] -right-[1px] w-1 h-1 bg-slate-400/60"></div>
<div class="absolute -bottom-[1px] -left-[1px] w-1 h-1 bg-slate-400/60"></div>
<div class="absolute -bottom-[1px] -right-[1px] w-1 h-1 bg-slate-400/60"></div>
<!-- Top Active Icon -->
<div class="absolute -top-7 left-1/2 -translate-x-1/2 w-14 h-14 flex items-center justify-center z-30 border border-slate-600/60 bg-slate-900 group-hover/card:border-slate-500/60 transition-colors shadow-[0_0_15px_rgba(148,163,184,0.15)]">
<div class="w-4 h-4 bg-slate-400/80 group-hover/card:bg-slate-300 transition-colors shadow-[0_0_10px_rgba(148,163,184,0.4)]"></div>
</div>
<span class="text-slate-300 bg-slate-800/40 text-xs font-extralight px-4 py-1.5 uppercase tracking-widest mb-6 border border-slate-700/50">Swarm</span>
<div class="flex items-baseline justify-center gap-1 mb-2">
<span class="text-6xl font-thin tracking-tight text-white drop-shadow-sm">$85</span>
<span class="text-xs text-slate-400 font-extralight">/ MO</span>
</div>
<p class="text-sm text-slate-300/70 mb-8 font-extralight">Tuned for parallel workloads</p>
<div class="w-full h-px mb-8 bg-gradient-to-r from-transparent via-slate-600/50 to-transparent"></div>
<ul class="flex flex-col gap-4 w-full text-left mb-10">
<li class="flex items-center gap-3 text-sm font-extralight text-white">
<div class="flex items-center justify-center text-slate-400 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
All Instance capabilities
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-white">
<div class="flex items-center justify-center text-slate-400 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
5TB decentralized storage
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-white">
<div class="flex items-center justify-center text-slate-400 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Uncapped worker threads
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-white">
<div class="flex items-center justify-center text-slate-400 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Distributed tracing
</li>
</ul>
<button class="mt-auto w-full py-3.5 transition-all flex items-center justify-center gap-2 text-xs font-extralight tracking-wide text-slate-200 bg-slate-800/60 hover:bg-slate-700/60 border border-slate-600/60 hover:border-slate-400/60 shadow-[0_0_10px_rgba(148,163,184,0.05)]">
<div class="w-1.5 h-1.5 bg-slate-400"></div>
START SWARM
</button>
<div class="absolute -bottom-10 left-1/2 -translate-x-1/2 text-xs text-slate-500/60 tracking-widest uppercase whitespace-nowrap font-extralight">
- PREFERRED TOPOLOGY -
</div>
</div>
<!-- Card 3: Network -->
<div class="relative p-8 pt-12 flex flex-col items-center text-center z-10 transition-all duration-500 hover:-translate-y-1 border border-slate-800/60 bg-slate-900/30 backdrop-blur-md group/card" onmousemove="window.updateMousePos(event, this)">
<!-- Flashlight Border Overlay -->
<div class="absolute inset-0 pointer-events-none opacity-0 group-hover/card:opacity-100 transition-opacity duration-300 z-50" style="padding: 1px; background: radial-gradient(400px circle at var(--mouse-x, 0px) var(--mouse-y, 0px), rgba(255,255,255,0.5) 0%, transparent 100%); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude;"></div>
<!-- Corner Indicators -->
<div class="absolute -top-[1px] -left-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<div class="absolute -top-[1px] -right-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<div class="absolute -bottom-[1px] -left-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<div class="absolute -bottom-[1px] -right-[1px] w-1 h-1 bg-slate-600/50 opacity-0 group-hover/card:opacity-100 transition-opacity"></div>
<!-- Top Icon -->
<div class="absolute -top-6 left-1/2 -translate-x-1/2 w-12 h-12 flex items-center justify-center border border-slate-800/60 bg-slate-900 backdrop-blur-md group-hover/card:border-slate-600/60 transition-colors">
<div class="w-3 h-3 border border-slate-600 flex items-center justify-center group-hover/card:border-slate-400 transition-colors">
<div class="w-1 h-1 bg-slate-600 group-hover/card:bg-slate-400 transition-colors"></div>
</div>
</div>
<span class="text-slate-400 text-xs font-extralight px-3 py-1 uppercase tracking-widest mb-6 border border-slate-800/60 group-hover/card:border-slate-700/60 transition-colors bg-slate-900/50">Network</span>
<div class="flex items-baseline justify-center gap-1 mb-2">
<span class="text-5xl font-thin tracking-tight text-white">$180</span>
<span class="text-xs text-slate-500 font-extralight">/ MO</span>
</div>
<p class="text-sm text-slate-400 mb-8 font-extralight">For global-scale operations</p>
<div class="w-full h-px mb-8 bg-gradient-to-r from-transparent via-slate-800/60 to-transparent group-hover/card:via-slate-700/60 transition-colors"></div>
<ul class="flex flex-col gap-4 w-full text-left mb-10">
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
All Swarm capabilities
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Infinite secure storage
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Dynamic request routing
</li>
<li class="flex items-center gap-3 text-sm font-extralight text-slate-300">
<div class="flex items-center justify-center text-slate-500 shrink-0"><iconify-icon icon="solar:check-square-linear" width="16" style="stroke-width: 1.5;"></iconify-icon></div>
Dedicated bandwidth
</li>
</ul>
<button class="mt-auto w-full py-3 transition-colors flex items-center justify-center gap-2 text-xs font-extralight tracking-wide group text-slate-300 hover:text-white border border-slate-800/60 hover:border-slate-700/60 hover:bg-slate-800/40 bg-slate-900/50">
<div class="w-1.5 h-1.5 bg-slate-600 group-hover:bg-slate-300 transition-colors"></div>
DEPLOY NETWORK
</button>
</div>
</div>
</div>
<script>
window.updateMousePos = (e, el) => {
const rect = el.getBoundingClientRect();
el.style.setProperty('--mouse-x', `${e.clientX - rect.left}px`);
el.style.setProperty('--mouse-y', `${e.clientY - rect.top}px`);
};
const initWebGL = () => {
const container = document.getElementById('webgl-canvas');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
container.appendChild(renderer.domElement);
const interactiveGroup = new THREE.Group();
scene.add(interactiveGroup);
const group = new THREE.Group();
interactiveGroup.add(group);
scene.add(new THREE.AmbientLight(0xffffff, 0.2));
const pointLight = new THREE.PointLight(0x64748b, 2.0, 50);
pointLight.position.set(5, 15, 5);
scene.add(pointLight);
const particlesGeo = new THREE.BufferGeometry();
const particlesCount = 6000;
const posArray = new Float32Array(particlesCount * 3);
const basePosArray = new Float32Array(particlesCount * 3);
const colorsArray = new Float32Array(particlesCount * 3);
const velocities = new Float32Array(particlesCount * 3);
for(let i = 0; i < particlesCount * 3; i+=3) {
const radius = 4.0 + Math.random() * 0.3;
const u = Math.random(), v = Math.random();
const theta = 2 * Math.PI * u, phi = Math.acos(2 * v - 1);
const x = radius * Math.sin(phi) * Math.cos(theta);
const y = radius * Math.sin(phi) * Math.sin(theta);
const z = radius * Math.cos(phi);
posArray[i] = x; posArray[i+1] = y; posArray[i+2] = z;
basePosArray[i] = x; basePosArray[i+1] = y; basePosArray[i+2] = z;
colorsArray[i] = 0.4; colorsArray[i+1] = 0.45; colorsArray[i+2] = 0.5;
}
particlesGeo.setAttribute('position', new THREE.BufferAttribute(posArray, 3));
particlesGeo.setAttribute('color', new THREE.BufferAttribute(colorsArray, 3));
const particlesMat = new THREE.PointsMaterial({
size: 0.025,
vertexColors: true,
transparent: true,
opacity: 0.9,
blending: THREE.AdditiveBlending
});
const particlesMesh = new THREE.Points(particlesGeo, particlesMat);
group.add(particlesMesh);
const createRing = (radius, rotationX, rotationY) => {
const geometry = new THREE.TorusGeometry(radius, 0.0015, 16, 120);
const material = new THREE.MeshBasicMaterial({ color: 0x1e293b, transparent: true, opacity: 0.4 });
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x = rotationX; mesh.rotation.y = rotationY;
return mesh;
};
group.add(createRing(4.4, Math.PI / 2, 0));
group.add(createRing(4.7, Math.PI / 4, Math.PI / 4));
group.add(createRing(5.0, -Math.PI / 4, Math.PI / 6));
camera.position.z = 8.5;
camera.position.y = 1.0;
camera.lookAt(0, 0, 0);
let mouseX = 0, mouseY = 0, explodeFactor = 0;
document.addEventListener('mousemove', (event) => {
mouseX = (event.clientX / window.innerWidth) * 2 - 1;
mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
});
document.addEventListener('click', () => { explodeFactor = 1.2; });
const animate = () => {
requestAnimationFrame(animate);
group.rotation.y += 0.0008; group.rotation.x += 0.0004;
interactiveGroup.rotation.x += (mouseY * 0.08 - interactiveGroup.rotation.x) * 0.02;
interactiveGroup.rotation.y += (mouseX * 0.08 - interactiveGroup.rotation.y) * 0.02;
explodeFactor *= 0.92;
const positions = particlesGeo.attributes.position.array;
const colors = particlesGeo.attributes.color.array;
const mx = mouseX * 5.0, my = mouseY * 5.0;
for(let i = 0; i < particlesCount * 3; i+=3) {
const ox = basePosArray[i], oy = basePosArray[i+1], oz = basePosArray[i+2];
let cx = positions[i], cy = positions[i+1], cz = positions[i+2];
let tx = ox, ty = oy, tz = oz;
const dx = cx - mx, dy = cy - my;
const distSq = dx*dx + dy*dy;
if (distSq < 3.0) {
const force = (3.0 - distSq) * 0.3;
tx += dx * force; ty += dy * force; tz += (cz > 0 ? 1 : -1) * force;
}
if (explodeFactor > 0.01) {
const len = Math.sqrt(ox*ox + oy*oy + oz*oz);
const expForce = explodeFactor * 2.5;
tx += (ox / len) * expForce; ty += (oy / len) * expForce; tz += (oz / len) * expForce;
}
velocities[i] += (tx - cx) * 0.08; velocities[i+1] += (ty - cy) * 0.08; velocities[i+2] += (tz - cz) * 0.08;
velocities[i] *= 0.75; velocities[i+1] *= 0.75; velocities[i+2] *= 0.75;
positions[i] += velocities[i]; positions[i+1] += velocities[i+1]; positions[i+2] += velocities[i+2];
let b = 0.2;
if (distSq < 15.0) b += (15.0 - distSq) * 0.06;
if (b > 1.0) b = 1.0;
colors[i] = b * 0.8; colors[i+1] = b * 0.95; colors[i+2] = b;
}
particlesGeo.attributes.position.needsUpdate = true;
particlesGeo.attributes.color.needsUpdate = true;
renderer.render(scene, camera);
};
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
};
document.addEventListener('DOMContentLoaded', initWebGL);
</script>
</div>