|
| 1 | +"use client" |
| 2 | + |
| 3 | +import { useI18n } from "@/lib/i18n" |
| 4 | +import { SectionHeader } from "./reading-path" |
| 5 | + |
| 6 | +export function Teams() { |
| 7 | + const { t } = useI18n() |
| 8 | + |
| 9 | + return ( |
| 10 | + <section id="teams" className="py-20 md:py-28 px-6 border-t border-border"> |
| 11 | + <div className="mx-auto max-w-4xl"> |
| 12 | + <SectionHeader |
| 13 | + number="08" |
| 14 | + title={t("multi.title")} |
| 15 | + subtitle={t("multi.subtitle")} |
| 16 | + /> |
| 17 | + |
| 18 | + <div className="flex flex-col gap-8"> |
| 19 | + <div className="rounded-xl border border-border bg-card overflow-hidden"> |
| 20 | + <div className="px-5 pt-5 pb-2 flex items-baseline gap-3"> |
| 21 | + <span className="text-xs font-mono text-muted-foreground/50">A</span> |
| 22 | + <h3 className="text-sm font-mono font-semibold text-foreground">{t("multi.shared.title")}</h3> |
| 23 | + <p className="text-xs text-muted-foreground">{t("multi.shared.desc")}</p> |
| 24 | + </div> |
| 25 | + <div className="p-4 md:px-8 md:pb-4"> |
| 26 | + <SharedTapeDiagram /> |
| 27 | + </div> |
| 28 | + <div className="px-5 pb-5"> |
| 29 | + <p className="text-[11px] font-mono text-muted-foreground/70">{t("multi.shared.note")}</p> |
| 30 | + </div> |
| 31 | + </div> |
| 32 | + |
| 33 | + <div className="rounded-xl border border-border bg-card overflow-hidden"> |
| 34 | + <div className="px-5 pt-5 pb-2 flex items-baseline gap-3"> |
| 35 | + <span className="text-xs font-mono text-muted-foreground/50">B</span> |
| 36 | + <h3 className="text-sm font-mono font-semibold text-foreground">{t("multi.cross.title")}</h3> |
| 37 | + <p className="text-xs text-muted-foreground">{t("multi.cross.desc")}</p> |
| 38 | + </div> |
| 39 | + <div className="p-4 md:px-8 md:pb-4"> |
| 40 | + <CrossTapeDiagram /> |
| 41 | + </div> |
| 42 | + <div className="px-5 pb-5"> |
| 43 | + <p className="text-[11px] font-mono text-muted-foreground/70">{t("multi.cross.note")}</p> |
| 44 | + </div> |
| 45 | + </div> |
| 46 | + </div> |
| 47 | + </div> |
| 48 | + </section> |
| 49 | + ) |
| 50 | +} |
| 51 | + |
| 52 | +function SharedTapeDiagram() { |
| 53 | + return ( |
| 54 | + <svg viewBox="0 0 700 220" className="w-full" fill="none"> |
| 55 | + <defs> |
| 56 | + <marker id="ma-shared-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto"> |
| 57 | + <path d="M0 1L9 5L0 9" className="fill-none stroke-foreground" strokeWidth="1.5" /> |
| 58 | + </marker> |
| 59 | + </defs> |
| 60 | + |
| 61 | + <rect x="420" y="12" width="130" height="32" rx="6" className="fill-foreground" /> |
| 62 | + <text x="485" y="33" textAnchor="middle" className="fill-primary-foreground text-[12px] font-mono font-semibold"> |
| 63 | + Shared Tape |
| 64 | + </text> |
| 65 | + <line x1="485" y1="46" x2="485" y2="200" className="stroke-border" strokeWidth="1.5" strokeDasharray="5 4" /> |
| 66 | + |
| 67 | + {[ |
| 68 | + { name: "Team A", y: 45 }, |
| 69 | + { name: "Team B", y: 105 }, |
| 70 | + { name: "Team C", y: 165 }, |
| 71 | + ].map((agent) => ( |
| 72 | + <g key={agent.name}> |
| 73 | + <rect x="40" y={agent.y} width="110" height="30" rx="6" className="fill-foreground" /> |
| 74 | + <text x="95" y={agent.y + 20} textAnchor="middle" className="fill-primary-foreground text-[12px] font-mono font-semibold"> |
| 75 | + {agent.name} |
| 76 | + </text> |
| 77 | + <line x1="150" y1={agent.y + 15} x2="475" y2={agent.y + 15} className="stroke-foreground" strokeWidth="1.2" markerEnd="url(#ma-shared-arr)" /> |
| 78 | + </g> |
| 79 | + ))} |
| 80 | + |
| 81 | + {[ |
| 82 | + { label: "A:201", y: 62, className: "fill-accent/15 stroke-accent" }, |
| 83 | + { label: "B:202", y: 102, className: "fill-secondary stroke-border" }, |
| 84 | + { label: "C:203", y: 142, className: "fill-secondary/80 stroke-border" }, |
| 85 | + { label: "A:204", y: 182, className: "fill-accent/10 stroke-accent/60" }, |
| 86 | + ].map((entry) => ( |
| 87 | + <g key={entry.label}> |
| 88 | + <rect x="505" y={entry.y} width="60" height="20" rx="4" className={entry.className} strokeWidth="0.8" /> |
| 89 | + <text x="535" y={entry.y + 14} textAnchor="middle" className="fill-foreground text-[9px] font-mono"> |
| 90 | + {entry.label} |
| 91 | + </text> |
| 92 | + </g> |
| 93 | + ))} |
| 94 | + |
| 95 | + <text x="485" y="214" textAnchor="middle" className="fill-muted-foreground/40 text-[9px] font-mono"> |
| 96 | + append-only timeline |
| 97 | + </text> |
| 98 | + </svg> |
| 99 | + ) |
| 100 | +} |
| 101 | + |
| 102 | +function CrossTapeDiagram() { |
| 103 | + return ( |
| 104 | + <svg viewBox="0 0 700 230" className="w-full" fill="none"> |
| 105 | + <defs> |
| 106 | + <marker id="ma-cross-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto"> |
| 107 | + <path d="M0 1L9 5L0 9" className="fill-none stroke-accent" strokeWidth="1.5" /> |
| 108 | + </marker> |
| 109 | + </defs> |
| 110 | + |
| 111 | + <rect x="30" y="16" width="110" height="32" rx="6" className="fill-foreground" /> |
| 112 | + <text x="85" y="37" textAnchor="middle" className="fill-primary-foreground text-[12px] font-mono font-semibold">Team A</text> |
| 113 | + |
| 114 | + <rect x="560" y="16" width="110" height="32" rx="6" className="fill-foreground" /> |
| 115 | + <text x="615" y="37" textAnchor="middle" className="fill-primary-foreground text-[12px] font-mono font-semibold">Team B</text> |
| 116 | + |
| 117 | + <rect x="170" y="16" width="110" height="32" rx="6" className="fill-secondary" /> |
| 118 | + <text x="225" y="37" textAnchor="middle" className="fill-foreground text-[11px] font-mono font-semibold">Tape A</text> |
| 119 | + |
| 120 | + <rect x="420" y="16" width="110" height="32" rx="6" className="fill-secondary" /> |
| 121 | + <text x="475" y="37" textAnchor="middle" className="fill-foreground text-[11px] font-mono font-semibold">Tape B</text> |
| 122 | + |
| 123 | + <line x1="170" y1="80" x2="280" y2="80" className="stroke-border" strokeWidth="1.5" /> |
| 124 | + <line x1="420" y1="80" x2="530" y2="80" className="stroke-border" strokeWidth="1.5" /> |
| 125 | + |
| 126 | + {[ |
| 127 | + { x: 182, label: "A1" }, |
| 128 | + { x: 214, label: "A2" }, |
| 129 | + { x: 246, label: "A3" }, |
| 130 | + ].map((entry) => ( |
| 131 | + <g key={entry.label}> |
| 132 | + <rect x={entry.x} y="68" width="24" height="22" rx="4" className="fill-card stroke-border" strokeWidth="0.6" /> |
| 133 | + <text x={entry.x + 12} y="83" textAnchor="middle" className="fill-muted-foreground text-[8px] font-mono">{entry.label}</text> |
| 134 | + </g> |
| 135 | + ))} |
| 136 | + |
| 137 | + {[ |
| 138 | + { x: 432, label: "B1" }, |
| 139 | + { x: 464, label: "B2" }, |
| 140 | + { x: 496, label: "B3" }, |
| 141 | + ].map((entry) => ( |
| 142 | + <g key={entry.label}> |
| 143 | + <rect x={entry.x} y="68" width="24" height="22" rx="4" className="fill-card stroke-border" strokeWidth="0.6" /> |
| 144 | + <text x={entry.x + 12} y="83" textAnchor="middle" className="fill-muted-foreground text-[8px] font-mono">{entry.label}</text> |
| 145 | + </g> |
| 146 | + ))} |
| 147 | + |
| 148 | + <rect x="90" y="140" width="160" height="42" rx="8" className="fill-accent/10 stroke-accent" strokeWidth="1" /> |
| 149 | + <text x="170" y="165" textAnchor="middle" className="fill-accent text-[11px] font-mono font-semibold">View from Tape B</text> |
| 150 | + |
| 151 | + <rect x="450" y="140" width="160" height="42" rx="8" className="fill-accent/10 stroke-accent" strokeWidth="1" /> |
| 152 | + <text x="530" y="165" textAnchor="middle" className="fill-accent text-[11px] font-mono font-semibold">View from Tape A</text> |
| 153 | + |
| 154 | + <line x1="475" y1="92" x2="170" y2="140" className="stroke-accent" strokeWidth="1.2" strokeDasharray="5 4" markerEnd="url(#ma-cross-arr)" /> |
| 155 | + <line x1="225" y1="92" x2="530" y2="140" className="stroke-accent" strokeWidth="1.2" strokeDasharray="5 4" markerEnd="url(#ma-cross-arr)" /> |
| 156 | + |
| 157 | + <line x1="170" y1="140" x2="85" y2="58" className="stroke-accent/60" strokeWidth="1" markerEnd="url(#ma-cross-arr)" /> |
| 158 | + <line x1="530" y1="140" x2="615" y2="58" className="stroke-accent/60" strokeWidth="1" markerEnd="url(#ma-cross-arr)" /> |
| 159 | + |
| 160 | + <text x="350" y="208" textAnchor="middle" className="fill-muted-foreground/40 text-[9px] font-mono"> |
| 161 | + views assemble cross-tape context |
| 162 | + </text> |
| 163 | + </svg> |
| 164 | + ) |
| 165 | +} |
0 commit comments