SuperShipped // Item 21

SNIPPET VIEW

Live Render

HTML CODE

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Interactive Social UI</title>
    <style>
        :root {
            --purple-bg: #6a1b9a;
            --card-shadow: 0 15px 35px rgba(0,0,0,0.3);
            --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
        }

        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
            font-family: 'Segoe UI', system-ui, sans-serif;
            background-color: var(--purple-bg);
            color: #333;
        }

        #canvas-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 0;
            pointer-events: none;
        }

        .main-container {
            position: relative;
            z-index: 1;
            width: 100vw;
            height: 100vh;
            perspective: 1000px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* --- UI Elements --- */
        .card {
            background: white;
            border-radius: 16px;
            box-shadow: var(--card-shadow);
            position: absolute;
            transition: var(--transition);
            cursor: pointer;
            user-select: none;
        }

        .card:hover {
            transform: scale(1.05) translateZ(20px) !important;
            box-shadow: 0 25px 50px rgba(0,0,0,0.4);
            z-index: 10;
        }

        /* Main Center Image Card */
        .center-post {
            width: 320px;
            height: 460px;
            padding: 12px;
            display: flex;
            flex-direction: column;
        }

        .img-container {
            position: relative;
            width: 100%;
            height: 85%;
            overflow: hidden;
            border-radius: 10px;
        }

        .center-post img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.5s ease;
        }

        .center-post:hover img {
            transform: scale(1.1);
        }

        /* Heart Interaction */
        .heart-btn {
            position: absolute;
            bottom: 10px;
            right: 10px;
            background: rgba(255,255,255,0.9);
            border-radius: 50%;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
            border: none;
            cursor: pointer;
            transition: var(--transition);
        }
        .heart-btn.active { color: #e91e63; transform: scale(1.2); }

        /* Secondary Card */
        .left-post {
            width: 160px;
            height: 200px;
            left: 15%;
            top: 20%;
            padding: 8px;
        }

        .left-post img { width: 100%; height: 75%; object-fit: cover; border-radius: 6px; }

        /* Chat Bubbles */
        .bubble {
            background: white;
            padding: 14px 22px;
            border-radius: 20px;
            box-shadow: var(--card-shadow);
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 14px;
            font-weight: 600;
            position: absolute;
            transition: var(--transition);
            cursor: pointer;
        }

        .bubble:hover {
            transform: scale(1.1) translateX(10px) !important;
            background: #fdfdfd;
        }

        .avatar {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            flex-shrink: 0;
        }

        .bubble-1 { top: 18%; right: 18%; }
        .bubble-2 { top: 38%; right: 12%; }
        .bubble-3 { bottom: 22%; left: 12%; }

        .tag { color: #1e88e5; text-decoration: none; font-weight: bold; }

        /* UI Placeholder Lines */
        .ui-line { height: 6px; background: #eee; border-radius: 3px; margin-top: 8px; }
        .ui-line.short { width: 40%; }
        .ui-line.long { width: 85%; }

    </style>
</head>
<body>

    <div id="canvas-container">
        <canvas id="webgl-canvas"></canvas>
    </div>

    <div class="main-container" id="parallax-scene">
        <div class="card left-post" data-depth="0.2" style="transform: rotate(-8deg);">
            <img src="https://images.unsplash.com/photo-1529156069898-49953e39b3ac?auto=format&fit=crop&w=300&q=80" alt="Friends">
            <div class="ui-line long"></div>
            <div class="ui-line short"></div>
        </div>

        <div class="card center-post" data-depth="0.1" style="transform: rotate(-2deg);">
            <div class="img-container">
                <img src="https://images.unsplash.com/photo-1534528741775-53994a69daeb?auto=format&fit=crop&w=500&q=80" alt="Main Model">
                <button class="heart-btn" onclick="this.classList.toggle('active')">❤</button>
            </div>
            <div style="display: flex; align-items: center; gap: 10px; margin-top: 15px;">
                <div class="avatar" style="background: #9c27b0;"></div>
                <div style="flex-grow: 1;">
                    <div class="ui-line long"></div>
                    <div class="ui-line short"></div>
                </div>
            </div>
        </div>

        <div class="bubble bubble-1" data-depth="0.3">
            <div class="avatar" style="background: linear-gradient(45deg, #f093fb, #f5576c);"></div>
            <span>This video is us hahaha</span>
        </div>

        <div class="bubble bubble-2" data-depth="0.4">
            <div class="avatar" style="background: linear-gradient(45deg, #2196F3, #3F51B5);"></div>
            <span>I feel seen lol</span>
        </div>

        <div class="bubble bubble-3" data-depth="0.25">
            <div class="avatar" style="background: #0d47a1;"></div>
            <span><span class="tag">@friend</span> please tell me you saw this!</span>
        </div>
    </div>

    <script id="vs" type="x-shader/x-vertex">
        attribute vec2 position;
        void main() { gl_Position = vec4(position, 0.0, 1.0); }
    </script>

    <script id="fs" type="x-shader/x-fragment">
        precision highp float;
        uniform float u_time;
        uniform vec2 u_resolution;
        uniform vec2 u_mouse;

        float noise(vec2 uv) {
            return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453);
        }

        void main() {
            vec2 uv = gl_FragCoord.xy / u_resolution.xy;
            vec2 m = u_mouse / u_resolution.xy;
            
            // Subtle movement based on mouse
            vec3 color = vec3(0.35 + (m.x * 0.1), 0.08, 0.55 + (m.y * 0.1)); 
            
            // Abstract Background Shapes
            float d1 = distance(uv, vec2(0.8 + sin(u_time*0.5)*0.05, 0.5));
            float d2 = distance(uv, vec2(0.2, 0.8));
            
            color = mix(color, vec3(0.5, 0.15, 0.7), smoothstep(0.45, 0.44, d1) * 0.6);
            color = mix(color, vec3(0.45, 0.1, 0.65), smoothstep(0.3, 0.29, d2) * 0.4);

            // Grain
            color += (noise(uv + u_time * 0.05) - 0.5) * 0.07;

            gl_FragColor = vec4(color, 1.0);
        }
    </script>

    <script>
        // 1. WebGL Background Logic
        const canvas = document.getElementById('webgl-canvas');
        const gl = canvas.getContext('webgl');
        let mouseX = 0, mouseY = 0;

        function initWebGL() {
            const program = gl.createProgram();
            const addShader = (type, source) => {
                const s = gl.createShader(type);
                gl.shaderSource(s, source);
                gl.compileShader(s);
                gl.attachShader(program, s);
            };
            addShader(gl.VERTEX_SHADER, document.getElementById('vs').text);
            addShader(gl.FRAGMENT_SHADER, document.getElementById('fs').text);
            gl.linkProgram(program);
            gl.useProgram(program);

            const buffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]), gl.STATIC_DRAW);
            const pos = gl.getAttribLocation(program, "position");
            gl.enableVertexAttribArray(pos);
            gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);

            const timeLoc = gl.getUniformLocation(program, "u_time");
            const resLoc = gl.getUniformLocation(program, "u_resolution");
            const mouseLoc = gl.getUniformLocation(program, "u_mouse");

            function render(time) {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
                gl.viewport(0, 0, canvas.width, canvas.height);
                gl.uniform1f(timeLoc, time * 0.001);
                gl.uniform2f(resLoc, canvas.width, canvas.height);
                gl.uniform2f(mouseLoc, mouseX, mouseY);
                gl.drawArrays(gl.TRIANGLES, 0, 6);
                requestAnimationFrame(render);
            }
            requestAnimationFrame(render);
        }

        // 2. Parallax & Mouse Interactivity
        const scene = document.getElementById('parallax-scene');
        const elements = document.querySelectorAll('[data-depth]');

        window.addEventListener('mousemove', (e) => {
            mouseX = e.clientX;
            mouseY = e.clientY;

            // Calculate offset from center
            const x = (window.innerWidth / 2 - e.pageX) / 25;
            const y = (window.innerHeight / 2 - e.pageY) / 25;

            elements.forEach(el => {
                const depth = el.getAttribute('data-depth');
                const moveX = x * depth;
                const moveY = y * depth;
                
                // Maintain the original rotation while adding parallax
                const currentRotation = el.style.transform.match(/rotate\((.*?)\)/);
                const rot = currentRotation ? currentRotation[0] : 'rotate(0deg)';
                
                el.style.transform = `${rot} translate3d(${moveX}px, ${moveY}px, 0)`;
            });
        });

        // Initialize everything
        initWebGL();
    </script>
</body>
</html>

AI PROMPT

Create a "Interactive Social UI" component. Implement custom GLSL shaders for visual effects. Apply gradients, 3D CSS perspective, layered shadows, hover transitions. Color palette: #6a1b9a. Layout: Flexbox, full-screen fixed canvas background, full-viewport sizing. Interactivity: mouse tracking, click interactions, continuous animation loop. Use procedural noise for organic visual effects.