VibeCoderzVibeCoderz
Telegram
All Prompts
Skeuomorphic 3D Analytics Metrics Card preview
cardanalyticsdashboardmetricsanimatedinteractivesvgtailwind

Skeuomorphic 3D Analytics Metrics Card

Скевоморфная 3D карточка метрик аналитики: емкость, CPU, память, сеть. Анимированные SVG кольца, параллакс, Tailwind. Для дашбордов.

Prompt

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Premium Skeuomorphic Analytics Card</title>
    
    <!-- Fonts: Inter for UI text, JetBrains Mono for numbers -->
    <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=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
    
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    fontFamily: {
                        sans:['Inter', 'sans-serif'],
                        mono: ['JetBrains Mono', 'monospace'],
                    },
                    colors: {
                        graphite: '#0b0b0d',
                        cardBase: '#151519',
                        cardTop: '#1d1d22',
                    }
                }
            }
        }
    </script>

    <style>
        /* Base Reset & Background */
        body {
            background-color: #0b0b0d;
            margin: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            color: #ffffff;
            overflow: hidden;
        }

        /* 3D Perspective Container */
        .perspective-container {
            perspective: 1400px;
        }

        /* Main Skeuomorphic Card Body */
        .skeuo-card {
            background: linear-gradient(145deg, #1c1c22 0%, #0e0e11 100%);
            box-shadow: 
                /* Outer soft drop shadow */
                25px 25px 50px rgba(0, 0, 0, 0.9),
                /* Opposite light rim to simulate ambient occlusion */
                -10px -10px 30px rgba(35, 35, 45, 0.2),
                /* Micro-reflection on the top/left edge */
                inset 1.5px 1.5px 2px rgba(255, 255, 255, 0.12),
                /* Inner shadow on bottom/right for bevel depth */
                inset -1.5px -1.5px 3px rgba(0, 0, 0, 0.7);
            border: 1px solid #222228;
            transform-style: preserve-3d;
            will-change: transform;
        }

        /* Subtle Noise Texture for anodized metal look */
        .noise-texture {
            position: absolute;
            inset: 0;
            background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
            opacity: 0.04;
            mix-blend-mode: overlay;
            pointer-events: none;
            border-radius: inherit;
        }

        /* Inset Surfaces (Dials / Screens) */
        .skeuo-inset {
            background: linear-gradient(145deg, #09090b 0%, #121216 100%);
            box-shadow: 
                /* Deep dark inset */
                inset 6px 6px 15px rgba(0, 0, 0, 0.8),
                /* Inset opposite light to show inner lip */
                inset -2px -2px 8px rgba(35, 35, 45, 0.3),
                /* Outer lip reflection */
                1px 1px 1px rgba(255, 255, 255, 0.06);
            border: 1px solid #000;
        }

        /* Hardware Details: Screws */
        .screw {
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: #111;
            box-shadow: 
                inset 1px 1px 2px rgba(0, 0, 0, 0.9), 
                0 1px 1px rgba(255, 255, 255, 0.15);
        }

        /* Text Glows */
        .glow-text-teal { text-shadow: 0 0 10px rgba(20, 184, 166, 0.6); }
        .glow-text-violet { text-shadow: 0 0 10px rgba(139, 92, 246, 0.6); }

        /* Parallax Depth Classes */
        .parallax-layer { transform: translateZ(25px); }
        .parallax-layer-lg { transform: translateZ(45px); }
        .parallax-layer-xl { transform: translateZ(60px); }

        /* Light Sweep Effect */
        .sweep-light {
            background: linear-gradient(
                90deg, 
                transparent 0%, 
                rgba(255, 255, 255, 0.03) 40%, 
                rgba(255, 255, 255, 0.1) 50%, 
                rgba(255, 255, 255, 0.03) 60%, 
                transparent 100%
            );
            transform: translateX(-150%) skewX(-20deg);
            transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .perspective-container:hover .sweep-light {
            transform: translateX(150%) skewX(-20deg);
        }

        /* SVG Animation */
        .progress-ring {
            transition: stroke-dashoffset 2s cubic-bezier(0.16, 1, 0.3, 1);
        }
    </style>
</head>
<body>

    <!-- 3D Perspective Container -->
    <div class="perspective-container group relative w-[380px] h-[540px]">
        
        <!-- Main Card Body -->
        <div id="card" class="skeuo-card relative w-full h-full rounded-[32px] p-7 flex flex-col justify-between">
            
            <!-- Noise Texture Overlay -->
            <div class="noise-texture"></div>

            <!-- Dynamic Specular Glare (Controlled by JS) -->
            <div id="glare" class="absolute inset-0 rounded-[32px] pointer-events-none z-50 transition-opacity duration-300 opacity-0 group-hover:opacity-100"></div>

            <!-- Light Sweep Layer (Triggered on hover) -->
            <div class="absolute inset-0 rounded-[32px] pointer-events-none overflow-hidden z-40">
                <div class="sweep-light absolute top-0 bottom-0 left-0 w-[200%] h-full"></div>
            </div>

            <!-- Hardware Detail: Corner Screws -->
            <div class="absolute top-4 left-4 screw"></div>
            <div class="absolute top-4 right-4 screw"></div>
            <div class="absolute bottom-4 left-4 screw"></div>
            <div class="absolute bottom-4 right-4 screw"></div>

            <!-- Header Section -->
            <div class="parallax-layer flex justify-between items-center z-10 mt-2">
                <div class="flex items-center gap-2">
                    <div class="w-2 h-2 rounded-full bg-violet-500 shadow-[0_0_8px_#8b5cf6]"></div>
                    <span class="text-[10px] font-bold tracking-[0.25em] text-gray-400">SYS.ANALYTICS</span>
                </div>
                <!-- Mini decorative grill -->
                <div class="flex gap-1">
                    <div class="w-1 h-3 rounded-full skeuo-inset"></div>
                    <div class="w-1 h-3 rounded-full skeuo-inset"></div>
                    <div class="w-1 h-3 rounded-full skeuo-inset"></div>
                </div>
            </div>

            <!-- Main Circular Ring Section -->
            <div class="parallax-layer-lg relative flex flex-1 items-center justify-center z-10 my-6">
                
                <!-- The Inset Dial Container -->
                <div class="relative w-64 h-64 rounded-full skeuo-inset flex items-center justify-center">
                    
                    <!-- SVG Progress Ring -->
                    <svg width="240" height="240" viewBox="0 0 240 240" class="absolute transform -rotate-90">
                        <defs>
                            <!-- Violet to Teal Gradient -->
                            <linearGradient id="ringGrad" x1="0%" y1="0%" x2="100%" y2="100%">
                                <stop offset="0%" stop-color="#8b5cf6" />
                                <stop offset="100%" stop-color="#14b8a6" />
                            </linearGradient>
                            
                            <!-- Drop Shadow Glow Filter for the progress line -->
                            <filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
                                <feGaussianBlur stdDeviation="6" result="blur" />
                                <feMerge>
                                    <feMergeNode in="blur" />
                                    <feMergeNode in="SourceGraphic" />
                                </feMerge>
                            </filter>
                            
                            <!-- Inner Shadow for the background track -->
                            <filter id="innerShadow">
                                <feOffset dx="1" dy="1"/>
                                <feGaussianBlur stdDeviation="3" result="offset-blur"/>
                                <feComposite operator="out" in="SourceGraphic" in2="offset-blur" result="inverse"/>
                                <feFlood flood-color="black" flood-opacity="0.9" result="color"/>
                                <feComposite operator="in" in="color" in2="inverse" result="shadow"/>
                                <feComposite operator="over" in="shadow" in2="SourceGraphic"/>
                            </filter>
                        </defs>
                        
                        <!-- Track Circle (Dark Inset) -->
                        <circle cx="120" cy="120" r="100" fill="none" stroke="#101014" stroke-width="14" filter="url(#innerShadow)" />
                        
                        <!-- Progress Circle (Glowing Segment) -->
                        <circle id="progressRing" cx="120" cy="120" r="100" fill="none" stroke="url(#ringGrad)" stroke-width="14" stroke-linecap="round" class="progress-ring" filter="url(#glow)" />
                    </svg>

                    <!-- Center Display Number -->
                    <div class="parallax-layer-xl flex flex-col items-center justify-center mt-2 relative z-20">
                        <div class="text-6xl font-mono text-white flex items-start leading-none tracking-tighter shadow-black drop-shadow-lg">
                            <span id="mainVal">0</span>
                            <span class="text-2xl text-violet-400 mt-1 ml-1 glow-text-violet">%</span>
                        </div>
                        <span class="text-[10px] font-bold tracking-[0.3em] text-gray-500 mt-3">CAPACITY</span>
                    </div>
                </div>
            </div>

            <!-- Metrics Grid Section -->
            <div class="parallax-layer grid grid-cols-3 gap-4 z-10 mb-2">
                
                <!-- CPU Load Metric -->
                <div class="skeuo-inset rounded-2xl p-4 flex flex-col items-center justify-center relative">
                    <span class="text-[9px] font-bold tracking-widest text-gray-500 mb-2">CPU LOAD</span>
                    <div class="flex items-baseline font-mono">
                        <span class="text-lg font-semibold text-teal-400 glow-text-teal" id="cpuVal">0</span>
                        <span class="text-[10px] text-teal-600 ml-0.5">%</span>
                    </div>
                </div>
                
                <!-- Memory Metric -->
                <div class="skeuo-inset rounded-2xl p-4 flex flex-col items-center justify-center relative overflow-hidden">
                    <span class="text-[9px] font-bold tracking-widest text-gray-500 mb-2">MEMORY</span>
                    <div class="flex items-baseline font-mono">
                        <span class="text-lg font-semibold text-violet-400 glow-text-violet" id="memVal">0</span>
                        <span class="text-[10px] text-violet-600 ml-0.5">%</span>
                    </div>
                    <!-- Tiny physical active bar indicator -->
                    <div class="absolute bottom-0 left-0 h-[2px] bg-violet-500 shadow-[0_0_5px_#8b5cf6] transition-all duration-[2s] ease-out w-0" id="memBar"></div>
                </div>
                
                <!-- Network Metric -->
                <div class="skeuo-inset rounded-2xl p-4 flex flex-col items-center justify-center relative">
                    <span class="text-[9px] font-bold tracking-widest text-gray-500 mb-2">NETWORK</span>
                    <div class="flex items-baseline font-mono">
                        <span class="text-lg font-semibold text-gray-200" id="netVal">0</span>
                        <span class="text-[10px] text-gray-500 ml-1">mb/s</span>
                    </div>
                </div>

            </div>
        </div>
    </div>

    <!-- Vanilla JS Interactions & Animations -->
    <script>
        document.addEventListener("DOMContentLoaded", () => {
            
            // --- 1. Ring and Count-Up Animation Logic ---
            const ring = document.getElementById("progressRing");
            const radius = ring.r.baseVal.value;
            const circumference = 2 * Math.PI * radius;

            // Initialize Ring Stroke
            ring.style.strokeDasharray = `${circumference} ${circumference}`;
            ring.style.strokeDashoffset = circumference; // Start completely hidden

            // Define targets
            const targets = {
                main: 82,   // Overall Capacity
                cpu: 64,    // CPU Load
                mem: 78,    // Memory
                net: 412    // Network throughput
            };

            const animDuration = 2200; // ms
            const startTime = performance.now();

            // Custom easing function (easeOutExpo)
            const easeOut = (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t);

            function animateCounters(currentTime) {
                const elapsed = currentTime - startTime;
                const progress = Math.min(elapsed / animDuration, 1);
                const easedProgress = easeOut(progress);

                // Animate SVG Ring
                const offset = circumference - (targets.main / 100) * circumference * easedProgress;
                ring.style.strokeDashoffset = offset;

                // Animate Text Metrics
                document.getElementById("mainVal").innerText = Math.floor(targets.main * easedProgress);
                document.getElementById("cpuVal").innerText = Math.floor(targets.cpu * easedProgress);
                document.getElementById("memVal").innerText = Math.floor(targets.mem * easedProgress);
                document.getElementById("netVal").innerText = Math.floor(targets.net * easedProgress);

                // Animate Memory Bar Width Indicator
                document.getElementById("memBar").style.width = `${Math.floor(targets.mem * easedProgress)}%`;

                if (progress < 1) {
                    requestAnimationFrame(animateCounters);
                }
            }
            
            // Start counter animation
            requestAnimationFrame(animateCounters);


            // --- 2. 3D Tilt & Specular Glare (Lerped for premium feel) ---
            const container = document.querySelector('.perspective-container');
            const card = document.getElementById('card');
            const glare = document.getElementById('glare');

            // Tracking variables
            let mouseX = 0, mouseY = 0;
            let currentX = 0, currentY = 0;
            const maxRotation = 12; // Maximum tilt angle in degrees

            // Update mouse coordinates relative to center on mousemove
            container.addEventListener('mousemove', (e) => {
                const rect = container.getBoundingClientRect();
                // Normalize values between -0.5 and 0.5
                mouseX = ((e.clientX - rect.left) / rect.width) - 0.5;
                mouseY = ((e.clientY - rect.top) / rect.height) - 0.5;
            });

            // Reset coordinates when mouse leaves
            container.addEventListener('mouseleave', () => {
                mouseX = 0;
                mouseY = 0;
            });

            // Animation loop for smooth physical interpolation (lerping)
            function renderTilt() {
                // Lerp formula: current = current + (target - current) * friction
                currentX += (mouseX - currentX) * 0.1;
                currentY += (mouseY - currentY) * 0.1;

                // Calculate Rotation: inverted Y for natural pitch, normal X for yaw
                const rotateX = currentY * -maxRotation;
                const rotateY = currentX * maxRotation;

                card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;

                // Dynamic Glare: Map lerped position to percentage (0% to 100%)
                const glareX = (currentX + 0.5) * 100;
                const glareY = (currentY + 0.5) * 100;
                
                // Create a smooth radial gradient that acts as a specular highlight
                glare.style.background = `radial-gradient(circle at ${glareX}% ${glareY}%, rgba(255, 255, 255, 0.08) 0%, transparent 60%)`;

                requestAnimationFrame(renderTilt);
            }

            // Start tilt animation loop
            renderTilt();
        });
    </script>
</body>
</html>
All Prompts