Spaces:
Running
Running
| import Button from "./Button"; | |
| import { useState, useEffect } from "react"; | |
| import { THEME } from "../constants"; | |
| import HfIcon from "./HfIcon"; | |
| interface WelcomeScreenProps { | |
| onStart: () => void; | |
| } | |
| export default function WelcomeScreen({ onStart }: WelcomeScreenProps) { | |
| const [mounted, setMounted] = useState(false); | |
| useEffect(() => { | |
| setMounted(true); | |
| }, []); | |
| return ( | |
| <> | |
| <div | |
| className="absolute inset-0 flex items-center justify-center p-6 overflow-y-auto" | |
| style={{ | |
| backgroundColor: THEME.beigeLight, | |
| backgroundImage: ` | |
| linear-gradient(${THEME.beigeDark} 1px, transparent 1px), | |
| linear-gradient(90deg, ${THEME.beigeDark} 1px, transparent 1px) | |
| `, | |
| backgroundSize: "40px 40px", | |
| color: THEME.textBlack, | |
| }} | |
| > | |
| <div | |
| className={`relative max-w-4xl w-full backdrop-blur-sm p-10 md:p-12 rounded-sm border shadow-2xl transition-all duration-700 ${mounted ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"}`} | |
| style={{ | |
| backgroundColor: `${THEME.beigeLight}F2`, // 95% opacity | |
| borderColor: THEME.beigeDark, | |
| }} | |
| > | |
| {/* 1. Top Right Status Indicator */} | |
| <div className="absolute top-6 right-6 group cursor-help z-10"> | |
| <span className="absolute right-full mr-4 top-1/2 -translate-y-1/2 whitespace-nowrap text-xs font-mono uppercase tracking-widest text-gray-500 opacity-0 group-hover:opacity-100 transition-all duration-300 translate-x-2 group-hover:translate-x-0 pointer-events-none"> | |
| System Ready | |
| </span> | |
| <div className="relative flex h-3 w-3"> | |
| <span | |
| className="animate-ping absolute inline-flex h-full w-full rounded-full opacity-75" | |
| style={{ backgroundColor: THEME.mistralOrange }} | |
| ></span> | |
| <span | |
| className="relative inline-flex rounded-sm h-3 w-3" | |
| style={{ backgroundColor: THEME.mistralOrange }} | |
| ></span> | |
| </div> | |
| </div> | |
| <div className="space-y-12"> | |
| {/* Header Section */} | |
| <div className="text-center space-y-4 animate-enter"> | |
| <div className="flex flex-col items-center justify-center space-y-5"> | |
| <div className="relative group"> | |
| <img | |
| src="Ministral.png" | |
| alt="Ministral Logo" | |
| className="h-24 object-contain transition-transform duration-500 group-hover:scale-105 drop-shadow-sm" | |
| /> | |
| </div> | |
| <h1 | |
| className="text-6xl md:text-7xl font-semibold tracking-tighter" | |
| style={{ color: THEME.textBlack }} | |
| > | |
| Ministral WebGPU | |
| </h1> | |
| </div> | |
| <p className="text-xl md:text-2xl text-gray-600 max-w-2xl mx-auto font-light leading-relaxed"> | |
| Frontier multimodal AI, running entirely in your browser. | |
| <br /> | |
| Powered by{" "} | |
| <a | |
| href="https://huggingface.co/mistralai/Ministral-3-3B-Instruct-2512-ONNX" | |
| className="font-medium underline decoration-2 underline-offset-4 transition-all hover:decoration-[3px]" | |
| style={{ | |
| color: THEME.mistralOrange, | |
| textDecorationColor: THEME.mistralOrange, | |
| }} | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| > | |
| Ministral-3-3B | |
| </a> | |
| </p> | |
| </div> | |
| {/* Content Grid */} | |
| <div | |
| className="grid grid-cols-1 md:grid-cols-3 gap-8 border-t border-b py-10 animate-enter delay-100" | |
| style={{ borderColor: THEME.beigeDark }} | |
| > | |
| {/* Feature 1 */} | |
| <div className="space-y-3 group"> | |
| <div | |
| className="w-10 h-10 flex items-center justify-center text-white font-bold text-lg shadow-sm transition-transform duration-300 group-hover:-translate-y-1" | |
| style={{ backgroundColor: THEME.mistralOrange }} | |
| > | |
| 1 | |
| </div> | |
| <h4 | |
| className="font-semibold text-xl" | |
| style={{ color: THEME.textBlack }} | |
| > | |
| Load Model | |
| </h4> | |
| <p className="text-gray-600 leading-relaxed"> | |
| Downloads the optimized Ministral model (~3GB) directly to | |
| your browser cache. | |
| </p> | |
| </div> | |
| {/* Feature 2 */} | |
| <div className="space-y-3 group"> | |
| <div | |
| className="w-10 h-10 flex items-center justify-center text-white font-bold text-lg shadow-sm transition-transform duration-300 group-hover:-translate-y-1" | |
| style={{ backgroundColor: THEME.mistralOrange }} | |
| > | |
| 2 | |
| </div> | |
| <h4 | |
| className="font-semibold text-xl" | |
| style={{ color: THEME.textBlack }} | |
| > | |
| Private & Local | |
| </h4> | |
| <p className="text-gray-600 leading-relaxed"> | |
| Your video feed is processed locally and never sent to a | |
| server, powered by | |
| <a href="https://github.com/huggingface/transformers.js"> | |
| <span className="font-medium underline"> | |
| <HfIcon className="size-6 ml-1 mt-[-1px] inline" /> | |
| Transformers.js | |
| </span> | |
| </a> | |
| . | |
| </p> | |
| </div> | |
| {/* Feature 3 */} | |
| <div className="space-y-3 group"> | |
| <div | |
| className="w-10 h-10 flex items-center justify-center text-white font-bold text-lg shadow-sm transition-transform duration-300 group-hover:-translate-y-1" | |
| style={{ backgroundColor: THEME.mistralOrange }} | |
| > | |
| 3 | |
| </div> | |
| <h4 | |
| className="font-semibold text-xl" | |
| style={{ color: THEME.textBlack }} | |
| > | |
| Real-time Vision | |
| </h4> | |
| <p className="text-gray-600 leading-relaxed"> | |
| The model analyzes the current frame and responds to the | |
| user's prompt. | |
| </p> | |
| </div> | |
| </div> | |
| {/* Action Area */} | |
| <div className="flex flex-col items-center animate-enter delay-200"> | |
| <Button | |
| onClick={onStart} | |
| className="group relative px-8 py-5 text-white overflow-hidden transition-all hover:shadow-2xl hover:-translate-y-0.5" | |
| > | |
| <div className="absolute inset-0 bg-white/20 translate-y-full group-hover:translate-y-0 transition-transform duration-300 ease-out" /> | |
| <span className="relative font-bold text-xl tracking-wide flex items-center gap-3"> | |
| START LIVE CAPTIONING | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| fill="none" | |
| viewBox="0 0 24 24" | |
| strokeWidth={2.5} | |
| stroke="currentColor" | |
| className="w-5 h-5 transition-transform duration-300 group-hover:translate-x-1" | |
| > | |
| <path | |
| strokeLinecap="round" | |
| strokeLinejoin="round" | |
| d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" | |
| /> | |
| </svg> | |
| </span> | |
| </Button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </> | |
| ); | |
| } | |