"use client"; import { motion } from "framer-motion"; import { COLORS, VizFrame } from "./common"; /** CLIP style dual encoder: image and text towers into a shared embedding space. */ export function ClipDualEncoder({ width = 520, height = 380, }: { width?: number; height?: number; }) { const cx = width / 2; const encW = 88; const encH = 44; const embW = 72; const embH = 28; const imageY = 52; const textY = height - 118; const sharedY = height / 2 + 8; const leftX = 36; const encX = leftX + 78; const embX = encX + encW + 36; const sharedX = cx - 56; return ( {/* Image branch */} image {Array.from({ length: 16 }, (_, i) => { const c = i % 4; const r = Math.floor(i / 4); const v = 0.15 + ((c + r) % 3) * 0.22; return ( ); })} f_I z_I ∈ R^D {/* Text branch */} text {["a", "drone", "over", "field"].map((t, i) => ( {t} ))} f_T z_T ∈ R^D {/* Arrows image -> encoder -> embedding -> shared */} {/* Arrows text branch */} {/* Shared embedding space */} shared R^D {/* matched pair dots close together */} {/* unmatched pair far apart */} {/* Similarity matrix hint */} sim = z_I·z_T {[0, 1, 2].map((r) => [0, 1, 2].map((c) => { const hot = r === c; return ( ); }), )} ); }