feat: redesign page heroes, implement organic markers, and streamline contact flow
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 1m24s
Build & Deploy / 🏗️ Build (push) Failing after 4m3s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 5s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 1m24s
Build & Deploy / 🏗️ Build (push) Failing after 4m3s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 5s
- Refined hero sections for About, Blog, Websites, and Case Studies for a bespoke industrial entry point. - Redesigned Marker component using layered SVG paths for an organic, hand-drawn highlighter effect. - Restored technical precision in ArchitectureVisualizer with refined line thickness. - Streamlined contact page by removing generic headers and prioritizing the configurator/gateway. - Updated technical references to reflect self-hosted Gitea infrastructure. - Cleaned up unused imports and addressed linting warnings across modified pages.
This commit is contained in:
156
apps/web/src/components/Effects/ArchitectureVisualizer.tsx
Normal file
156
apps/web/src/components/Effects/ArchitectureVisualizer.tsx
Normal file
@@ -0,0 +1,156 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { GitBranch, Box, Server, Globe } from "lucide-react";
|
||||
import { MonoLabel, Label } from "../Typography";
|
||||
import { cn } from "../../utils/cn";
|
||||
|
||||
const Node: React.FC<{
|
||||
icon: React.ElementType;
|
||||
title: string;
|
||||
status: string;
|
||||
active?: boolean;
|
||||
color?: string;
|
||||
}> = ({ icon: Icon, title, status, active, color = "blue" }) => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
className="flex flex-col items-center gap-2 md:gap-3 relative z-10 w-full md:w-auto"
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"w-12 h-12 md:w-16 md:h-16 rounded-xl md:rounded-2xl border flex items-center justify-center transition-all duration-700 shadow-sm",
|
||||
active
|
||||
? `bg-${color}-50 border-${color}-200 text-${color}-600 shadow-${color}-100/50 scale-110`
|
||||
: "bg-white border-slate-100 text-slate-300",
|
||||
)}
|
||||
>
|
||||
<Icon className="w-5 h-5 md:w-8 md:h-8" />
|
||||
{active && (
|
||||
<motion.div
|
||||
layoutId="active-glow"
|
||||
className={cn(
|
||||
"absolute inset-0 rounded-2xl blur-xl -z-10",
|
||||
`bg-${color}-400/20`,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-center space-y-0.5">
|
||||
<Label
|
||||
className={cn(
|
||||
"text-[8px] md:text-[9px] font-bold uppercase tracking-widest",
|
||||
active ? "text-slate-900" : "text-slate-300",
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</Label>
|
||||
<MonoLabel
|
||||
className={cn(
|
||||
"text-[6px] md:text-[7px]",
|
||||
active ? "text-green-500" : "text-slate-200",
|
||||
)}
|
||||
>
|
||||
{status}
|
||||
</MonoLabel>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
const Connector: React.FC<{ active?: boolean }> = ({ active }) => (
|
||||
<div className="flex-1 w-px md:w-auto h-8 md:h-[1px] bg-slate-100 relative min-h-[20px] md:min-w-[40px] shrink-0">
|
||||
{active && (
|
||||
<motion.div
|
||||
initial={{ scaleX: 0, scaleY: 0 }}
|
||||
animate={{ scaleX: 1, scaleY: 1 }}
|
||||
className="absolute inset-0 bg-blue-300 origin-top md:origin-left"
|
||||
/>
|
||||
)}
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<div
|
||||
className={cn(
|
||||
"w-1 h-1 rounded-full",
|
||||
active ? "bg-blue-300 animate-pulse" : "bg-slate-100",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ArchitectureVisualizer: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
const [step, setStep] = React.useState(0);
|
||||
|
||||
React.useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setStep((s) => (s + 1) % 4);
|
||||
}, 3000);
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative p-6 md:p-12 rounded-3xl border border-slate-100 bg-slate-50/30 backdrop-blur-sm overflow-hidden flex flex-col md:flex-row items-center justify-between gap-2 md:gap-4",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="absolute inset-0 opacity-[0.03] pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: "radial-gradient(#000 1px, transparent 1px)",
|
||||
backgroundSize: "30px 30px",
|
||||
}}
|
||||
/>
|
||||
|
||||
<Node
|
||||
icon={GitBranch}
|
||||
title="Repository"
|
||||
status="VCS_STABLE"
|
||||
active={step === 0}
|
||||
color="slate"
|
||||
/>
|
||||
<Connector active={step >= 1} />
|
||||
<Node
|
||||
icon={Box}
|
||||
title="Container"
|
||||
status="BUILD_SUCCESS"
|
||||
active={step === 1}
|
||||
color="blue"
|
||||
/>
|
||||
<Connector active={step >= 2} />
|
||||
<Node
|
||||
icon={Server}
|
||||
title="Deployment"
|
||||
status="HEALTH_OK"
|
||||
active={step === 2}
|
||||
color="indigo"
|
||||
/>
|
||||
<Connector active={step >= 3} />
|
||||
<Node
|
||||
icon={Globe}
|
||||
title="CDN Edge"
|
||||
status="LIVE_SYNCED"
|
||||
active={step === 3}
|
||||
color="green"
|
||||
/>
|
||||
|
||||
{/* Decorative Binary Pulse */}
|
||||
<div className="absolute top-4 left-4 font-mono text-[6px] md:text-[7px] text-slate-200 uppercase tracking-widest leading-none hidden sm:block">
|
||||
BUILD_PROTOCOL_v4.2 // SYSTEM_IS_DETERMINISTIC
|
||||
</div>
|
||||
|
||||
<div className="md:absolute bottom-4 right-1/2 md:translate-x-1/2 flex items-center gap-2 mt-6 md:mt-0">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse" />
|
||||
<span className="text-[7px] font-mono text-slate-400 font-bold uppercase tracking-widest">
|
||||
{step === 0 && "Polling for changes..."}
|
||||
{step === 1 && "Bundling production image..."}
|
||||
{step === 2 && "Syncing cluster state..."}
|
||||
{step === 3 && "Invalidating edge cache..."}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
215
apps/web/src/components/Effects/CMSVisualizer.tsx
Normal file
215
apps/web/src/components/Effects/CMSVisualizer.tsx
Normal file
@@ -0,0 +1,215 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import {
|
||||
Shield,
|
||||
Lock,
|
||||
Edit3,
|
||||
CheckCircle2,
|
||||
Globe,
|
||||
RotateCw,
|
||||
} from "lucide-react";
|
||||
import { MonoLabel, Label, BodyText } from "../Typography";
|
||||
import { cn } from "../../utils/cn";
|
||||
|
||||
export const CMSVisualizer: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = React.useState<"cms" | "live">("cms");
|
||||
const [lastAction, setLastAction] = React.useState<string | null>(null);
|
||||
|
||||
const triggerAction = (action: string) => {
|
||||
setLastAction(action);
|
||||
setTimeout(() => setLastAction(null), 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative w-full aspect-square rounded-3xl overflow-hidden border border-slate-100 bg-white shadow-2xl group/cms flex flex-col",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{/* ── BROWSER CHROME ── */}
|
||||
<div className="h-16 bg-slate-50 border-b border-slate-100 flex flex-col shrink-0 z-30">
|
||||
<div className="h-full flex items-center justify-between px-4 gap-4">
|
||||
<div className="flex gap-1.5 shrink-0">
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-slate-200" />
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-slate-200" />
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-slate-200" />
|
||||
</div>
|
||||
|
||||
<div className="flex-1 max-w-md h-8 bg-white border border-slate-200 rounded-lg flex items-center px-3 gap-2">
|
||||
<Globe className="w-3 h-3 text-slate-400" />
|
||||
<span className="text-[9px] font-mono text-slate-400 truncate">
|
||||
{activeTab === "cms"
|
||||
? "mintel.localhost/admin/posts/edit"
|
||||
: "mintel.me/projects/performance"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex bg-slate-200/50 rounded-lg p-0.5 text-[8px] font-mono font-bold shrink-0">
|
||||
<button
|
||||
onClick={() => setActiveTab("cms")}
|
||||
className={cn(
|
||||
"px-3 py-1.5 rounded-md transition-all",
|
||||
activeTab === "cms"
|
||||
? "bg-white text-slate-900 shadow-sm"
|
||||
: "text-slate-400",
|
||||
)}
|
||||
>
|
||||
CMS
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("live")}
|
||||
className={cn(
|
||||
"px-3 py-1.5 rounded-md transition-all",
|
||||
activeTab === "live"
|
||||
? "bg-white text-slate-900 shadow-sm"
|
||||
: "text-slate-400",
|
||||
)}
|
||||
>
|
||||
LIVE
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── MAIN CONTENT AREA ── */}
|
||||
<div className="flex-1 relative overflow-hidden bg-slate-50/20">
|
||||
<AnimatePresence mode="wait">
|
||||
{activeTab === "cms" ? (
|
||||
<motion.div
|
||||
key="cms-view"
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -10 }}
|
||||
className="absolute inset-0 flex flex-col md:flex-row"
|
||||
>
|
||||
{/* LEFT: Editor */}
|
||||
<div className="flex-1 p-6 md:p-8 flex flex-col gap-5 bg-white border-r border-slate-100">
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[9px] text-slate-400">
|
||||
BLOG TITEL
|
||||
</Label>
|
||||
<div className="h-10 rounded-lg bg-slate-50 border border-slate-200 p-3 relative">
|
||||
<motion.div
|
||||
animate={{ opacity: [1, 0.4, 1] }}
|
||||
transition={{ repeat: Infinity, duration: 2 }}
|
||||
className="w-32 h-3.5 bg-slate-200/50 rounded"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[9px] text-slate-400">
|
||||
TITELBILD
|
||||
</Label>
|
||||
<div
|
||||
className="aspect-video rounded-lg bg-slate-50 border border-slate-200 flex items-center justify-center cursor-pointer hover:bg-slate-100 transition-colors"
|
||||
onClick={() => triggerAction("Image Updated")}
|
||||
>
|
||||
<span className="text-xl text-slate-300">+</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-auto flex justify-end">
|
||||
<button
|
||||
onClick={() => triggerAction("Published")}
|
||||
className="px-5 py-2 bg-slate-900 text-white text-[10px] font-bold rounded-xl flex items-center gap-2"
|
||||
>
|
||||
<CheckCircle2 className="w-3 h-3" /> Veröffentlichen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* RIGHT: Preview */}
|
||||
<div className="hidden md:flex flex-1 p-8 items-center justify-center bg-slate-50/50 relative">
|
||||
<div className="w-full max-w-[240px] aspect-[3/4] bg-white rounded-2xl border border-slate-200 shadow-sm p-4 space-y-3 relative opacity-60">
|
||||
<div className="absolute top-2 right-2">
|
||||
<Lock className="w-2.5 h-2.5 text-blue-400" />
|
||||
</div>
|
||||
<div className="h-2 w-3/4 bg-blue-100 rounded" />
|
||||
<div className="aspect-video w-full bg-slate-100 rounded" />
|
||||
<div className="space-y-1.5">
|
||||
<div className="h-1 w-full bg-slate-50 rounded" />
|
||||
<div className="h-1 w-full bg-slate-50 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
<MonoLabel className="absolute bottom-4 text-[7px] text-slate-300">
|
||||
SANDBOX MODE: DESIGN FROZEN
|
||||
</MonoLabel>
|
||||
</div>
|
||||
</motion.div>
|
||||
) : (
|
||||
<motion.div
|
||||
key="live-view"
|
||||
initial={{ opacity: 0, scale: 0.98 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 1.02 }}
|
||||
className="absolute inset-0 bg-white flex flex-col p-6 md:p-12"
|
||||
>
|
||||
<header className="flex justify-between items-center border-b border-slate-100 pb-4 mb-8">
|
||||
<div className="w-8 h-8 bg-slate-900 rounded flex items-center justify-center text-white text-xs font-bold">
|
||||
M
|
||||
</div>
|
||||
<div className="flex gap-4 text-[8px] font-mono text-slate-400">
|
||||
<span>BLOG</span>
|
||||
<span>WORK</span>
|
||||
</div>
|
||||
</header>
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<MonoLabel className="text-blue-500">
|
||||
ARTICLE PREVIEW
|
||||
</MonoLabel>
|
||||
<h3 className="text-2xl md:text-4xl font-bold text-slate-900">
|
||||
Performance by{" "}
|
||||
<span className="text-slate-400 italic">Code.</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div className="aspect-video md:aspect-[21/9] w-full bg-slate-100 rounded-3xl relative overflow-hidden">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<span className="px-4 py-2 bg-white/90 rounded-full border border-slate-100 text-[10px] font-bold text-slate-900 flex items-center gap-2">
|
||||
<Shield className="w-3 h-3 text-blue-500" /> DESIGN
|
||||
ENFORCED
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<BodyText className="text-slate-400 text-xs max-w-md">
|
||||
Layout-Stabilität garantiert durch strikte Trennung von
|
||||
Content und Architektur.
|
||||
</BodyText>
|
||||
</div>
|
||||
<div className="mt-auto h-6 bg-slate-900 -mx-12 -mb-12 flex items-center px-6 justify-between">
|
||||
<span className="text-[6px] font-mono text-white/40 uppercase tracking-widest">
|
||||
Global CDN: Optimal
|
||||
</span>
|
||||
<span className="text-[6px] font-mono text-white/20">
|
||||
© 2026 MINTEL.ME
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<AnimatePresence>
|
||||
{lastAction && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.9 }}
|
||||
className="absolute bottom-6 left-1/2 -translate-x-1/2 z-50 bg-slate-900 text-white px-5 py-2.5 rounded-xl shadow-2xl flex items-center gap-3"
|
||||
>
|
||||
<RotateCw className="w-3 h-3 animate-spin text-blue-400" />
|
||||
<span className="text-[9px] font-bold tracking-wider uppercase">
|
||||
{lastAction}
|
||||
</span>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -28,7 +28,7 @@ export const CodeWindow: React.FC<CodeWindowProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative rounded-xl border border-slate-100 bg-slate-50/50 backdrop-blur-sm overflow-hidden w-full flex-shrink-0 flex flex-col",
|
||||
"relative rounded-xl border border-slate-100 bg-slate-50/50 backdrop-blur-sm overflow-hidden w-full flex flex-col",
|
||||
fixedHeight && "h-[400px]",
|
||||
className,
|
||||
)}
|
||||
|
||||
137
apps/web/src/components/Effects/ResultVisualizer.tsx
Normal file
137
apps/web/src/components/Effects/ResultVisualizer.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
Code2,
|
||||
Cpu,
|
||||
LayoutDashboard,
|
||||
CheckCircle2,
|
||||
Package,
|
||||
} from "lucide-react";
|
||||
import { MonoLabel, Label, BodyText } from "../Typography";
|
||||
import { cn } from "../../utils/cn";
|
||||
|
||||
const DeliveryCard: React.FC<{
|
||||
icon: React.ElementType;
|
||||
title: string;
|
||||
desc: string;
|
||||
delay: number;
|
||||
}> = ({ icon: Icon, title, desc, delay }) => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20, rotateX: 10 }}
|
||||
whileInView={{ opacity: 1, y: 0, rotateX: 0 }}
|
||||
transition={{ delay, duration: 0.8, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="group relative h-full"
|
||||
>
|
||||
<div className="h-full bg-white border border-slate-100 rounded-2xl p-6 md:p-8 shadow-sm flex flex-col gap-6 transition-all duration-700 hover:border-slate-300 hover:shadow-xl hover:shadow-slate-100/50">
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="w-12 h-12 rounded-xl bg-slate-50 border border-slate-100 flex items-center justify-center text-slate-400 group-hover:text-slate-900 group-hover:bg-white group-hover:border-slate-200 transition-all duration-500">
|
||||
<Icon className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="w-5 h-5 rounded-full border border-green-100 bg-green-50 flex items-center justify-center">
|
||||
<CheckCircle2 className="w-3 h-3 text-green-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h4 className="text-xl font-bold tracking-tight text-slate-900">
|
||||
{title}
|
||||
</h4>
|
||||
<BodyText className="text-sm text-slate-400 leading-relaxed group-hover:text-slate-500 transition-colors">
|
||||
{desc}
|
||||
</BodyText>
|
||||
</div>
|
||||
|
||||
<div className="mt-auto pt-6 border-t border-slate-50 flex items-center justify-between">
|
||||
<MonoLabel className="text-[8px] text-slate-300 uppercase tracking-widest">
|
||||
Ownership: 100%
|
||||
</MonoLabel>
|
||||
<span className="text-[10px] font-mono font-bold text-slate-900 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
READY
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Subtle hover accent */}
|
||||
<div className="absolute -inset-2 bg-gradient-to-tr from-slate-100/50 to-transparent rounded-3xl -z-10 opacity-0 group-hover:opacity-100 transition-opacity duration-700 blur-sm" />
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
export const ResultVisualizer: React.FC<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative p-6 md:p-12 lg:p-16 rounded-[2.5rem] border border-slate-100 bg-white overflow-hidden",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className="absolute inset-0 bg-slate-50/30 opacity-60" />
|
||||
<div
|
||||
className="absolute inset-0 opacity-[0.02] pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: "radial-gradient(#000 1px, transparent 1px)",
|
||||
backgroundSize: "40px 40px",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="relative z-10 space-y-12">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="px-4 py-2 bg-slate-900 rounded-xl flex items-center gap-3 shadow-xl">
|
||||
<Package className="w-4 h-4 text-white" />
|
||||
<MonoLabel className="text-white text-[10px]">
|
||||
DELIVERY_PACKAGE_v2
|
||||
</MonoLabel>
|
||||
</div>
|
||||
<div className="h-px flex-1 bg-slate-100" />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 lg:gap-8">
|
||||
<DeliveryCard
|
||||
icon={Code2}
|
||||
title="Quellcode"
|
||||
desc="Ihr Eigentum. Versioniert auf GitHub, dokumentiert und jederzeit bereit für Weiterentwicklungen."
|
||||
delay={0.1}
|
||||
/>
|
||||
<DeliveryCard
|
||||
icon={Cpu}
|
||||
title="Infrastruktur"
|
||||
desc="Docker-Container & CI/CD Pipelines. Ein System, das überall läuft und sich selbst aktualisiert."
|
||||
delay={0.2}
|
||||
/>
|
||||
<DeliveryCard
|
||||
icon={LayoutDashboard}
|
||||
title="Content System"
|
||||
desc="Ein maßgeschneidertes CMS für Ihre Inhalte. Intuitive Pflege ohne das Design zu gefährden."
|
||||
delay={0.3}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Status Line */}
|
||||
<div className="pt-8 flex flex-col md:flex-row items-center justify-between gap-6 border-t border-slate-100">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex -space-x-2">
|
||||
{[0, 1, 2].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-8 h-8 rounded-full border-2 border-white bg-slate-100"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Label className="text-slate-400 text-xs">
|
||||
Ihre Teams haben die volle Kontrolle.
|
||||
</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-green-500 animate-ping" />
|
||||
<MonoLabel className="text-slate-900 font-bold tracking-tighter">
|
||||
PROJECT STATUS: PRODUCTION_READY
|
||||
</MonoLabel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -4,3 +4,6 @@ export { BinaryStream } from "./BinaryStream";
|
||||
export { GradientMesh } from "./GradientMesh";
|
||||
export { CodeSnippet } from "./CodeSnippet";
|
||||
export { AbstractCircuit } from "./AbstractCircuit";
|
||||
export { CMSVisualizer } from "./CMSVisualizer";
|
||||
export { ArchitectureVisualizer } from "./ArchitectureVisualizer";
|
||||
export { ResultVisualizer } from "./ResultVisualizer";
|
||||
|
||||
Reference in New Issue
Block a user