Open
Description
Desired Behavior
A new card component can be created to be used in a couple of different section on the site. The HTML code is attached below.
Screen.Recording.2025-05-25.at.9.49.34.AM.mov
Code
HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Meshery Schemas</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: { geist: ['Geist', 'sans-serif'] },
animation: {
'float': 'float 6s ease-in-out infinite',
'data-stream': 'dataStream 3s linear infinite',
'schema-pulse': 'schemaPulse 4s ease-in-out infinite',
},
keyframes: {
float: {
'0%, 100%': { transform: 'translateY(0px)' },
'50%': { transform: 'translateY(-10px)' }
},
dataStream: {
'0%': { strokeDashoffset: 20 },
'100%': { strokeDashoffset: 0 }
},
schemaPulse: {
'0%, 100%': { transform: 'scale(1)', opacity: 0.8 },
'50%': { transform: 'scale(1.03)', opacity: 1 }
}
}
}
}
}
</script>
<style>
.glass {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
.connector {
stroke-dasharray: 8;
animation: dataStream 2s linear infinite;
}
.table-float {
animation: float 6s ease-in-out infinite;
}
.table-float:nth-child(2) { animation-delay: -1s; }
.table-float:nth-child(3) { animation-delay: -2s; }
.table-float:nth-child(4) { animation-delay: -3s; }
.gradient-border {
position: relative;
background: linear-gradient(135deg, rgba0, 179, 159, 0.1), rgba(59, 130, 246, 0.1), rgba(0, 211, 169, 0.1);
}
.gradient-border::before {
content: '';
position: absolute;
inset: 0;
padding: 2px;
background: linear-gradient(135deg, #EBC017, #477E96, #477E96, #EBC017);
border-radius: inherit;
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
mask-composite: xor;
-webkit-mask-composite: xor;
}
.inner-glow {
box-shadow:
inset 0 0 20px rgba(0, 179, 159, 0.3),
inset 0 0 40px rgba(59, 130, 246, 0.2),
0 0 30px rgba(0, 211, 169, 0.4);
}
.card-border {
background: rgba(0, 179, 159, 0.08);
border: 1px solid rgba(0, 179, 159, 0.3);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
box-shadow:
0 0 0 1px rgba(0, 179, 159, 0.3),
inset 0 0 30px rgba(0, 179, 159, 0.1),
inset 0 0 60px rgba(0, 211, 169, 0.05),
0 0 50px rgba(0, 211, 169, 0.2);
}
</style>
</head>
<body class="bg-black m-0 p-0 overflow-hidden h-screen w-screen font-geist">
<!-- Wave Visualizer Background -->
<canvas id="visualizer" class="fixed inset-0 w-full h-full"></canvas>
<!-- Glass Database Card -->
<div class="fixed inset-0 flex items-center justify-center p-4 z-10">
<div class="w-full relative max-w-xs">
<!-- Card content -->
<div class="relative card-border overflow-hidden rounded-2xl flex flex-col animate-float">
<!-- Database Schema Preview -->
<div class="p-4 flex justify-center relative">
<div class="w-full h-48 rounded-xl gradient-border inner-glow overflow-hidden relative">
<!-- Animated grid background -->
<div class="absolute inset-0 opacity-10">
<div class="w-full h-full animate-pulse" style="background-image: linear-gradient(90deg, rgba(255,255,255,0.3) 1px, transparent 1px), linear-gradient(rgba(255,255,255,0.3) 1px, transparent 1px); background-size: 15px 15px;"></div>
</div>
<!-- Database connections -->
<svg class="absolute inset-0 w-full h-full pointer-events-none" viewBox="0 0 320 180">
<defs>
<linearGradient id="connectionGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#4f46e5;stop-opacity:0.8" />
<stop offset="50%" style="stop-color:#00b39f;stop-opacity:1" />
<stop offset="100%" style="stop-color:#8b5cf6;stop-opacity:0.8" />
</linearGradient>
</defs>
<g stroke="url(#connectionGradient)" stroke-width="1.5" fill="none">
<!-- Primary data flow -->
<path class="connector animate-pulse" d="M75,40 L140,60 L140,90 L200,90" />
<path class="connector animate-pulse" d="M225,90 L240,90 L240,60 L240,60" />
<path class="connector animate-pulse" d="M140,90 L140,120 L220,120" />
<path class="connector animate-pulse" d="M225,120 L240,120 L240,150 L220,150" />
<!-- Connection nodes -->
<circle cx="75" cy="40" r="3" fill="#4f46e5"/>
<circle cx="225" cy="90" r="3" fill="#3b82f6"/>
<circle cx="245" cy="60" r="3" fill="#8b5cf6"/>
<circle cx="225" cy="120" r="3" fill="#f59e0b"/>
<circle cx="225" cy="150" r="3" fill="#ef4444"/>
</g>
</svg>
<!-- Animated Database Tables -->
<div class="absolute inset-0 w-full h-full">
<!-- Kanvas icon hub -->
<div class="absolute bottom-2 left-2 transform -translate-x-1/2 animate-schema-pulse">
<div class="w-8 h-8 glass rounded-xl flex items-center justify-center border border-indigo-400/30 inner-glow">
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<defs><style>
.cls-1 {fill: #00b39f;}
.cls-2 {fill: #00d3a9;}
</style></defs>
<polygon class="cls-2" points="261.82 30.1 261.82 228.75 433.99 129.07 261.82 30.1"/>
<polygon class="cls-2" points="261.82 270.3 261.82 469.9 435.56 370.56 261.82 270.3"/>
<polygon class="cls-1" points="237.03 227.38 237.03 31.77 66.97 129.25 237.03 227.38"/>
<polygon class="cls-1" points="237.03 468.98 237.03 271.74 66.56 370.43 237.03 468.98"/>
<polygon class="cls-1" points="447.37 348.75 447.37 149.97 275.4 249.52 447.37 348.75"/>
<polygon class="cls-2" points="52.63 149.59 52.63 349.85 225.87 249.56 52.63 149.59"/>
</svg>
</div>
</div>
<!-- Floating table cards -->
<div class="absolute left-3 top-12 table-float">
<div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
<div class="bg-gradient-to-r from-indigo-500/20 to-blue-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">designs</div>
<div class="px-1.5 py-0.5 space-y-0.5">
<div class="flex items-center space-x-0.5">
<div class="w-1 h-1 bg-yellow-400 rounded-full"></div>
<div class="h-0.5 w-6 bg-white/30 rounded"></div>
</div>
<div class="h-0.5 w-4 bg-white/20 rounded"></div>
<div class="h-0.5 w-7 bg-white/20 rounded"></div>
</div>
</div>
</div>
<div class="absolute right-3 top-12 table-float">
<div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
<div class="bg-gradient-to-r from-blue-500/20 to-purple-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">relationships</div>
<div class="px-1.5 py-0.5 space-y-0.5">
<div class="flex items-center space-x-0.5">
<div class="w-1 h-1 bg-blue-400 rounded-full"></div>
<div class="h-0.5 w-6 bg-white/30 rounded"></div>
</div>
<div class="h-0.5 w-3 bg-white/20 rounded"></div>
<div class="h-0.5 w-5 bg-white/20 rounded"></div>
</div>
</div>
</div>
<div class="absolute left-1/2 transform -translate-x-1/2 top-24 table-float">
<div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
<div class="bg-gradient-to-r from-purple-500/20 to-pink-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">models</div>
<div class="px-1.5 py-0.5 space-y-0.5">
<div class="flex items-center space-x-0.5">
<div class="w-1 h-1 bg-green-400 rounded-full"></div>
<div class="h-0.5 w-6 bg-white/30 rounded"></div>
</div>
<div class="h-0.5 w-6 bg-white/20 rounded"></div>
<div class="h-0.5 w-4 bg-white/20 rounded"></div>
</div>
</div>
</div>
<div class="absolute left-1/2 transform -translate-x-1/2 bottom-3 table-float">
<div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
<div class="bg-gradient-to-r from-orange-500/20 to-red-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">components</div>
<div class="px-1.5 py-0.5 space-y-0.5">
<div class="flex items-center space-x-0.5">
<div class="w-1 h-1 bg-orange-400 rounded-full"></div>
<div class="h-0.5 w-6 bg-white/30 rounded"></div>
</div>
<div class="h-0.5 w-3 bg-white/20 rounded"></div>
<div class="h-0.5 w-5 bg-white/20 rounded"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Glass divider -->
<div class="w-full h-px bg-gradient-to-r from-transparent via-white/30 to-transparent"></div>
<!-- Content -->
<div class="p-4">
<span class="inline-block px-3 py-1 glass text-orange-300 rounded-full text-xs font-medium mb-3 border border-orange-400/30">AWS</span>
<span class="inline-block px-3 py-1 glass text-indigo-300 rounded-full text-xs font-medium mb-3 border border-indigo-400/30">Azure</span>
<span class="inline-block px-3 py-1 glass text-sky-300 rounded-full text-xs font-medium mb-3 border border-sky-400/30">GCP</span>
<h3 class="text-lg font-medium text-white mb-2">Model your infrastructure</h3>
<p class="text-white/70 mb-4 leading-relaxed text-xs">
Design, optimize and maintain your infrastructure with Kanvas' intelligent inference.
</p>
<div class="flex justify-between items-center">
<a href="#" class="text-green-400 hover:text-green-300 transition flex items-center text-xs font-medium glass px-3 py-1.5 rounded-lg border border-green-400/30">
Manage
<svg class="w-3 h-3 ml-1" viewBox="0 0 24 24" fill="none"><path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</a>
<span class="text-black-400/50 text-xs glass px-2 py-1 rounded-full border border-gray-400/10">Live</span>
</div>
</div>
</div>
</div>
</div>
<script>
const canvas = document.getElementById('visualizer');
const ctx = canvas.getContext('2d');
let time = 0;
let waveData = Array(8).fill(0).map(() => ({
value: Math.random() * 0.5 + 0.1,
targetValue: Math.random() * 0.15 + 0.1,
speed: Math.random() * .02 + 0.01
}));
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function updateWaveData() {
waveData.forEach(data => {
if (Math.random() < 0.01) {
data.targetValue = Math.random() * 0.7 + 0.1;
}
const diff = data.targetValue - data.value;
data.value += diff * data.speed;
});
}
function draw() {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < 8; i++) {
const freq = waveData[i].value * 7.0;
ctx.beginPath();
for (let x = 0; x < canvas.width; x += 1) {
const normalizedX = (x / canvas.width) * 2 - 1;
let px = normalizedX + i * 0.04 + freq * 0.03;
let py = Math.sin(px * 10 + time) * Math.cos(px * 2) * freq * 0.1 * ((i + 1) / 8);
const canvasY = (py + 1) * canvas.height / 2;
if (x === 0) {
ctx.moveTo(x, canvasY);
} else {
ctx.lineTo(x, canvasY);
}
}
const intensity = Math.min(1, freq * 0.3);
const r = 255 + intensity * 100;
const g = 243 + intensity * 130;
const b = 197;
ctx.lineWidth = .1 + (i * 0.3);
ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, 0.6)`;
ctx.shadowColor = `rgba(${r}, ${g}, ${b}, 0.5)`;
ctx.shadowBlur = 5;
ctx.stroke();
ctx.shadowBlur = 0;
}
}
function animate() {
time += 0.02;
updateWaveData();
draw();
requestAnimationFrame(animate);
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
animate();
</script>
</body>
</html>
Implementation
- refer to the html code above
Acceptance Tests
- reusable react card component created
- animated card used in suitable sections on the site
Contributor Resources and Handbook
The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the master
branch.
- 📚 See contributing instructions.
- 🎨 Wireframes and designs for Layer5 site in Figma (open invite)
- 🙋🏾🙋🏼 Questions: Discussion Forum and Community Slack.
Join the Layer5 Community by submitting your community member form.