algorembrant commited on
Commit
d2ac159
·
verified ·
1 Parent(s): d579b78

Upload 2 files

Browse files
Files changed (2) hide show
  1. CybberTicket.jsx +1407 -0
  2. CyberTicket.jsx +646 -0
CybberTicket.jsx ADDED
@@ -0,0 +1,1407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect, useRef } from "react";
2
+
3
+ /* ============================================================
4
+ TICKETPUNCH UI — Complete Cyberpunk Design System
5
+ Font: IBM Plex Mono | Palette: Dark / White / Gold / Red / Peach
6
+ ============================================================ */
7
+
8
+ const FontInjector = () => (
9
+ <style>{`
10
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&display=swap');
11
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
12
+ :root {
13
+ /* ── DARK ── */
14
+ --d-900: #060606;
15
+ --d-800: #0A0A0A;
16
+ --d-700: #0f0f0f;
17
+ --d-600: #1e1e1e;
18
+ --d-500: #2a2a2a;
19
+
20
+ /* ── WHITE ── */
21
+ --w-100: #FFFFFF;
22
+ --w-200: #EFEFEF;
23
+ --w-300: #CDCDCD;
24
+ --w-400: #AAAAAA;
25
+ --w-500: #888888;
26
+
27
+ /* ── GOLD ── */
28
+ --g-100: #FFF4CC;
29
+ --g-300: #FFD700;
30
+ --g-500: #C8960C;
31
+ --g-700: #7A5800;
32
+ --g-900: #3D2C00;
33
+
34
+ /* ── RED ── */
35
+ --r-100: #FFE5E5;
36
+ --r-300: #FF6666;
37
+ --r-500: #FF3333;
38
+ --r-700: #CC0000;
39
+ --r-900: #550000;
40
+
41
+ /* ── PEACH ── */
42
+ --p-100: #FFF0EB;
43
+ --p-300: #FFBFA8;
44
+ --p-500: #FF8C69;
45
+ --p-700: #C45A35;
46
+ --p-900: #5C2010;
47
+
48
+ /* ── SEMANTIC ALIASES ── */
49
+ --bg: var(--d-900);
50
+ --surface: var(--d-800);
51
+ --header: var(--d-700);
52
+ --border-1: var(--d-600);
53
+ --border-2: var(--d-500);
54
+ --text-primary: var(--w-100);
55
+ --text-6: #383838;
56
+
57
+ --font: 'IBM Plex Mono', monospace;
58
+ --tooth: 9px;
59
+ }
60
+ body { background: var(--bg); color: var(--text-primary); font-family: var(--font); }
61
+ ::-webkit-scrollbar { width: 4px; }
62
+ ::-webkit-scrollbar-track { background: var(--bg); }
63
+ ::-webkit-scrollbar-thumb { background: var(--border-2); }
64
+
65
+ @keyframes pulse-dot { 0%,100%{opacity:1} 50%{opacity:0.2} }
66
+ @keyframes scroll-up { 0%{transform:translateY(0)} 100%{transform:translateY(-50%)} }
67
+ @keyframes spin-slow { from{transform:rotate(0deg)} to{transform:rotate(360deg)} }
68
+ @keyframes progress-fill { from{width:0} to{width:var(--fill)} }
69
+ @keyframes toast-in { from{transform:translateX(120%);opacity:0} to{transform:translateX(0);opacity:1} }
70
+
71
+ .pulse-anim { animation: pulse-dot 1400ms ease-in-out infinite; }
72
+ .scroll-anim { animation: scroll-up 12s linear infinite; }
73
+ .spin-slow { animation: spin-slow 8s linear infinite; }
74
+ .toast-anim { animation: toast-in 0.3s ease forwards; }
75
+
76
+ .punched-frame { position: relative; }
77
+ .punched-frame::before,
78
+ .punched-frame::after {
79
+ content: '';
80
+ position: absolute;
81
+ left: 0; right: 0;
82
+ height: var(--tooth);
83
+ z-index: 20;
84
+ pointer-events: none;
85
+ background: repeating-linear-gradient(
86
+ 90deg,
87
+ transparent 0px, transparent 8px,
88
+ var(--bg) 8px, var(--bg) 18px
89
+ );
90
+ }
91
+ .punched-frame::before { top: 0; }
92
+ .punched-frame::after { bottom: 0; }
93
+ `}</style>
94
+ );
95
+
96
+ const GrainOverlay = ({ strength = 0.18 }) => {
97
+ const canvasRef = useRef(null);
98
+ useEffect(() => {
99
+ const canvas = canvasRef.current;
100
+ if (!canvas) return;
101
+ const ctx = canvas.getContext("2d");
102
+ const W = 256, H = 256;
103
+ canvas.width = W; canvas.height = H;
104
+ const imageData = ctx.createImageData(W, H);
105
+ const data = imageData.data;
106
+ for (let i = 0; i < data.length; i += 4) {
107
+ const v = (Math.random() * 255) | 0;
108
+ data[i] = data[i + 1] = data[i + 2] = v;
109
+ data[i + 3] = (strength * 255) | 0;
110
+ }
111
+ ctx.putImageData(imageData, 0, 0);
112
+ }, [strength]);
113
+ return (
114
+ <canvas ref={canvasRef} style={{
115
+ position: "absolute", inset: 0, width: "100%", height: "100%",
116
+ pointerEvents: "none", mixBlendMode: "overlay", opacity: 0.9, zIndex: 5
117
+ }} />
118
+ );
119
+ };
120
+
121
+ const GeometricOverlay = () => (
122
+ <svg style={{ position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", zIndex: 4, opacity: 0.07 }} preserveAspectRatio="xMidYMid slice">
123
+ <defs>
124
+ <pattern id="lattice" width="32" height="32" patternUnits="userSpaceOnUse">
125
+ <path d="M 32 0 L 0 0 0 32" fill="none" stroke="white" strokeWidth="0.5" />
126
+ <circle cx="0" cy="0" r="1" fill="white" opacity="0.5" />
127
+ </pattern>
128
+ </defs>
129
+ <rect width="100%" height="100%" fill="url(#lattice)" />
130
+ <circle cx="50%" cy="50%" r="80" fill="none" stroke="white" strokeWidth="0.5" />
131
+ <circle cx="50%" cy="50%" r="140" fill="none" stroke="white" strokeWidth="0.3" />
132
+ <line x1="50%" y1="0" x2="50%" y2="100%" stroke="white" strokeWidth="0.3" />
133
+ <line x1="0" y1="50%" x2="100%" y2="50%" stroke="white" strokeWidth="0.3" />
134
+ <polygon points="50%,10% 90%,90% 10%,90%" fill="none" stroke="white" strokeWidth="0.4" opacity="0.5" />
135
+ </svg>
136
+ );
137
+
138
+ const PunchHoles = () => (
139
+ <>
140
+ {[{ top: "3px", left: "4px" }, { top: "3px", right: "4px" }, { bottom: "3px", left: "4px" }, { bottom: "3px", right: "4px" }].map((pos, i) => (
141
+ <div key={i} style={{
142
+ position: "absolute", ...pos, width: 9, height: 9, borderRadius: "50%",
143
+ background: "radial-gradient(circle, var(--bg) 4px, transparent 4px)",
144
+ border: "1px solid var(--d-500)", zIndex: 25, pointerEvents: "none",
145
+ }} />
146
+ ))}
147
+ </>
148
+ );
149
+
150
+ const Punched = ({ children, style = {}, className = "" }) => (
151
+ <div className={`punched-frame ${className}`} style={{ position: "relative", ...style }}>
152
+ <PunchHoles />
153
+ {children}
154
+ </div>
155
+ );
156
+
157
+ const TicketShell = ({ children, stubHeight = 60, style = {} }) => (
158
+ <Punched style={style}>
159
+ <div style={{
160
+ background: "var(--surface)", border: "1px solid var(--border-1)",
161
+ boxShadow: "0 40px 100px rgba(0,0,0,0.95)", position: "relative", overflow: "hidden"
162
+ }}>
163
+ <svg style={{ position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", zIndex: 6 }}>
164
+ <rect x="8" y="8" width="calc(100% - 16px)" height="calc(100% - 16px)"
165
+ fill="none" stroke="var(--d-500)" strokeWidth="1" strokeDasharray="4 3" />
166
+ </svg>
167
+ <GrainOverlay />
168
+ <GeometricOverlay />
169
+ {stubHeight > 0 && (
170
+ <div style={{
171
+ position: "absolute", bottom: stubHeight, left: 0, right: 0, zIndex: 8,
172
+ borderTop: "1px dashed var(--border-2)", display: "flex", alignItems: "center", justifyContent: "center"
173
+ }}>
174
+ <span style={{
175
+ background: "var(--surface)", padding: "0 8px", fontSize: 7, color: "var(--w-500)",
176
+ letterSpacing: "0.2em", fontFamily: "var(--font)"
177
+ }}>✂ TEAR</span>
178
+ </div>
179
+ )}
180
+ {children}
181
+ </div>
182
+ </Punched>
183
+ );
184
+
185
+ const Barcode = ({ value = "OMEGA-7749-XX", width = 120, height = 28 }) => {
186
+ const bars = [];
187
+ for (let i = 0; i < 48; i++)
188
+ bars.push({ x: i * (width / 48), w: Math.random() > 0.5 ? 1.5 : 0.8, o: 0.4 + Math.random() * 0.6 });
189
+ return (
190
+ <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 2 }}>
191
+ <svg width={width} height={height} style={{ display: "block" }}>
192
+ {bars.map((b, i) => <rect key={i} x={b.x} y={0} width={b.w} height={height} fill="var(--w-300)" opacity={b.o} />)}
193
+ </svg>
194
+ <span style={{ fontSize: 6, letterSpacing: "0.28em", color: "var(--w-500)", fontFamily: "var(--font)", textTransform: "uppercase" }}>{value}</span>
195
+ </div>
196
+ );
197
+ };
198
+
199
+ const StatusPill = ({ status = "active", label, pulse = true }) => {
200
+ const colors = {
201
+ active: "var(--g-300)",
202
+ inactive: "var(--w-500)",
203
+ warning: "var(--p-500)",
204
+ danger: "var(--r-500)",
205
+ pending: "var(--g-100)",
206
+ };
207
+ const color = colors[status] || colors.active;
208
+ return (
209
+ <div style={{
210
+ display: "inline-flex", alignItems: "center", gap: 6, padding: "3px 8px",
211
+ border: `1px solid ${color}33`, background: `${color}0d`, borderRadius: 2
212
+ }}>
213
+ <div className={pulse ? "pulse-anim" : ""} style={{
214
+ width: 5, height: 5, borderRadius: "50%",
215
+ background: color, boxShadow: `0 0 6px ${color}`
216
+ }} />
217
+ <span style={{ fontSize: 8, letterSpacing: "0.28em", color, fontFamily: "var(--font)", textTransform: "uppercase" }}>
218
+ {label || status}
219
+ </span>
220
+ </div>
221
+ );
222
+ };
223
+
224
+ const TerminalMask = ({ lines = [], size = 120 }) => {
225
+ const defaultLines = [
226
+ "CLASSIFIED // OMEGA PROTOCOL", "ACCESS GRANTED — NEXUS-7", "THREAT LEVEL: CRITICAL",
227
+ "SYNC: 99.7% COMPLETE", "FIREWALL: ACTIVE", "ENCRYPTION: AES-512",
228
+ "NODE: 192.168.0.77", "UPTIME: 847:22:11", "AGENT: SPECTRE-9", "STATUS: OPERATIONAL", ...lines
229
+ ];
230
+ const doubled = [...defaultLines, ...defaultLines];
231
+ return (
232
+ <div style={{
233
+ width: size, height: size, borderRadius: "50%", overflow: "hidden", position: "relative",
234
+ border: "1px solid var(--d-500)", background: "var(--bg)",
235
+ boxShadow: "inset 0 0 20px rgba(0,0,0,0.8), 0 0 20px rgba(0,0,0,0.6)"
236
+ }}>
237
+ <div className="scroll-anim" style={{ position: "absolute", width: "100%", paddingTop: 8 }}>
238
+ {doubled.map((line, i) => (
239
+ <div key={i} style={{
240
+ padding: "1.5px 8px", fontSize: 6.5, letterSpacing: "0.18em",
241
+ color: i % 3 === 0 ? "var(--g-300)" : "var(--w-500)",
242
+ fontFamily: "var(--font)", textTransform: "uppercase", whiteSpace: "nowrap", overflow: "hidden"
243
+ }}>{line}</div>
244
+ ))}
245
+ </div>
246
+ <div style={{
247
+ position: "absolute", inset: 0, borderRadius: "50%",
248
+ background: "radial-gradient(circle, transparent 40%, var(--bg) 80%)", pointerEvents: "none"
249
+ }} />
250
+ </div>
251
+ );
252
+ };
253
+
254
+ const Divider = ({ label }) => (
255
+ <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "4px 0" }}>
256
+ <div style={{ flex: 1, height: 1, background: "var(--border-1)" }} />
257
+ {label
258
+ ? <span style={{ fontSize: 7, letterSpacing: "0.28em", color: "var(--w-500)", textTransform: "uppercase", fontFamily: "var(--font)" }}>{label}</span>
259
+ : <svg width="8" height="8"><polygon points="4,0 8,4 4,8 0,4" fill="var(--d-500)" /></svg>
260
+ }
261
+ <div style={{ flex: 1, height: 1, background: "var(--border-1)" }} />
262
+ </div>
263
+ );
264
+
265
+ const SectionLabel = ({ children, sub }) => (
266
+ <div style={{ marginBottom: 20 }}>
267
+ <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
268
+ <div style={{ width: 2, height: 14, background: "var(--g-300)" }} />
269
+ <span style={{
270
+ fontSize: 9.5, fontWeight: 700, letterSpacing: "0.34em", textTransform: "uppercase",
271
+ fontFamily: "var(--font)", color: "var(--w-100)"
272
+ }}>{children}</span>
273
+ </div>
274
+ {sub && <div style={{
275
+ marginTop: 4, marginLeft: 10, fontSize: 7, letterSpacing: "0.2em",
276
+ color: "var(--g-700)", textTransform: "uppercase", fontFamily: "var(--font)"
277
+ }}>{sub}</div>}
278
+ </div>
279
+ );
280
+
281
+ const Micro = ({ children, color = "var(--text-6)" }) => (
282
+ <span style={{ fontSize: 7, letterSpacing: "0.28em", color, fontFamily: "var(--font)", textTransform: "uppercase" }}>{children}</span>
283
+ );
284
+
285
+ // ── 1. HEADER ──────────────────────────────────────────────────
286
+ const Header = ({ activeTab, setActiveTab }) => {
287
+ const navItems = ["DASHBOARD", "INTEL", "ASSETS", "COMMS", "SYSTEM"];
288
+ return (
289
+ <Punched style={{ zIndex: 100 }}>
290
+ <div style={{
291
+ position: "relative", background: "var(--header)", borderBottom: "1px solid var(--border-1)",
292
+ height: 52, display: "flex", alignItems: "center", padding: "0 24px", gap: 24, overflow: "hidden"
293
+ }}>
294
+ <GrainOverlay strength={0.1} />
295
+ <div style={{ display: "flex", alignItems: "center", gap: 10, zIndex: 7 }}>
296
+ <svg width="18" height="18" viewBox="0 0 18 18">
297
+ <polygon points="9,1 17,5 17,13 9,17 1,13 1,5" fill="none" stroke="var(--g-300)" strokeWidth="1.5" />
298
+ <polygon points="9,5 13,7 13,11 9,13 5,11 5,7" fill="var(--g-500)" opacity="0.3" />
299
+ <circle cx="9" cy="9" r="2" fill="var(--g-300)" />
300
+ </svg>
301
+ <div>
302
+ <div style={{
303
+ fontSize: 11, fontWeight: 700, letterSpacing: "0.22em", textTransform: "uppercase",
304
+ fontFamily: "var(--font)", color: "var(--w-100)"
305
+ }}>NEXUS</div>
306
+ <div style={{ fontSize: 6.5, letterSpacing: "0.34em", color: "var(--g-500)", textTransform: "uppercase", fontFamily: "var(--font)" }}>OMEGA PROTOCOL</div>
307
+ </div>
308
+ </div>
309
+ <div style={{ width: 1, height: 28, background: "var(--border-1)", zIndex: 7 }} />
310
+ <div style={{ display: "flex", gap: 2, zIndex: 7 }}>
311
+ {navItems.map(item => (
312
+ <button key={item} onClick={() => setActiveTab(item)} style={{
313
+ background: activeTab === item ? "rgba(255,215,0,0.06)" : "transparent",
314
+ border: activeTab === item ? "1px solid var(--g-700)" : "1px solid transparent",
315
+ color: activeTab === item ? "var(--g-300)" : "var(--w-500)",
316
+ padding: "5px 12px", cursor: "pointer", fontFamily: "var(--font)",
317
+ fontSize: 8, letterSpacing: "0.22em", textTransform: "uppercase", transition: "all 0.2s"
318
+ }}>
319
+ {item}
320
+ {activeTab === item && <div style={{ width: "100%", height: 1, background: "var(--g-300)", marginTop: 2 }} />}
321
+ </button>
322
+ ))}
323
+ </div>
324
+ <div style={{ flex: 1 }} />
325
+ <div style={{ display: "flex", alignItems: "center", gap: 14, zIndex: 7 }}>
326
+ <StatusPill status="active" label="SYS ONLINE" />
327
+ <div style={{ textAlign: "right" }}>
328
+ <div style={{ fontSize: 8, letterSpacing: "0.2em", color: "var(--w-300)", textTransform: "uppercase", fontFamily: "var(--font)" }}>AGT-09</div>
329
+ <div style={{ fontSize: 6.5, letterSpacing: "0.18em", color: "var(--g-500)", textTransform: "uppercase", fontFamily: "var(--font)" }}>CLEARANCE: OMEGA</div>
330
+ </div>
331
+ <div style={{
332
+ width: 28, height: 28, borderRadius: "50%", border: "1px solid var(--g-700)",
333
+ background: "var(--surface)", display: "flex", alignItems: "center", justifyContent: "center",
334
+ fontSize: 9, color: "var(--g-300)", fontFamily: "var(--font)"
335
+ }}>Ω</div>
336
+ </div>
337
+ </div>
338
+ </Punched>
339
+ );
340
+ };
341
+
342
+ // ── 2. BUTTON ──────────────────────────────────────────────────
343
+ const Button = ({ variant = "primary", children, icon, size = "md", disabled, onClick }) => {
344
+ const sizes = { sm: "4px 10px", md: "7px 16px", lg: "10px 22px" };
345
+ const fontSizes = { sm: 7.5, md: 8.5, lg: 9.5 };
346
+ const bases = {
347
+ primary: { bg: "var(--g-300)", color: "var(--d-900)", border: "1px solid var(--g-300)" },
348
+ secondary: { bg: "rgba(255,215,0,0.06)", color: "var(--g-300)", border: "1px solid var(--g-700)" },
349
+ outline: { bg: "transparent", color: "var(--w-100)", border: "1px solid var(--w-300)" },
350
+ ghost: { bg: "transparent", color: "var(--w-500)", border: "1px solid transparent" },
351
+ danger: { bg: "rgba(255,51,51,0.10)", color: "var(--r-500)", border: "1px solid var(--r-700)" },
352
+ success: { bg: "rgba(255,215,0,0.08)", color: "var(--g-300)", border: "1px solid var(--g-700)" },
353
+ };
354
+ const s = bases[variant] || bases.primary;
355
+ return (
356
+ <button onClick={onClick} disabled={disabled} style={{
357
+ background: s.bg, color: s.color, border: s.border,
358
+ padding: sizes[size], fontFamily: "var(--font)",
359
+ fontSize: fontSizes[size], letterSpacing: "0.22em", textTransform: "uppercase",
360
+ cursor: disabled ? "not-allowed" : "pointer", opacity: disabled ? 0.4 : 1,
361
+ display: "inline-flex", alignItems: "center", gap: 6,
362
+ position: "relative", overflow: "hidden", transition: "all 0.2s", outline: "none",
363
+ }}>
364
+ {["top:2px;left:2px", "top:2px;right:2px", "bottom:2px;left:2px", "bottom:2px;right:2px"].map((pos, i) => {
365
+ const st = pos.split(";").reduce((a, p) => { const [k, v] = p.split(":"); a[k] = v; return a; }, {});
366
+ return <div key={i} style={{ position: "absolute", ...st, width: 2, height: 2, background: s.color, opacity: 0.5 }} />;
367
+ })}
368
+ {icon && <span style={{ fontSize: fontSizes[size] * 1.1 }}>{icon}</span>}
369
+ {children}
370
+ </button>
371
+ );
372
+ };
373
+
374
+ // ── 3. INPUT ───────────────────────────────────────────────────
375
+ const Input = ({ placeholder, label, type = "text", value, onChange, prefix, suffix, hint }) => (
376
+ <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
377
+ {label && <label style={{ fontSize: 7.5, letterSpacing: "0.28em", color: "var(--g-500)", textTransform: "uppercase", fontFamily: "var(--font)" }}>{label}</label>}
378
+ <div style={{
379
+ position: "relative", background: "var(--surface)", border: "1px solid var(--border-1)",
380
+ display: "flex", alignItems: "center", overflow: "hidden"
381
+ }}>
382
+ {prefix && <span style={{ padding: "0 8px", fontSize: 8, color: "var(--g-500)", fontFamily: "var(--font)", borderRight: "1px solid var(--border-1)" }}>{prefix}</span>}
383
+ <input type={type} placeholder={placeholder} value={value} onChange={onChange} style={{
384
+ flex: 1, background: "transparent", border: "none", outline: "none",
385
+ color: "var(--w-100)", fontFamily: "var(--font)", fontSize: 9, letterSpacing: "0.14em", padding: "9px 12px",
386
+ }} />
387
+ {suffix && <span style={{ padding: "0 8px", fontSize: 8, color: "var(--g-500)", fontFamily: "var(--font)", borderLeft: "1px solid var(--border-1)" }}>{suffix}</span>}
388
+ <div style={{ position: "absolute", inset: 2, border: "1px dashed var(--border-1)", pointerEvents: "none" }} />
389
+ </div>
390
+ {hint && <div style={{ fontSize: 7, letterSpacing: "0.18em", color: "var(--g-700)", fontFamily: "var(--font)", textTransform: "uppercase" }}>{hint}</div>}
391
+ </div>
392
+ );
393
+
394
+ // ── 4. CARD ────────────────────────────────────────────────────
395
+ const Card = ({ children, title, sub, tag, style = {} }) => (
396
+ <Punched style={style}>
397
+ <div style={{ position: "relative", background: "var(--surface)", border: "1px solid var(--border-1)", overflow: "hidden" }}>
398
+ <GrainOverlay strength={0.12} />
399
+ {["top:0;left:0", "top:0;right:0", "bottom:0;left:0", "bottom:0;right:0"].map((pos, i) => {
400
+ const st = pos.split(";").reduce((a, p) => { const [k, v] = p.split(":"); a[k] = v; return a; }, {});
401
+ return (
402
+ <div key={i} style={{
403
+ position: "absolute", ...st, width: 12, height: 12, zIndex: 7,
404
+ borderTop: i < 2 ? "1px solid var(--g-700)" : "none",
405
+ borderBottom: i >= 2 ? "1px solid var(--g-700)" : "none",
406
+ borderLeft: (i === 0 || i === 2) ? "1px solid var(--g-700)" : "none",
407
+ borderRight: (i === 1 || i === 3) ? "1px solid var(--g-700)" : "none",
408
+ }} />
409
+ );
410
+ })}
411
+ {(title || sub || tag) && (
412
+ <div style={{ padding: "10px 14px 8px", borderBottom: "1px solid var(--border-1)", position: "relative", zIndex: 7 }}>
413
+ <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
414
+ <div>
415
+ {title && <div style={{
416
+ fontSize: 9.5, fontWeight: 600, letterSpacing: "0.22em", textTransform: "uppercase",
417
+ fontFamily: "var(--font)", color: "var(--w-100)"
418
+ }}>{title}</div>}
419
+ {sub && <div style={{
420
+ fontSize: 7, letterSpacing: "0.18em", color: "var(--g-500)", textTransform: "uppercase",
421
+ fontFamily: "var(--font)", marginTop: 3
422
+ }}>{sub}</div>}
423
+ </div>
424
+ {tag && <div style={{
425
+ fontSize: 7, padding: "2px 7px", border: "1px solid var(--g-700)", color: "var(--g-500)",
426
+ letterSpacing: "0.2em", textTransform: "uppercase", fontFamily: "var(--font)"
427
+ }}>{tag}</div>}
428
+ </div>
429
+ </div>
430
+ )}
431
+ <div style={{ padding: 14, position: "relative", zIndex: 7 }}>{children}</div>
432
+ </div>
433
+ </Punched>
434
+ );
435
+
436
+ // ── 5. BADGE ───────────────────────────────────────────────────
437
+ const Badge = ({ children, variant = "default" }) => {
438
+ const vars = {
439
+ default: { bg: "var(--surface)", color: "var(--w-400)", border: "1px solid var(--border-2)" },
440
+ active: { bg: "rgba(255,215,0,0.08)", color: "var(--g-300)", border: "1px solid var(--g-700)" },
441
+ danger: { bg: "rgba(255,51,51,0.08)", color: "var(--r-500)", border: "1px solid var(--r-700)" },
442
+ warning: { bg: "rgba(255,140,105,0.08)", color: "var(--p-500)", border: "1px solid var(--p-700)" },
443
+ omega: { bg: "rgba(255,244,204,0.05)", color: "var(--g-100)", border: "1px solid var(--g-700)" },
444
+ };
445
+ const v = vars[variant] || vars.default;
446
+ return (
447
+ <span style={{
448
+ ...v, display: "inline-block", padding: "2px 7px", fontSize: 7,
449
+ letterSpacing: "0.22em", textTransform: "uppercase", fontFamily: "var(--font)"
450
+ }}>{children}</span>
451
+ );
452
+ };
453
+
454
+ // ── 6. PROGRESS BAR ────────────────────────────────────────────
455
+ const ProgressBar = ({ value = 65, label, color = "var(--g-300)" }) => (
456
+ <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
457
+ {label && (
458
+ <div style={{ display: "flex", justifyContent: "space-between" }}>
459
+ <Micro color="var(--w-500)">{label}</Micro>
460
+ <Micro color="var(--g-500)">{value}%</Micro>
461
+ </div>
462
+ )}
463
+ <div style={{ height: 3, background: "var(--border-1)", position: "relative", overflow: "hidden" }}>
464
+ <div style={{
465
+ "--fill": `${value}%`, width: `${value}%`, height: "100%", background: color,
466
+ animation: "progress-fill 1.5s ease forwards", boxShadow: `0 0 8px ${color}`
467
+ }} />
468
+ {[25, 50, 75].map(t => (
469
+ <div key={t} style={{ position: "absolute", top: 0, left: `${t}%`, width: 1, height: "100%", background: "var(--border-2)" }} />
470
+ ))}
471
+ </div>
472
+ </div>
473
+ );
474
+
475
+ // ── 7. SPINNER ─────────────────────────────────────────────────
476
+ const Spinner = ({ size = 32 }) => (
477
+ <div style={{ position: "relative", width: size, height: size }}>
478
+ <div className="spin-slow" style={{
479
+ width: "100%", height: "100%",
480
+ border: "1px solid var(--border-2)", borderTop: "1px solid var(--g-300)", borderRadius: "50%"
481
+ }} />
482
+ <div style={{ position: "absolute", inset: 4, border: "1px dashed var(--g-700)", borderRadius: "50%" }} />
483
+ <div style={{
484
+ position: "absolute", inset: "50%", transform: "translate(-50%,-50%)",
485
+ width: 4, height: 4, background: "var(--g-300)", borderRadius: "50%"
486
+ }} />
487
+ </div>
488
+ );
489
+
490
+ // ── 8. TABS ────────────────────────────────────────────────────
491
+ const Tabs = ({ tabs, active, onSelect }) => (
492
+ <div style={{ borderBottom: "1px solid var(--border-1)", display: "flex", gap: 0 }}>
493
+ {tabs.map((tab, i) => (
494
+ <button key={i} onClick={() => onSelect(i)} style={{
495
+ background: active === i ? "rgba(255,215,0,0.04)" : "transparent",
496
+ border: "none", borderBottom: active === i ? "1px solid var(--g-300)" : "1px solid transparent",
497
+ color: active === i ? "var(--g-300)" : "var(--w-500)",
498
+ padding: "8px 16px", cursor: "pointer", fontFamily: "var(--font)",
499
+ fontSize: 8, letterSpacing: "0.22em", textTransform: "uppercase", position: "relative", marginBottom: -1,
500
+ }}>
501
+ {active === i && <div style={{ position: "absolute", top: 0, left: 0, right: 0, height: 1, background: "var(--g-700)" }} />}
502
+ {tab}
503
+ </button>
504
+ ))}
505
+ </div>
506
+ );
507
+
508
+ // ── 9. ACCORDION ───────────────────────────────────────────────
509
+ const AccordionItem = ({ title, children }) => {
510
+ const [open, setOpen] = useState(false);
511
+ return (
512
+ <div style={{ borderBottom: "1px solid var(--border-1)" }}>
513
+ <button onClick={() => setOpen(!open)} style={{
514
+ width: "100%", background: "transparent", border: "none", padding: "10px 14px",
515
+ display: "flex", justifyContent: "space-between", alignItems: "center",
516
+ cursor: "pointer", color: "var(--w-300)", fontFamily: "var(--font)",
517
+ fontSize: 8.5, letterSpacing: "0.22em", textTransform: "uppercase",
518
+ }}>
519
+ <span>{title}</span>
520
+ <svg width="10" height="10" style={{ transform: open ? "rotate(180deg)" : "rotate(0deg)", transition: "transform 0.2s" }}>
521
+ <polygon points="5,7 0,0 10,0" fill="var(--g-500)" />
522
+ </svg>
523
+ </button>
524
+ {open && (
525
+ <div style={{
526
+ padding: "8px 14px 12px", color: "var(--w-500)", fontSize: 8.5, lineHeight: 1.7,
527
+ fontFamily: "var(--font)", letterSpacing: "0.1em", borderTop: "1px dashed var(--border-1)"
528
+ }}>
529
+ {children}
530
+ </div>
531
+ )}
532
+ </div>
533
+ );
534
+ };
535
+
536
+ // ── 10. TOOLTIP ────────────────────────────────────────────────
537
+ const Tooltip = ({ label, children }) => {
538
+ const [show, setShow] = useState(false);
539
+ return (
540
+ <div style={{ position: "relative", display: "inline-block" }}
541
+ onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)}>
542
+ {children}
543
+ {show && (
544
+ <div style={{
545
+ position: "absolute", bottom: "calc(100% + 6px)", left: "50%", transform: "translateX(-50%)",
546
+ background: "var(--header)", border: "1px solid var(--g-700)", padding: "5px 10px",
547
+ whiteSpace: "nowrap", zIndex: 200, pointerEvents: "none"
548
+ }}>
549
+ <span style={{
550
+ fontSize: 7.5, letterSpacing: "0.18em", color: "var(--g-300)",
551
+ fontFamily: "var(--font)", textTransform: "uppercase"
552
+ }}>{label}</span>
553
+ <div style={{
554
+ position: "absolute", bottom: -4, left: "50%", transform: "translateX(-50%)", width: 6, height: 4,
555
+ background: "var(--header)", borderRight: "1px solid var(--g-700)", borderBottom: "1px solid var(--g-700)",
556
+ transformOrigin: "center", rotate: "45deg"
557
+ }} />
558
+ </div>
559
+ )}
560
+ </div>
561
+ );
562
+ };
563
+
564
+ // ── 11. DATA TABLE ─────────────────────────────────────────────
565
+ const DataTable = ({ columns, rows }) => (
566
+ <Punched>
567
+ <div style={{ border: "1px solid var(--border-1)", overflow: "hidden", position: "relative" }}>
568
+ <GrainOverlay strength={0.08} />
569
+ <div style={{
570
+ display: "grid", gridTemplateColumns: `repeat(${columns.length}, 1fr)`,
571
+ borderBottom: "1px solid var(--border-2)", background: "var(--header)", position: "relative", zIndex: 7
572
+ }}>
573
+ {columns.map((col, i) => (
574
+ <div key={i} style={{
575
+ padding: "8px 12px", fontSize: 7.5, letterSpacing: "0.22em",
576
+ textTransform: "uppercase", color: "var(--g-500)", fontFamily: "var(--font)",
577
+ borderRight: i < columns.length - 1 ? "1px solid var(--border-1)" : "none"
578
+ }}>
579
+ {col}
580
+ </div>
581
+ ))}
582
+ </div>
583
+ {rows.map((row, ri) => (
584
+ <div key={ri} style={{
585
+ display: "grid", gridTemplateColumns: `repeat(${columns.length}, 1fr)`,
586
+ borderBottom: ri < rows.length - 1 ? "1px solid var(--border-1)" : "none",
587
+ background: ri % 2 === 0 ? "transparent" : "rgba(255,215,0,0.01)", position: "relative", zIndex: 7
588
+ }}>
589
+ {row.map((cell, ci) => (
590
+ <div key={ci} style={{
591
+ padding: "7px 12px", fontSize: 8, letterSpacing: "0.12em",
592
+ color: ci === 0 ? "var(--w-200)" : "var(--w-500)", fontFamily: "var(--font)",
593
+ borderRight: ci < row.length - 1 ? "1px solid var(--border-1)" : "none"
594
+ }}>
595
+ {cell}
596
+ </div>
597
+ ))}
598
+ </div>
599
+ ))}
600
+ </div>
601
+ </Punched>
602
+ );
603
+
604
+ // ── 12. TOGGLE ─────────────────────────────────────────────────
605
+ const Toggle = ({ checked, onChange, label }) => (
606
+ <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
607
+ <div onClick={onChange} style={{
608
+ cursor: "pointer", width: 40, height: 16, position: "relative",
609
+ background: checked ? "rgba(255,215,0,0.1)" : "var(--surface)",
610
+ border: `1px solid ${checked ? "var(--g-700)" : "var(--border-1)"}`
611
+ }}>
612
+ {[...Array(8)].map((_, i) => (
613
+ <div key={i} style={{
614
+ position: "absolute", top: 2, bottom: 2, left: 4 + i * 4, width: 1,
615
+ background: "var(--border-2)", opacity: checked ? 1 : 0.4
616
+ }} />
617
+ ))}
618
+ <div style={{
619
+ position: "absolute", top: 1, width: 12, height: 12,
620
+ background: checked ? "var(--g-300)" : "var(--border-2)",
621
+ left: checked ? "calc(100% - 14px)" : 1,
622
+ transition: "all 0.2s", boxShadow: checked ? "0 0 8px var(--g-500)" : "none",
623
+ display: "flex", alignItems: "center", justifyContent: "center",
624
+ fontSize: 5, color: checked ? "var(--d-900)" : "transparent"
625
+ }}>■</div>
626
+ </div>
627
+ {label && <span style={{
628
+ fontSize: 8, letterSpacing: "0.18em", color: "var(--w-400)",
629
+ fontFamily: "var(--font)", textTransform: "uppercase"
630
+ }}>{label}</span>}
631
+ </div>
632
+ );
633
+
634
+ // ── 13. ALERT ──────────────────────────────────────────────────
635
+ const Alert = ({ type = "info", title, message, onClose }) => {
636
+ const types = {
637
+ info: { color: "var(--w-300)", border: "var(--border-2)", icon: "◈" },
638
+ success: { color: "var(--g-300)", border: "var(--g-700)", icon: "✓" },
639
+ warning: { color: "var(--p-500)", border: "var(--p-700)", icon: "⚠" },
640
+ danger: { color: "var(--r-500)", border: "var(--r-700)", icon: "✕" },
641
+ };
642
+ const t = types[type] || types.info;
643
+ return (
644
+ <Punched>
645
+ <div className="toast-anim" style={{
646
+ background: "var(--surface)", border: `1px solid ${t.border}`,
647
+ padding: "10px 14px", position: "relative", overflow: "hidden", display: "flex", gap: 10, alignItems: "flex-start"
648
+ }}>
649
+ <GrainOverlay strength={0.1} />
650
+ <span style={{ fontSize: 14, color: t.color, zIndex: 7 }}>{t.icon}</span>
651
+ <div style={{ flex: 1, zIndex: 7 }}>
652
+ {title && <div style={{
653
+ fontSize: 9, fontWeight: 600, letterSpacing: "0.2em", color: t.color,
654
+ textTransform: "uppercase", fontFamily: "var(--font)", marginBottom: 3
655
+ }}>{title}</div>}
656
+ <div style={{ fontSize: 8, letterSpacing: "0.14em", color: "var(--w-500)", fontFamily: "var(--font)" }}>{message}</div>
657
+ </div>
658
+ {onClose && <button onClick={onClose} style={{
659
+ background: "none", border: "none",
660
+ color: "var(--w-500)", cursor: "pointer", fontSize: 10, zIndex: 7
661
+ }}>×</button>}
662
+ </div>
663
+ </Punched>
664
+ );
665
+ };
666
+
667
+ // ── 14. BREADCRUMBS ────────────────────────────────────────────
668
+ const Breadcrumbs = ({ items }) => (
669
+ <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
670
+ {items.map((item, i) => (
671
+ <div key={i} style={{ display: "flex", alignItems: "center", gap: 6 }}>
672
+ <span style={{
673
+ fontSize: 8, letterSpacing: "0.18em",
674
+ color: i === items.length - 1 ? "var(--g-300)" : "var(--w-500)",
675
+ textTransform: "uppercase", fontFamily: "var(--font)", cursor: i < items.length - 1 ? "pointer" : "default"
676
+ }}>
677
+ {item}
678
+ </span>
679
+ {i < items.length - 1 && (
680
+ <svg width="6" height="6"><polygon points="3,0 6,3 3,6 0,3" fill="var(--g-700)" /></svg>
681
+ )}
682
+ </div>
683
+ ))}
684
+ </div>
685
+ );
686
+
687
+ // ── 15. STEPPER ────────────────────────────────────────────────
688
+ const Stepper = ({ steps, current }) => (
689
+ <div style={{ display: "flex", alignItems: "center" }}>
690
+ {steps.map((step, i) => (
691
+ <div key={i} style={{ display: "flex", alignItems: "center", flex: i < steps.length - 1 ? 1 : "none" }}>
692
+ <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4 }}>
693
+ <div style={{
694
+ width: 24, height: 24,
695
+ border: `1px solid ${i <= current ? "var(--g-300)" : "var(--border-2)"}`,
696
+ background: i < current ? "var(--g-300)" : i === current ? "rgba(255,215,0,0.1)" : "transparent",
697
+ display: "flex", alignItems: "center", justifyContent: "center",
698
+ fontSize: 7.5, color: i < current ? "var(--d-900)" : i === current ? "var(--g-300)" : "var(--w-500)",
699
+ fontFamily: "var(--font)", fontWeight: 700, letterSpacing: "0.1em"
700
+ }}>
701
+ {i < current ? "✓" : i + 1}
702
+ </div>
703
+ <span style={{
704
+ fontSize: 7, letterSpacing: "0.16em",
705
+ color: i <= current ? "var(--g-300)" : "var(--w-500)",
706
+ textTransform: "uppercase", fontFamily: "var(--font)", whiteSpace: "nowrap"
707
+ }}>{step}</span>
708
+ </div>
709
+ {i < steps.length - 1 && (
710
+ <div style={{
711
+ flex: 1, height: 1, background: i < current ? "var(--g-500)" : "var(--border-1)",
712
+ margin: "0 8px", marginBottom: 14
713
+ }} />
714
+ )}
715
+ </div>
716
+ ))}
717
+ </div>
718
+ );
719
+
720
+ // ── 16. SELECT ─────────────────────────────────────────────────
721
+ const Select = ({ label, options, value, onChange }) => {
722
+ const [open, setOpen] = useState(false);
723
+ return (
724
+ <div style={{ position: "relative", display: "flex", flexDirection: "column", gap: 5 }}>
725
+ {label && <label style={{
726
+ fontSize: 7.5, letterSpacing: "0.28em", color: "var(--g-500)",
727
+ textTransform: "uppercase", fontFamily: "var(--font)"
728
+ }}>{label}</label>}
729
+ <div onClick={() => setOpen(!open)} style={{
730
+ background: "var(--surface)", border: "1px solid var(--border-1)",
731
+ padding: "9px 12px", cursor: "pointer", display: "flex", justifyContent: "space-between",
732
+ alignItems: "center", position: "relative"
733
+ }}>
734
+ <span style={{
735
+ fontSize: 9, letterSpacing: "0.14em", fontFamily: "var(--font)",
736
+ color: value ? "var(--w-100)" : "var(--w-500)"
737
+ }}>
738
+ {value || "— SELECT OPTION —"}
739
+ </span>
740
+ <svg width="8" height="8" style={{ transform: open ? "rotate(180deg)" : "none", transition: "transform 0.2s" }}>
741
+ <polygon points="4,6 0,0 8,0" fill="var(--g-500)" />
742
+ </svg>
743
+ <div style={{ position: "absolute", inset: 2, border: "1px dashed var(--border-1)", pointerEvents: "none" }} />
744
+ </div>
745
+ {open && (
746
+ <div style={{
747
+ position: "absolute", top: "calc(100% + 2px)", left: 0, right: 0, background: "var(--header)",
748
+ border: "1px solid var(--g-700)", zIndex: 100, overflow: "hidden"
749
+ }}>
750
+ {options.map((opt, i) => (
751
+ <div key={i} onClick={() => { onChange(opt); setOpen(false); }} style={{
752
+ padding: "8px 12px", cursor: "pointer", fontSize: 8.5, letterSpacing: "0.14em",
753
+ fontFamily: "var(--font)", color: "var(--w-400)", textTransform: "uppercase",
754
+ borderBottom: i < options.length - 1 ? "1px solid var(--border-1)" : "none", transition: "background 0.1s",
755
+ }}
756
+ onMouseEnter={e => e.currentTarget.style.background = "rgba(255,215,0,0.05)"}
757
+ onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
758
+ <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
759
+ <div style={{ width: 3, height: 3, background: "var(--g-500)" }} />{opt}
760
+ </div>
761
+ </div>
762
+ ))}
763
+ </div>
764
+ )}
765
+ </div>
766
+ );
767
+ };
768
+
769
+ // ── 17. MODAL ──────────────────────────────────────────────────
770
+ const Modal = ({ open, onClose, title, children }) => {
771
+ if (!open) return null;
772
+ return (
773
+ <div style={{
774
+ position: "fixed", inset: 0, background: "rgba(0,0,0,0.85)", zIndex: 1000,
775
+ display: "flex", alignItems: "center", justifyContent: "center", backdropFilter: "blur(4px)"
776
+ }}>
777
+ <div style={{ position: "relative", maxWidth: 480, width: "90%", maxHeight: "80vh", overflow: "hidden" }}>
778
+ <TicketShell stubHeight={0}>
779
+ <div style={{ padding: "20px 20px 16px", position: "relative", zIndex: 8 }}>
780
+ <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
781
+ <div>
782
+ <div style={{
783
+ fontSize: 7, letterSpacing: "0.28em", color: "var(--g-700)",
784
+ fontFamily: "var(--font)", textTransform: "uppercase", marginBottom: 4
785
+ }}>// CLASSIFIED DIALOGUE</div>
786
+ <div style={{
787
+ fontSize: 11, fontWeight: 700, letterSpacing: "0.22em", textTransform: "uppercase",
788
+ fontFamily: "var(--font)", color: "var(--g-300)"
789
+ }}>{title}</div>
790
+ </div>
791
+ <button onClick={onClose} style={{
792
+ background: "transparent", border: "1px solid var(--g-700)",
793
+ color: "var(--g-500)", width: 24, height: 24, cursor: "pointer", fontFamily: "var(--font)", fontSize: 10,
794
+ display: "flex", alignItems: "center", justifyContent: "center"
795
+ }}>×</button>
796
+ </div>
797
+ <Divider />
798
+ <div style={{
799
+ marginTop: 14, color: "var(--w-400)", fontSize: 8.5, lineHeight: 1.7,
800
+ letterSpacing: "0.12em", fontFamily: "var(--font)"
801
+ }}>{children}</div>
802
+ <div style={{ marginTop: 18, display: "flex", gap: 8, justifyContent: "flex-end" }}>
803
+ <Button variant="ghost" onClick={onClose}>CANCEL</Button>
804
+ <Button variant="primary" onClick={onClose}>CONFIRM</Button>
805
+ </div>
806
+ </div>
807
+ </TicketShell>
808
+ </div>
809
+ </div>
810
+ );
811
+ };
812
+
813
+ // ── 18. AVATAR ─────────────────────────────────────────────────
814
+ const Avatar = ({ initials = "Ω", status }) => (
815
+ <div style={{ position: "relative", width: 40, height: 40 }}>
816
+ <div style={{
817
+ width: "100%", height: "100%", borderRadius: "50%", background: "var(--surface)",
818
+ border: "1px solid var(--g-700)", display: "flex", alignItems: "center", justifyContent: "center",
819
+ overflow: "hidden", position: "relative"
820
+ }}>
821
+ <GeometricOverlay />
822
+ <span style={{ fontSize: 13, color: "var(--g-300)", fontFamily: "var(--font)", zIndex: 7 }}>{initials}</span>
823
+ </div>
824
+ {status && (
825
+ <div className="pulse-anim" style={{
826
+ position: "absolute", bottom: 1, right: 1, width: 7, height: 7,
827
+ borderRadius: "50%", background: "var(--g-300)", border: "1px solid var(--bg)",
828
+ boxShadow: "0 0 6px var(--g-500)"
829
+ }} />
830
+ )}
831
+ </div>
832
+ );
833
+
834
+ // ── 19. FIELDSET ───────────────────────────────────────────────
835
+ const Fieldset = ({ legend, children }) => (
836
+ <div style={{ border: "1px solid var(--border-1)", padding: "14px 16px", position: "relative", marginTop: 8 }}>
837
+ <div style={{
838
+ position: "absolute", top: -7, left: 12, background: "var(--bg)", padding: "0 6px",
839
+ fontSize: 7, letterSpacing: "0.28em", color: "var(--g-500)", textTransform: "uppercase", fontFamily: "var(--font)"
840
+ }}>
841
+ {legend}
842
+ </div>
843
+ <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>{children}</div>
844
+ </div>
845
+ );
846
+
847
+ // ── 20. STAT CARD ──────────────────────────────────────────────
848
+ const StatCard = ({ label, value, unit, change, trend }) => (
849
+ <Punched>
850
+ <div style={{
851
+ position: "relative", background: "var(--surface)", border: "1px solid var(--border-1)",
852
+ padding: "14px 16px", overflow: "hidden"
853
+ }}>
854
+ <GrainOverlay strength={0.1} />
855
+ <div style={{ position: "relative", zIndex: 7 }}>
856
+ <div style={{
857
+ fontSize: 7, letterSpacing: "0.28em", color: "var(--g-700)", textTransform: "uppercase",
858
+ fontFamily: "var(--font)", marginBottom: 8
859
+ }}>{label}</div>
860
+ <div style={{ display: "flex", alignItems: "baseline", gap: 4 }}>
861
+ <span style={{
862
+ fontSize: 26, fontWeight: 700, letterSpacing: "0.04em",
863
+ fontFamily: "var(--font)", lineHeight: 1, color: "var(--w-100)"
864
+ }}>{value}</span>
865
+ {unit && <span style={{ fontSize: 9, color: "var(--g-500)", fontFamily: "var(--font)", letterSpacing: "0.14em" }}>{unit}</span>}
866
+ </div>
867
+ {change !== undefined && (
868
+ <div style={{
869
+ marginTop: 6, fontSize: 7.5, letterSpacing: "0.18em", fontFamily: "var(--font)",
870
+ color: trend === "up" ? "var(--g-300)" : trend === "down" ? "var(--r-500)" : "var(--w-500)"
871
+ }}>
872
+ {trend === "up" ? "▲" : trend === "down" ? "▼" : "—"} {change}
873
+ </div>
874
+ )}
875
+ </div>
876
+ <div style={{
877
+ position: "absolute", bottom: -20, right: -20, width: 60, height: 60,
878
+ borderRadius: "50%", background: "rgba(255,215,0,0.03)", pointerEvents: "none"
879
+ }} />
880
+ </div>
881
+ </Punched>
882
+ );
883
+
884
+ // ── 21. SIDEBAR ────────────────────────────────────────────────
885
+ const Sidebar = ({ activeItem, setActiveItem }) => {
886
+ const items = [
887
+ { icon: "◈", label: "DASHBOARD", sub: "OVERVIEW" },
888
+ { icon: "◉", label: "INTEL", sub: "CLASSIFIED" },
889
+ { icon: "▣", label: "ASSETS", sub: "INVENTORY" },
890
+ { icon: "◆", label: "COMMS", sub: "ENCRYPTED" },
891
+ { icon: "⬡", label: "ANALYTICS", sub: "METRICS" },
892
+ { icon: "⊕", label: "SETTINGS", sub: "CONFIG" },
893
+ ];
894
+ return (
895
+ <Punched style={{ width: 160 }}>
896
+ <div style={{
897
+ background: "var(--header)", borderRight: "1px solid var(--border-1)",
898
+ display: "flex", flexDirection: "column", position: "relative", overflow: "hidden", height: "100%"
899
+ }}>
900
+ <GrainOverlay strength={0.13} />
901
+ <div style={{
902
+ position: "absolute", right: 0, top: 0, bottom: 0, width: 8,
903
+ background: "repeating-linear-gradient(180deg, transparent 0px, transparent 8px, var(--bg) 8px, var(--bg) 18px)",
904
+ zIndex: 10
905
+ }} />
906
+ <div style={{ padding: "12px 0", flex: 1, position: "relative", zIndex: 7 }}>
907
+ {items.map((item, i) => (
908
+ <button key={i} onClick={() => setActiveItem(item.label)} style={{
909
+ width: "100%", background: activeItem === item.label ? "rgba(255,215,0,0.05)" : "transparent",
910
+ border: "none", borderLeft: activeItem === item.label ? "2px solid var(--g-300)" : "2px solid transparent",
911
+ borderRight: "none", padding: "10px 14px", cursor: "pointer", textAlign: "left",
912
+ borderBottom: i < items.length - 1 ? "1px solid var(--border-1)" : "none",
913
+ }}>
914
+ <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
915
+ <span style={{ fontSize: 11, color: activeItem === item.label ? "var(--g-300)" : "var(--w-500)" }}>{item.icon}</span>
916
+ <div>
917
+ <div style={{
918
+ fontSize: 8, fontWeight: 600, letterSpacing: "0.18em", textTransform: "uppercase",
919
+ color: activeItem === item.label ? "var(--g-300)" : "var(--w-400)", fontFamily: "var(--font)"
920
+ }}>{item.label}</div>
921
+ <div style={{ fontSize: 6, letterSpacing: "0.2em", color: "var(--g-700)", textTransform: "uppercase", fontFamily: "var(--font)" }}>{item.sub}</div>
922
+ </div>
923
+ </div>
924
+ </button>
925
+ ))}
926
+ </div>
927
+ <div style={{ padding: "12px 14px", borderTop: "1px solid var(--border-1)", position: "relative", zIndex: 7 }}>
928
+ <Barcode value="AGT-09-NEXUS" width={120} height={16} />
929
+ </div>
930
+ </div>
931
+ </Punched>
932
+ );
933
+ };
934
+
935
+ // ── 22. FOOTER ─────────────────────────────────────────────────
936
+ const Footer = () => (
937
+ <Punched style={{ marginTop: 8 }}>
938
+ <div style={{
939
+ position: "relative", background: "var(--header)", borderTop: "1px solid var(--border-1)",
940
+ padding: "12px 24px", display: "flex", justifyContent: "space-between", alignItems: "center", overflow: "hidden"
941
+ }}>
942
+ <GrainOverlay strength={0.1} />
943
+ <div style={{ position: "relative", zIndex: 7 }}>
944
+ <Micro color="var(--g-700)">© NEXUS PROTOCOL — OMEGA DIVISION — CLEARANCE REQUIRED</Micro>
945
+ </div>
946
+ <div style={{ position: "relative", zIndex: 7 }}>
947
+ <Barcode value="NEXUS-FOOTER-SYS" width={100} height={14} />
948
+ </div>
949
+ <div style={{ position: "relative", zIndex: 7, display: "flex", gap: 12 }}>
950
+ <Micro color="var(--g-500)">v4.7.2</Micro>
951
+ <Micro color="var(--g-700)">BUILD-20470312</Micro>
952
+ </div>
953
+ </div>
954
+ </Punched>
955
+ );
956
+
957
+ // ══════════════════════════════════════════════════════════════
958
+ // DEMO PAGE
959
+ // ══════════════════════════════════════════════════════════════
960
+ export default function TicketPunchUIDemo() {
961
+ const [activeNavTab, setActiveNavTab] = useState("DASHBOARD");
962
+ const [activeSideItem, setActiveSideItem] = useState("DASHBOARD");
963
+ const [activeTab, setActiveTab] = useState(0);
964
+ const [toggleA, setToggleA] = useState(true);
965
+ const [toggleB, setToggleB] = useState(false);
966
+ const [modalOpen, setModalOpen] = useState(false);
967
+ const [selectVal, setSelectVal] = useState("");
968
+ const [inputVal, setInputVal] = useState("");
969
+
970
+ return (
971
+ <div style={{
972
+ fontFamily: "var(--font)", background: "var(--bg)", minHeight: "100vh",
973
+ color: "var(--text-primary)", position: "relative"
974
+ }}>
975
+ <FontInjector />
976
+
977
+ {/* Ambient gold glow */}
978
+ <div style={{
979
+ position: "fixed", top: "30%", left: "50%", transform: "translate(-50%,-50%)",
980
+ width: 600, height: 600, borderRadius: "50%",
981
+ background: "radial-gradient(circle, rgba(255,215,0,0.025) 0%, transparent 70%)",
982
+ pointerEvents: "none", zIndex: 0
983
+ }} />
984
+
985
+ <div style={{ display: "flex", flexDirection: "column", height: "100vh", overflow: "hidden" }}>
986
+ <Header activeTab={activeNavTab} setActiveTab={setActiveNavTab} />
987
+ <div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
988
+ <Sidebar activeItem={activeSideItem} setActiveItem={setActiveSideItem} />
989
+
990
+ <div style={{ flex: 1, overflow: "auto", padding: 24 }}>
991
+
992
+ {/* Page Header */}
993
+ <div style={{ marginBottom: 28, display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
994
+ <div>
995
+ <Breadcrumbs items={["NEXUS", "DASHBOARD", "COMPONENT LAB"]} />
996
+ <h1 style={{
997
+ fontSize: 22, fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase",
998
+ fontFamily: "var(--font)", marginTop: 8, lineHeight: 1, color: "var(--w-100)"
999
+ }}>TICKETPUNCH UI</h1>
1000
+ <div style={{
1001
+ fontSize: 8, letterSpacing: "0.28em", color: "var(--g-700)", textTransform: "uppercase",
1002
+ fontFamily: "var(--font)", marginTop: 6
1003
+ }}>
1004
+ DESIGN SYSTEM — OMEGA CLASSIFICATION — BUILD 2047.03.12
1005
+ </div>
1006
+ </div>
1007
+ <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
1008
+ <StatusPill status="active" label="ALL SYSTEMS GO" />
1009
+ <Button variant="outline" size="sm">EXPORT</Button>
1010
+ </div>
1011
+ </div>
1012
+
1013
+ {/* STAT CARDS */}
1014
+ <SectionLabel sub="// REAL-TIME METRICS — CLASSIFIED">SYSTEM OVERVIEW</SectionLabel>
1015
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12, marginBottom: 28 }}>
1016
+ <StatCard label="ACTIVE NODES" value="847" change="+12 TODAY" trend="up" />
1017
+ <StatCard label="THREAT LEVEL" value="2.7" unit="%" change="-0.4 DELTA" trend="down" />
1018
+ <StatCard label="DATA STREAMS" value="1.4" unit="TB" change="+0.2 TB" trend="up" />
1019
+ <StatCard label="UPTIME" value="99.9" unit="%" change="NOMINAL" trend="neutral" />
1020
+ </div>
1021
+
1022
+ {/* MAIN TICKET CARD */}
1023
+ <SectionLabel sub="// TICKET SHELL — PRIMARY CONTAINER">CLASSIFIED INTEL BRIEF</SectionLabel>
1024
+ <div style={{ marginBottom: 28 }}>
1025
+ <TicketShell stubHeight={68}>
1026
+ <div style={{ padding: "28px 24px 80px", position: "relative", zIndex: 8 }}>
1027
+ <div style={{ display: "flex", gap: 20, alignItems: "flex-start" }}>
1028
+ <TerminalMask size={100} />
1029
+ <div style={{ flex: 1 }}>
1030
+ <div style={{
1031
+ fontSize: 7, letterSpacing: "0.34em", color: "var(--g-700)",
1032
+ textTransform: "uppercase", fontFamily: "var(--font)", marginBottom: 6
1033
+ }}>
1034
+ // OMEGA-NEXUS // DIRECTIVE 7749 // CLASSIFIED
1035
+ </div>
1036
+ <h2 style={{
1037
+ fontSize: 18, fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase",
1038
+ fontFamily: "var(--font)", marginBottom: 10, lineHeight: 1.2, color: "var(--g-300)"
1039
+ }}>
1040
+ OPERATION<br />BLACKOUT
1041
+ </h2>
1042
+ <p style={{
1043
+ fontSize: 8.5, color: "var(--w-500)", lineHeight: 1.8,
1044
+ letterSpacing: "0.12em", fontFamily: "var(--font)", maxWidth: 420
1045
+ }}>
1046
+ AUTHORIZED PERSONNEL ONLY. MISSION PARAMETERS LOCKED PENDING CLEARANCE VERIFICATION.
1047
+ ALL COMMUNICATION ENCRYPTED VIA NEXUS-PROTOCOL AES-512.
1048
+ </p>
1049
+ <div style={{ marginTop: 14, display: "flex", gap: 8, flexWrap: "wrap" }}>
1050
+ <Badge variant="omega">OMEGA-7</Badge>
1051
+ <Badge variant="danger">TOP SECRET</Badge>
1052
+ <Badge variant="warning">ACTIVE</Badge>
1053
+ <Badge>NEXUS-PROTOCOL</Badge>
1054
+ </div>
1055
+ </div>
1056
+ <div style={{ display: "flex", flexDirection: "column", gap: 10, alignItems: "flex-end" }}>
1057
+ <Barcode value="OP-7749-BX-OMEGA" width={130} height={36} />
1058
+ <Micro color="var(--g-700)">ISSUED: 2047.03.12</Micro>
1059
+ </div>
1060
+ </div>
1061
+ </div>
1062
+ <div style={{
1063
+ position: "absolute", bottom: 0, left: 0, right: 0, height: 68, padding: "0 24px",
1064
+ display: "flex", alignItems: "center", justifyContent: "space-between", zIndex: 8
1065
+ }}>
1066
+ <Micro color="var(--g-700)">REF: NEXUS-OP-7749</Micro>
1067
+ <div style={{ display: "flex", gap: 16 }}>
1068
+ <StatusPill status="active" label="MISSION ACTIVE" />
1069
+ <StatusPill status="warning" label="HIGH RISK" />
1070
+ </div>
1071
+ </div>
1072
+ </TicketShell>
1073
+ </div>
1074
+
1075
+ {/* TABS + TABLE */}
1076
+ <SectionLabel sub="// DATA MANAGEMENT INTERFACE">INTEL DATABASE</SectionLabel>
1077
+ <div style={{ marginBottom: 28 }}>
1078
+ <Card>
1079
+ <Tabs tabs={["AGENTS", "MISSIONS", "ASSETS", "THREATS"]} active={activeTab} onSelect={setActiveTab} />
1080
+ <div style={{ marginTop: 16 }}>
1081
+ <DataTable
1082
+ columns={["AGENT ID", "STATUS", "CLEARANCE", "ASSIGNMENT", "LAST ACTIVE"]}
1083
+ rows={[
1084
+ ["AGT-001 SPECTRE", <Badge variant="active">ACTIVE</Badge>, "OMEGA", "OP-7749", "0:04:22 AGO"],
1085
+ ["AGT-002 PHANTOM", <Badge variant="warning">STANDBY</Badge>, "DELTA", "OP-7700", "2:14:07 AGO"],
1086
+ ["AGT-003 WRAITH", <Badge variant="danger">COMPROMISED</Badge>, "GAMMA", "—", "6:55:13 AGO"],
1087
+ ["AGT-004 NEXUS", <Badge>OFFLINE</Badge>, "ALPHA", "OP-7801", "1D 04H AGO"],
1088
+ ]}
1089
+ />
1090
+ </div>
1091
+ </Card>
1092
+ </div>
1093
+
1094
+ {/* BUTTONS */}
1095
+ <SectionLabel sub="// INTERACTION PRIMITIVES">BUTTON SYSTEM</SectionLabel>
1096
+ <div style={{ marginBottom: 28 }}>
1097
+ <Card title="BUTTON VARIANTS" sub="ALL STATES + SIZES">
1098
+ <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 16 }}>
1099
+ <Button variant="primary">EXECUTE</Button>
1100
+ <Button variant="secondary">STANDBY</Button>
1101
+ <Button variant="outline">CONFIRM</Button>
1102
+ <Button variant="ghost">DISMISS</Button>
1103
+ <Button variant="danger">ABORT</Button>
1104
+ <Button variant="success">SECURE</Button>
1105
+ <Button variant="primary" disabled>LOCKED</Button>
1106
+ <Button variant="outline" size="sm">SMALL</Button>
1107
+ <Button variant="primary" size="lg">LAUNCH SEQUENCE</Button>
1108
+ <Tooltip label="OMEGA CLASSIFIED FUNCTION">
1109
+ <Button variant="secondary" icon="◈">WITH ICON</Button>
1110
+ </Tooltip>
1111
+ </div>
1112
+ <Divider label="ICON VARIANTS" />
1113
+ <div style={{ display: "flex", gap: 8, marginTop: 12 }}>
1114
+ {["◈", "◉", "▣", "◆", "⊕"].map((icon, i) => (
1115
+ <Button key={i} variant="secondary" size="sm" icon={icon}>{icon === "⊕" ? "ADD" : ""}</Button>
1116
+ ))}
1117
+ </div>
1118
+ </Card>
1119
+ </div>
1120
+
1121
+ {/* FORM ELEMENTS */}
1122
+ <SectionLabel sub="// DATA ENTRY SYSTEM">FORM ELEMENTS</SectionLabel>
1123
+ <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 28 }}>
1124
+ <Card title="TEXT INPUTS" sub="TERMINAL STYLE">
1125
+ <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
1126
+ <Input label="AGENT ID" placeholder="ENTER AGENT IDENTIFIER"
1127
+ value={inputVal} onChange={e => setInputVal(e.target.value)} hint="FORMAT: AGT-XXX-CLEARANCE" />
1128
+ <Input label="AUTHORIZATION CODE" placeholder="••••••••" type="password" />
1129
+ <Input label="COORDINATES" placeholder="00.000000, 00.000000" prefix="GEO" suffix="WGS84" />
1130
+ <Fieldset legend="COMMS CHANNEL">
1131
+ <Input label="FREQUENCY" placeholder="XXX.XXXXX MHZ" prefix="RF" />
1132
+ <Toggle checked={toggleA} onChange={() => setToggleA(!toggleA)} label="ENCRYPTION ENABLED" />
1133
+ </Fieldset>
1134
+ </div>
1135
+ </Card>
1136
+ <Card title="SELECTORS + TOGGLES" sub="CONTROL ELEMENTS">
1137
+ <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
1138
+ <Select label="CLEARANCE LEVEL" options={["ALPHA", "BETA", "GAMMA", "DELTA", "OMEGA"]}
1139
+ value={selectVal} onChange={setSelectVal} />
1140
+ <Select label="MISSION STATUS" options={["ACTIVE", "STANDBY", "COMPLETED", "ABORT", "CLASSIFIED"]}
1141
+ value="" onChange={() => { }} />
1142
+ <Divider label="TOGGLES" />
1143
+ <Toggle checked={toggleA} onChange={() => setToggleA(!toggleA)} label="ACTIVE SURVEILLANCE" />
1144
+ <Toggle checked={toggleB} onChange={() => setToggleB(!toggleB)} label="STEALTH MODE" />
1145
+ <Toggle checked={true} onChange={() => { }} label="ENCRYPTION LAYER" />
1146
+ <Divider />
1147
+ <div>
1148
+ <Micro color="var(--g-500)">PROGRESS INDICATORS</Micro>
1149
+ <div style={{ marginTop: 10, display: "flex", flexDirection: "column", gap: 10 }}>
1150
+ <ProgressBar value={87} label="UPLINK SYNC" color="var(--g-300)" />
1151
+ <ProgressBar value={44} label="THREAT SCAN" color="var(--p-500)" />
1152
+ <ProgressBar value={12} label="BREACH RISK" color="var(--r-500)" />
1153
+ </div>
1154
+ </div>
1155
+ </div>
1156
+ </Card>
1157
+ </div>
1158
+
1159
+ {/* STATUS + BADGES */}
1160
+ <SectionLabel sub="// CLASSIFICATION LABELS">STATUS SYSTEM</SectionLabel>
1161
+ <div style={{ marginBottom: 28 }}>
1162
+ <Card title="BADGES + STATUS PILLS" sub="ALL VARIANTS">
1163
+ <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 16 }}>
1164
+ <StatusPill status="active" />
1165
+ <StatusPill status="inactive" label="OFFLINE" />
1166
+ <StatusPill status="warning" label="STANDBY" />
1167
+ <StatusPill status="danger" label="BREACH" />
1168
+ <StatusPill status="pending" label="SYNCING" />
1169
+ </div>
1170
+ <Divider label="BADGES" />
1171
+ <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 12 }}>
1172
+ <Badge variant="omega">OMEGA</Badge>
1173
+ <Badge variant="active">ACTIVE</Badge>
1174
+ <Badge variant="danger">COMPROMISED</Badge>
1175
+ <Badge variant="warning">ALERT</Badge>
1176
+ <Badge>DEFAULT</Badge>
1177
+ <Badge>CLASSIFIED</Badge>
1178
+ <Badge>NEXUS</Badge>
1179
+ </div>
1180
+ </Card>
1181
+ </div>
1182
+
1183
+ {/* ACCORDION + STEPPER */}
1184
+ <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 28 }}>
1185
+ <div>
1186
+ <SectionLabel sub="// COLLAPSIBLE SECTIONS">ACCORDION</SectionLabel>
1187
+ <Card>
1188
+ <AccordionItem title="MISSION PARAMETERS">
1189
+ PRIMARY OBJECTIVE: INFILTRATE NEXUS SIGMA NODE. SECONDARY: EXTRACT DATA PACKAGE DELTA-7.
1190
+ ABORT CODE: 4419-OMEGA. DURATION: 72H MAX.
1191
+ </AccordionItem>
1192
+ <AccordionItem title="AGENT DOSSIER">
1193
+ AGENT: SPECTRE-9 // RANK: SENIOR OPERATIVE // CLEARANCE: OMEGA //
1194
+ STATUS: FIELD ACTIVE // DEPLOYMENTS: 47 COMPLETED.
1195
+ </AccordionItem>
1196
+ <AccordionItem title="CLASSIFIED INTEL">
1197
+ [REDACTED — CLEARANCE LEVEL OMEGA REQUIRED. CONTACT DIVISION COMMANDER FOR ACCESS CREDENTIALS.]
1198
+ </AccordionItem>
1199
+ </Card>
1200
+ </div>
1201
+ <div>
1202
+ <SectionLabel sub="// MISSION PROGRESS WIZARD">STEPPER</SectionLabel>
1203
+ <Card>
1204
+ <Stepper steps={["BRIEF", "DEPLOY", "ACTIVE", "EXTRACT", "DEBRIEF"]} current={2} />
1205
+ <div style={{ marginTop: 20 }}>
1206
+ <Divider label="CURRENT PHASE" />
1207
+ <div style={{ marginTop: 12, padding: "12px", border: "1px solid var(--g-900)", position: "relative" }}>
1208
+ <div style={{
1209
+ fontSize: 7, letterSpacing: "0.28em", color: "var(--g-300)",
1210
+ fontFamily: "var(--font)", textTransform: "uppercase", marginBottom: 6
1211
+ }}>▶ PHASE 3: ACTIVE DEPLOYMENT</div>
1212
+ <div style={{ fontSize: 8, color: "var(--w-500)", lineHeight: 1.7, letterSpacing: "0.12em", fontFamily: "var(--font)" }}>
1213
+ AGENT SPECTRE-9 IS CURRENTLY ACTIVE IN THE FIELD. ALL VITALS NOMINAL.
1214
+ COMMS ENCRYPTED. ETA TO OBJECTIVE: 04:22:11.
1215
+ </div>
1216
+ </div>
1217
+ </div>
1218
+ </Card>
1219
+ </div>
1220
+ </div>
1221
+
1222
+ {/* ALERTS + LOADER */}
1223
+ <SectionLabel sub="// SYSTEM NOTIFICATIONS">ALERTS + LOADERS</SectionLabel>
1224
+ <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 28 }}>
1225
+ <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
1226
+ <Alert type="success" title="OPERATION SECURED"
1227
+ message="NEXUS NODE ALPHA SECURED. ALL OBJECTIVES COMPLETE. EXTRACTION CONFIRMED." />
1228
+ <Alert type="warning" title="SIGNAL INTERFERENCE"
1229
+ message="COMMS DEGRADED ON CHANNEL 7. SWITCHING TO BACKUP FREQUENCY 449.7750 MHZ." />
1230
+ <Alert type="danger" title="BREACH DETECTED"
1231
+ message="UNAUTHORIZED ACCESS ATTEMPT — NODE SIGMA. LOCKDOWN INITIATED. STANDBY." onClose={() => { }} />
1232
+ <Alert type="info" title="ROUTINE SCAN COMPLETE"
1233
+ message="ALL SYSTEMS NOMINAL. NEXT SCHEDULED SWEEP IN 04:00:00." />
1234
+ </div>
1235
+ <Card title="SYSTEM STATES" sub="LOADING INDICATORS">
1236
+ <div style={{ display: "flex", gap: 20, alignItems: "center", justifyContent: "center", padding: 20 }}>
1237
+ {[["SMALL", 28], ["MEDIUM", 44], ["LARGE", 64]].map(([lbl, sz]) => (
1238
+ <div key={lbl} style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 8 }}>
1239
+ <Spinner size={sz} /><Micro color="var(--g-500)">{lbl}</Micro>
1240
+ </div>
1241
+ ))}
1242
+ </div>
1243
+ <Divider label="AVATARS" />
1244
+ <div style={{ display: "flex", gap: 10, marginTop: 12, alignItems: "center" }}>
1245
+ <Avatar initials="Ω" status="active" />
1246
+ <Avatar initials="Σ" status="active" />
1247
+ <Avatar initials="Δ" />
1248
+ <Avatar initials="Γ" />
1249
+ <div style={{ flex: 1 }}>
1250
+ <div style={{ fontSize: 8.5, letterSpacing: "0.16em", fontFamily: "var(--font)", color: "var(--g-300)" }}>OMEGA TEAM</div>
1251
+ <div style={{
1252
+ fontSize: 7, letterSpacing: "0.18em", color: "var(--g-700)", fontFamily: "var(--font)",
1253
+ textTransform: "uppercase", marginTop: 2
1254
+ }}>4 AGENTS // 2 ACTIVE</div>
1255
+ </div>
1256
+ </div>
1257
+ </Card>
1258
+ </div>
1259
+
1260
+ {/* MODAL TRIGGER */}
1261
+ <SectionLabel sub="// OVERLAY SYSTEM">MODAL SYSTEM</SectionLabel>
1262
+ <div style={{ marginBottom: 28 }}>
1263
+ <Card title="MODAL TRIGGER" sub="TICKET-SHELL OVERLAY">
1264
+ <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
1265
+ <Button variant="outline" onClick={() => setModalOpen(true)}>OPEN CLASSIFIED BRIEF</Button>
1266
+ <Tooltip label="OPENS A FULL TICKET-SHELL MODAL">
1267
+ <Button variant="ghost" icon="◈" />
1268
+ </Tooltip>
1269
+ </div>
1270
+ </Card>
1271
+ </div>
1272
+
1273
+ {/* TYPOGRAPHY */}
1274
+ <SectionLabel sub="// IBM PLEX MONO TYPE SYSTEM">TYPOGRAPHY</SectionLabel>
1275
+ <div style={{ marginBottom: 28 }}>
1276
+ <Card title="TYPE SCALE + WEIGHTS">
1277
+ <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
1278
+ {[
1279
+ { size: 22, weight: 700, text: "DISPLAY — OMEGA PROTOCOL", color: "var(--g-300)" },
1280
+ { size: 16, weight: 700, text: "H1 — CLASSIFIED DIRECTIVE", color: "var(--w-100)" },
1281
+ { size: 13, weight: 600, text: "H2 — NEXUS SYSTEM HEADER", color: "var(--w-200)" },
1282
+ { size: 11, weight: 600, text: "H3 — OPERATION BRIEFING", color: "var(--w-300)" },
1283
+ { size: 9.5, weight: 500, text: "H4 — SUBHEADING ALPHA", color: "var(--w-300)" },
1284
+ { size: 8.5, weight: 400, text: "BODY — STANDARD INTEL REPORT BODY TEXT FOR EXTENDED BRIEFINGS", color: "var(--w-400)" },
1285
+ { size: 7.5, weight: 400, text: "SMALL — SECONDARY SUPPORT LABELS AND DESCRIPTORS", color: "var(--w-500)" },
1286
+ { size: 7, weight: 400, text: "MICRO — OMEGA-7749 // COPYRIGHT NEXUS DIVISION // CLEARANCE REQUIRED", color: "var(--g-700)" },
1287
+ ].map((t, i) => (
1288
+ <div key={i} style={{
1289
+ display: "flex", alignItems: "baseline", gap: 16,
1290
+ borderBottom: i < 7 ? "1px solid var(--border-1)" : "none", paddingBottom: 6
1291
+ }}>
1292
+ <span style={{ fontSize: 7, color: "var(--g-700)", width: 28, fontFamily: "var(--font)", letterSpacing: "0.1em" }}>{t.size}PX</span>
1293
+ <span style={{
1294
+ fontSize: t.size, fontWeight: t.weight, letterSpacing: "0.14em",
1295
+ textTransform: "uppercase", fontFamily: "var(--font)", color: t.color
1296
+ }}>{t.text}</span>
1297
+ </div>
1298
+ ))}
1299
+ </div>
1300
+ </Card>
1301
+ </div>
1302
+
1303
+ {/* COLOR PALETTE */}
1304
+ <SectionLabel sub="// DESIGN TOKENS — COLOR SYSTEM">COLOR PALETTE</SectionLabel>
1305
+ <div style={{ marginBottom: 28 }}>
1306
+ <Card title="TOKEN PALETTE" sub="TICKETPUNCH DESIGN LANGUAGE">
1307
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 8 }}>
1308
+ {[
1309
+ { scheme: "DARK", name: "D-900", val: "#060606" },
1310
+ { scheme: "DARK", name: "D-800", val: "#0A0A0A" },
1311
+ { scheme: "DARK", name: "D-700", val: "#0f0f0f" },
1312
+ { scheme: "DARK", name: "D-600", val: "#1e1e1e" },
1313
+ { scheme: "DARK", name: "D-500", val: "#2a2a2a" },
1314
+ { scheme: "WHITE", name: "W-100", val: "#FFFFFF" },
1315
+ { scheme: "WHITE", name: "W-200", val: "#EFEFEF" },
1316
+ { scheme: "WHITE", name: "W-300", val: "#CDCDCD" },
1317
+ { scheme: "WHITE", name: "W-400", val: "#AAAAAA" },
1318
+ { scheme: "WHITE", name: "W-500", val: "#888888" },
1319
+ { scheme: "GOLD", name: "G-100", val: "#FFF4CC" },
1320
+ { scheme: "GOLD", name: "G-300", val: "#FFD700" },
1321
+ { scheme: "GOLD", name: "G-500", val: "#C8960C" },
1322
+ { scheme: "GOLD", name: "G-700", val: "#7A5800" },
1323
+ { scheme: "GOLD", name: "G-900", val: "#3D2C00" },
1324
+ { scheme: "RED", name: "R-100", val: "#FFE5E5" },
1325
+ { scheme: "RED", name: "R-300", val: "#FF6666" },
1326
+ { scheme: "RED", name: "R-500", val: "#FF3333" },
1327
+ { scheme: "RED", name: "R-700", val: "#CC0000" },
1328
+ { scheme: "RED", name: "R-900", val: "#550000" },
1329
+ { scheme: "PEACH", name: "P-100", val: "#FFF0EB" },
1330
+ { scheme: "PEACH", name: "P-300", val: "#FFBFA8" },
1331
+ { scheme: "PEACH", name: "P-500", val: "#FF8C69" },
1332
+ { scheme: "PEACH", name: "P-700", val: "#C45A35" },
1333
+ { scheme: "PEACH", name: "P-900", val: "#5C2010" },
1334
+ ].map((c, i) => (
1335
+ <div key={i} style={{ display: "flex", flexDirection: "column", gap: 4 }}>
1336
+ {i % 5 === 0 && (
1337
+ <div style={{
1338
+ fontSize: 6.5, letterSpacing: "0.22em", color: "var(--w-400)",
1339
+ fontFamily: "var(--font)", textTransform: "uppercase", marginBottom: 2, fontWeight: 600
1340
+ }}>{c.scheme}</div>
1341
+ )}
1342
+ {i % 5 !== 0 && <div style={{ height: 15 }} />}
1343
+ <div style={{
1344
+ height: 32, background: c.val, border: "1px solid var(--border-1)",
1345
+ boxShadow: ["GOLD", "RED", "PEACH"].includes(c.scheme) ? `0 0 10px ${c.val}55` : "none"
1346
+ }} />
1347
+ <div style={{
1348
+ fontSize: 6.5, letterSpacing: "0.18em", color: "var(--w-500)",
1349
+ fontFamily: "var(--font)", textTransform: "uppercase"
1350
+ }}>{c.name}</div>
1351
+ <div style={{ fontSize: 6, letterSpacing: "0.12em", color: "var(--g-700)", fontFamily: "var(--font)" }}>{c.val}</div>
1352
+ </div>
1353
+ ))}
1354
+ </div>
1355
+ </Card>
1356
+ </div>
1357
+
1358
+ {/* PRIMITIVES */}
1359
+ <SectionLabel sub="// CORE VISUAL PRIMITIVES">DESIGN PRIMITIVES</SectionLabel>
1360
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16, marginBottom: 28 }}>
1361
+ <Card title="GRAIN OVERLAY" sub="STATIC NOISE TEXTURE" style={{ minHeight: 120 }}>
1362
+ <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
1363
+ {[0.08, 0.18, 0.28].map((s, i) => (
1364
+ <div key={i} style={{ position: "relative", height: 28, background: "var(--header)", border: "1px solid var(--border-1)" }}>
1365
+ <GrainOverlay strength={s} />
1366
+ <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", zIndex: 7 }}>
1367
+ <Micro color="var(--g-500)">{(s * 100).toFixed(0)}% STRENGTH</Micro>
1368
+ </div>
1369
+ </div>
1370
+ ))}
1371
+ </div>
1372
+ </Card>
1373
+ <Card title="BARCODES" sub="GENERATIVE PATTERN">
1374
+ <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
1375
+ <Barcode value="OMEGA-7749-XX" width={160} height={32} />
1376
+ <Barcode value="NEXUS-ALPHA-01" width={160} height={20} />
1377
+ <Barcode value="CLASSIFIED" width={160} height={14} />
1378
+ </div>
1379
+ </Card>
1380
+ <Card title="TERMINAL MASK" sub="SCROLLING INTEL FEED">
1381
+ <div style={{ display: "flex", gap: 12, justifyContent: "center" }}>
1382
+ <TerminalMask size={90} /><TerminalMask size={70} />
1383
+ </div>
1384
+ </Card>
1385
+ </div>
1386
+
1387
+ <Footer />
1388
+ </div>
1389
+ </div>
1390
+ </div>
1391
+
1392
+ <Modal open={modalOpen} onClose={() => setModalOpen(false)} title="CLASSIFIED DIRECTIVE">
1393
+ <p style={{ marginBottom: 12 }}>
1394
+ THIS DOCUMENT CONTAINS INFORMATION OF THE HIGHEST CLASSIFICATION.
1395
+ UNAUTHORIZED DISCLOSURE IS A VIOLATION OF NEXUS PROTOCOL ARTICLE 7-OMEGA.
1396
+ </p>
1397
+ <p>
1398
+ OPERATION BLACKOUT IS AUTHORIZED BY DIVISION COMMANDER NEXUS-1.
1399
+ ALL AGENTS MUST CONFIRM RECEIPT VIA SECURE CHANNEL BEFORE DEPLOYMENT.
1400
+ </p>
1401
+ <div style={{ marginTop: 16 }}>
1402
+ <Barcode value="DIRECTIVE-4419-OMEGA" width={160} height={24} />
1403
+ </div>
1404
+ </Modal>
1405
+ </div>
1406
+ );
1407
+ }
CyberTicket.jsx ADDED
@@ -0,0 +1,646 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect, useRef } from "react";
2
+
3
+ const FONT_URL = "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&display=swap";
4
+
5
+ const TERMINAL_LINES = [
6
+ "INIT SEQUENCE 0x4F2A...",
7
+ "AUTH TOKEN: ██████████████",
8
+ "SCAN FREQ 847.221 MHz",
9
+ "SECTOR [CLASSIFIED]",
10
+ "NODE_ID NX-9912-DELTA",
11
+ "TIMESTAMP 2025.03.06",
12
+ "CLEARANCE LEVEL-OMEGA",
13
+ "STATUS AUTHORIZED",
14
+ "PAYLOAD ENCRYPTED",
15
+ "UPLINK ACTIVE",
16
+ "SIGNAL ████░░░░ 61%",
17
+ "VERIFY SHA256:c0d3f",
18
+ "MATRIX 7×7 LATTICE",
19
+ "HASH 0xDEADBEEF",
20
+ "PING 12.4ms OK",
21
+ "TRACE DISABLED",
22
+ "VAULT SEALED",
23
+ "PROTOCOL OMEGA-9",
24
+ "ENTROPY HIGH",
25
+ "FRAME #00441",
26
+ "BUFFER FLUSHED",
27
+ "CIPHER AES-256",
28
+ "RELAY PROXIED",
29
+ "ECHO SILENT",
30
+ "LOCK ENGAGED",
31
+ "GRID REF 44.0N 76.2W",
32
+ "KERNEL 3.14.159",
33
+ "DAEMON RUNNING",
34
+ "WATCHDOG ARMED",
35
+ "ROUTE OBFUSCATED",
36
+ ];
37
+
38
+ // ── Noise / grain canvas ──────────────────────────────────────────────────────
39
+ function GrainOverlay({ strength = 0.18 }) {
40
+ const canvasRef = useRef();
41
+ const tick = useRef(0);
42
+
43
+ useEffect(() => {
44
+ const canvas = canvasRef.current;
45
+ if (!canvas) return;
46
+ const ctx = canvas.getContext("2d");
47
+ let raf;
48
+
49
+ const draw = () => {
50
+ tick.current++;
51
+ if (tick.current % 2 !== 0) { raf = requestAnimationFrame(draw); return; }
52
+ const { width, height } = canvas;
53
+ const img = ctx.createImageData(width, height);
54
+ const d = img.data;
55
+ for (let i = 0; i < d.length; i += 4) {
56
+ const px = i / 4;
57
+ const x = px % width;
58
+ const y = Math.floor(px / width);
59
+ const cx = x / width - 0.5, cy = y / height - 0.5;
60
+ const dist = Math.sqrt(cx * cx + cy * cy);
61
+ const vignette = Math.min(1, dist * 2.2);
62
+ const noise = (Math.random() - 0.5) * 255 * (strength + vignette * 0.18);
63
+ d[i] = d[i + 1] = d[i + 2] = 128 + noise;
64
+ d[i + 3] = Math.floor(18 + vignette * 30);
65
+ }
66
+ ctx.putImageData(img, 0, 0);
67
+ raf = requestAnimationFrame(draw);
68
+ };
69
+
70
+ const resize = () => {
71
+ canvas.width = canvas.offsetWidth;
72
+ canvas.height = canvas.offsetHeight;
73
+ };
74
+ resize();
75
+ draw();
76
+ window.addEventListener("resize", resize);
77
+ return () => { cancelAnimationFrame(raf); window.removeEventListener("resize", resize); };
78
+ }, [strength]);
79
+
80
+ return (
81
+ <canvas
82
+ ref={canvasRef}
83
+ style={{
84
+ position: "absolute", inset: 0, width: "100%", height: "100%",
85
+ pointerEvents: "none", mixBlendMode: "overlay", zIndex: 10,
86
+ }}
87
+ />
88
+ );
89
+ }
90
+
91
+ // ── SVG geometric overlay ─────────────────────────────────────────────────────
92
+ function GeometricOverlay() {
93
+ return (
94
+ <svg
95
+ viewBox="0 0 480 860"
96
+ style={{
97
+ position: "absolute", inset: 0, width: "100%", height: "100%",
98
+ pointerEvents: "none", zIndex: 5, opacity: 0.08,
99
+ }}
100
+ preserveAspectRatio="none"
101
+ >
102
+ <polygon points="0,0 72,0 0,72" fill="none" stroke="white" strokeWidth="0.8" />
103
+ <polygon points="480,0 408,0 480,72" fill="none" stroke="white" strokeWidth="0.8" />
104
+ <polygon points="0,860 72,860 0,788" fill="none" stroke="white" strokeWidth="0.8" />
105
+ <polygon points="480,860 408,860 480,788" fill="none" stroke="white" strokeWidth="0.8" />
106
+ {[0.2, 0.4, 0.6, 0.8].map((t) => (
107
+ <line key={t} x1={480 * t} y1="0" x2={480 * t} y2="860" stroke="white" strokeWidth="0.4" />
108
+ ))}
109
+ {[0.25, 0.5, 0.75].map((t) => (
110
+ <line key={t} x1="0" y1={860 * t} x2="480" y2={860 * t} stroke="white" strokeWidth="0.4" />
111
+ ))}
112
+ <line x1="240" y1="430" x2="0" y2="0" stroke="white" strokeWidth="0.3" />
113
+ <line x1="240" y1="430" x2="480" y2="0" stroke="white" strokeWidth="0.3" />
114
+ <line x1="240" y1="430" x2="0" y2="860" stroke="white" strokeWidth="0.3" />
115
+ <line x1="240" y1="430" x2="480" y2="860" stroke="white" strokeWidth="0.3" />
116
+ <circle cx="240" cy="430" r="200" fill="none" stroke="white" strokeWidth="0.5" />
117
+ </svg>
118
+ );
119
+ }
120
+
121
+ // ── Terminal code cascade ─────────────────────────────────────────────────────
122
+ function TerminalMask() {
123
+ const [offset, setOffset] = useState(0);
124
+ const [glitch, setGlitch] = useState({ row: -1, px: 0 });
125
+
126
+ useEffect(() => {
127
+ const iv = setInterval(() => {
128
+ setOffset((o) => (o + 1) % TERMINAL_LINES.length);
129
+ }, 120);
130
+ const gv = setInterval(() => {
131
+ setGlitch({ row: Math.floor(Math.random() * 18), px: (Math.random() - 0.5) * 8 });
132
+ setTimeout(() => setGlitch({ row: -1, px: 0 }), 80);
133
+ }, 900);
134
+ return () => { clearInterval(iv); clearInterval(gv); };
135
+ }, []);
136
+
137
+ const visible = Array.from({ length: 20 }, (_, i) =>
138
+ TERMINAL_LINES[(offset + i) % TERMINAL_LINES.length]
139
+ );
140
+
141
+ return (
142
+ <div style={{
143
+ width: "100%", height: "100%",
144
+ background: "#000",
145
+ borderRadius: "50%",
146
+ overflow: "hidden",
147
+ display: "flex",
148
+ flexDirection: "column",
149
+ justifyContent: "center",
150
+ padding: "18px 14px",
151
+ gap: 0,
152
+ position: "relative",
153
+ }}>
154
+ <div style={{
155
+ position: "absolute", inset: 0, borderRadius: "50%",
156
+ background: "radial-gradient(ellipse at center, transparent 30%, rgba(0,0,0,0.72) 100%)",
157
+ zIndex: 2, pointerEvents: "none",
158
+ }} />
159
+ {visible.map((line, i) => (
160
+ <div key={i} style={{
161
+ fontFamily: "'IBM Plex Mono', monospace",
162
+ fontSize: "9.5px",
163
+ fontWeight: i === 0 ? 700 : 400,
164
+ letterSpacing: "0.08em",
165
+ color: i === 0 ? "#FFFFFF" : i < 3 ? "#D8D8D8" : "#888",
166
+ lineHeight: "1.55",
167
+ opacity: i === 0 ? 1 : Math.max(0.18, 1 - i * 0.045),
168
+ transform: glitch.row === i ? `translateX(${glitch.px}px)` : "none",
169
+ whiteSpace: "nowrap",
170
+ overflow: "hidden",
171
+ textOverflow: "ellipsis",
172
+ transition: "transform 0.04s",
173
+ position: "relative",
174
+ zIndex: 3,
175
+ }}>
176
+ {i === 0 ? "▶ " : " "}{line}
177
+ </div>
178
+ ))}
179
+ </div>
180
+ );
181
+ }
182
+
183
+ // ── Barcode SVG ───────────────────────────────────────────────────────────────
184
+ function Barcode() {
185
+ const bars = Array.from({ length: 60 }, (_, i) => {
186
+ const w = [1, 1, 2, 1, 3, 1, 2, 1, 1, 2][i % 10];
187
+ return { w, gap: [2, 1, 2, 3, 1, 2, 1, 2, 3, 1][i % 10] };
188
+ });
189
+ return (
190
+ <svg width="160" height="36" viewBox="0 0 160 36">
191
+ {bars.reduce((acc, bar, i) => {
192
+ const x = acc.x;
193
+ acc.elements.push(
194
+ <rect key={i} x={x} y={2} width={bar.w} height={28} fill="white" />
195
+ );
196
+ acc.x += bar.w + bar.gap;
197
+ return acc;
198
+ }, { x: 2, elements: [] }).elements}
199
+ </svg>
200
+ );
201
+ }
202
+
203
+ // ── TICKET SHELL with authentic physical edges ────────────────────────────────
204
+ // Renders the outer ticket shape as a single SVG clip-path with:
205
+ // • Scalloped top & bottom edges (zigzag perforations)
206
+ // • Semicircle punch-outs on both sides at the tear line
207
+ // • Punched corner rounds
208
+ // • A perforated dashed-border inner stroke
209
+ function TicketShell({ children, stubHeight = 120 }) {
210
+ const W = 460; // SVG viewBox width
211
+ const H = 820; // SVG viewBox height
212
+ const R = 14; // corner radius
213
+ const PR = 9; // top/bottom diamond tooth size
214
+ const SR = 11; // side diamond notch size (tear notch)
215
+ const tearY = H - stubHeight; // Y where tear line sits
216
+
217
+ // Diamond zigzag teeth left→right: dir=-1 teeth UP, dir=+1 teeth DOWN
218
+ const zigzagLR = (x0, x1, y, dir) => {
219
+ const count = Math.floor((x1 - x0) / (PR * 2.2));
220
+ const step = (x1 - x0) / count;
221
+ let d = "";
222
+ for (let i = 0; i < count; i++) {
223
+ const mx = x0 + i * step + step / 2;
224
+ const ex = x0 + (i + 1) * step;
225
+ d += ` L ${mx} ${y + dir * PR} L ${ex} ${y}`;
226
+ }
227
+ return d;
228
+ };
229
+
230
+ // Diamond zigzag teeth right→left (bottom edge return)
231
+ const zigzagRL = (x0, x1, y, dir) => {
232
+ const count = Math.floor((x1 - x0) / (PR * 2.2));
233
+ const step = (x1 - x0) / count;
234
+ let d = "";
235
+ for (let i = count - 1; i >= 0; i--) {
236
+ const mx = x0 + i * step + step / 2;
237
+ const ex = x0 + i * step;
238
+ d += ` L ${mx} ${y + dir * PR} L ${ex} ${y}`;
239
+ }
240
+ return d;
241
+ };
242
+
243
+ const pad = 2;
244
+ const x0 = pad + R, x1 = W - pad - R;
245
+ const y0 = pad, y1 = H - pad;
246
+
247
+ // Right side semicircle at tearY (bites into card from right)
248
+ // Left side semicircle at tearY (bites into card from left)
249
+ const rightX = W - pad;
250
+ const leftX = pad;
251
+
252
+ // Build SVG path for clip
253
+ const path = [
254
+ `M ${x0} ${y0}`,
255
+ // top diamond zigzag edge →
256
+ zigzagLR(x0, x1, y0, -1),
257
+ // top-right corner
258
+ `L ${W - pad - R} ${y0}`,
259
+ `Q ${W - pad} ${y0} ${W - pad} ${y0 + R}`,
260
+ // right side down to tear notch
261
+ `L ${rightX} ${tearY - SR}`,
262
+ // semi-diamond bite: two lines forming a V-point inward
263
+ `L ${rightX - SR} ${tearY}`,
264
+ `L ${rightX} ${tearY + SR}`,
265
+ // right side continues down
266
+ `L ${rightX} ${y1 - R}`,
267
+ // bottom-right corner
268
+ `Q ${rightX} ${y1} ${x1} ${y1}`,
269
+ // bottom diamond zigzag edge ←
270
+ `L ${x1} ${y1}`,
271
+ zigzagRL(x0, x1, y1, 1),
272
+ // bottom-left corner
273
+ `L ${x0} ${y1}`,
274
+ `Q ${leftX} ${y1} ${leftX} ${y1 - R}`,
275
+ // left side up from bottom to tear notch
276
+ `L ${leftX} ${tearY + SR}`,
277
+ // semi-diamond bite: two lines forming a V-point inward from left
278
+ `L ${leftX + SR} ${tearY}`,
279
+ `L ${leftX} ${tearY - SR}`,
280
+ // left side up to top
281
+ `L ${leftX} ${y0 + R}`,
282
+ // top-left corner
283
+ `Q ${leftX} ${y0} ${x0} ${y0}`,
284
+ `Z`,
285
+ ].join(" ");
286
+
287
+ const clipId = "ticket-clip";
288
+ const innerId = "ticket-inner";
289
+
290
+ return (
291
+ <div style={{ position: "relative", width: "100%", maxWidth: 460 }}>
292
+ {/* SVG defs for clip path */}
293
+ <svg width="0" height="0" style={{ position: "absolute" }}>
294
+ <defs>
295
+ <clipPath id={clipId} clipPathUnits="userSpaceOnUse">
296
+ <path d={path} />
297
+ </clipPath>
298
+ </defs>
299
+ </svg>
300
+
301
+ {/* Outer shadow/glow layer */}
302
+ <div style={{
303
+ position: "absolute",
304
+ inset: -2,
305
+ borderRadius: 18,
306
+ boxShadow: "0 40px 100px rgba(0,0,0,0.95), 0 0 0 1px #1a1a1a",
307
+ pointerEvents: "none",
308
+ zIndex: 0,
309
+ }} />
310
+
311
+ {/* The actual ticket content clipped to shape */}
312
+ <div
313
+ style={{
314
+ position: "relative",
315
+ width: "100%",
316
+ clipPath: `url(#${clipId})`,
317
+ // Fallback border for browsers without clipPath
318
+ }}
319
+ >
320
+ {/* SVG border drawn on top of content */}
321
+ <svg
322
+ viewBox={`0 0 ${W} ${H}`}
323
+ width="100%"
324
+ style={{
325
+ position: "absolute", inset: 0, width: "100%", height: "100%",
326
+ pointerEvents: "none", zIndex: 50,
327
+ }}
328
+ preserveAspectRatio="none"
329
+ >
330
+ {/* Outer border */}
331
+ <path
332
+ d={path}
333
+ fill="none"
334
+ stroke="#2e2e2e"
335
+ strokeWidth="1.2"
336
+ />
337
+ {/* Inner inset border */}
338
+ <path
339
+ d={path}
340
+ fill="none"
341
+ stroke="#1e1e1e"
342
+ strokeWidth="3"
343
+ strokeDasharray="4 3"
344
+ opacity="0.5"
345
+ />
346
+
347
+ {/* Tear-line dashed rule */}
348
+ <line
349
+ x1={pad + SR + 4} y1={tearY}
350
+ x2={W - pad - SR - 4} y2={tearY}
351
+ stroke="#2a2a2a"
352
+ strokeWidth="1"
353
+ strokeDasharray="5 4"
354
+ />
355
+ {/* Tear scissors icon hint */}
356
+ <text x={W / 2 - 10} y={tearY - 5} fill="#333" fontSize="9" fontFamily="monospace" textAnchor="middle">✂ TEAR</text>
357
+
358
+ {/* Corner punch holes — diamond arrowhead shapes */}
359
+ {[
360
+ [pad + 28, pad + 28],
361
+ [W - pad - 28, pad + 28],
362
+ [pad + 28, H - pad - 28],
363
+ [W - pad - 28, H - pad - 28],
364
+ ].map(([cx, cy], i) => {
365
+ const ro = 9;
366
+ const ri = 4.5;
367
+ return (
368
+ <g key={i}>
369
+ <polygon
370
+ points={`${cx},${cy - ro} ${cx + ro},${cy} ${cx},${cy + ro} ${cx - ro},${cy}`}
371
+ fill="#0A0A0A" stroke="#2e2e2e" strokeWidth="1"
372
+ />
373
+ <polygon
374
+ points={`${cx},${cy - ri} ${cx + ri},${cy} ${cx},${cy + ri} ${cx - ri},${cy}`}
375
+ fill="none" stroke="#252525" strokeWidth="0.8"
376
+ />
377
+ </g>
378
+ );
379
+ })}
380
+
381
+ {/* Perforation diamond dots along tear line */}
382
+ {Array.from({ length: 18 }, (_, i) => {
383
+ const spacing = (W - pad * 2 - SR * 2 - 20) / 17;
384
+ const x = pad + SR + 10 + i * spacing;
385
+ const r = 2.2;
386
+ return (
387
+ <polygon
388
+ key={i}
389
+ points={`${x},${tearY - r} ${x + r},${tearY} ${x},${tearY + r} ${x - r},${tearY}`}
390
+ fill="#252525"
391
+ />
392
+ );
393
+ })}
394
+ </svg>
395
+
396
+ {children}
397
+ </div>
398
+ </div>
399
+ );
400
+ }
401
+
402
+ // ── Main component ────────────────────────────────────────────────────────────
403
+ export default function CyberTicket() {
404
+ const [pulse, setPulse] = useState(false);
405
+
406
+ useEffect(() => {
407
+ if (!document.getElementById("ibm-plex-mono")) {
408
+ const link = document.createElement("link");
409
+ link.id = "ibm-plex-mono";
410
+ link.rel = "stylesheet";
411
+ link.href = FONT_URL;
412
+ document.head.appendChild(link);
413
+ }
414
+ const iv = setInterval(() => setPulse((p) => !p), 1400);
415
+ return () => clearInterval(iv);
416
+ }, []);
417
+
418
+ const STUB_H = 130; // px — must roughly match SVG tearY portion
419
+
420
+ return (
421
+ <div
422
+ style={{
423
+ minHeight: "100vh",
424
+ background: "#060606",
425
+ display: "flex",
426
+ alignItems: "center",
427
+ justifyContent: "center",
428
+ padding: "60px 16px",
429
+ fontFamily: "'IBM Plex Mono', monospace",
430
+ position: "relative",
431
+ overflow: "hidden",
432
+ }}
433
+ >
434
+ {/* ambient radial glow */}
435
+ <div style={{
436
+ position: "absolute",
437
+ width: 600, height: 600,
438
+ background: "radial-gradient(circle, rgba(255,255,255,0.015) 0%, transparent 70%)",
439
+ left: "50%", top: "50%",
440
+ transform: "translate(-50%,-50%)",
441
+ pointerEvents: "none",
442
+ }} />
443
+ <GrainOverlay strength={0.13} />
444
+
445
+ <TicketShell stubHeight={130}>
446
+ {/* ── background fill */}
447
+ <div style={{
448
+ background: "#0A0A0A",
449
+ minHeight: 820,
450
+ position: "relative",
451
+ overflow: "hidden",
452
+ }}>
453
+ <GrainOverlay strength={0.2} />
454
+ <GeometricOverlay />
455
+
456
+ {/* 1 ── TOP HEADER BAR */}
457
+ <div style={{
458
+ background: "#0f0f0f",
459
+ borderBottom: "1px solid #1e1e1e",
460
+ padding: "16px 28px",
461
+ display: "flex",
462
+ alignItems: "center",
463
+ justifyContent: "space-between",
464
+ position: "relative",
465
+ zIndex: 20,
466
+ marginTop: 14, // clear top scallop
467
+ }}>
468
+ <div>
469
+ <div style={{
470
+ fontSize: 9, fontWeight: 700, letterSpacing: "0.32em",
471
+ color: "#FFF", textTransform: "uppercase",
472
+ }}>NEXUS PROTOCOL</div>
473
+ <div style={{ fontSize: 7.5, color: "#555", letterSpacing: "0.18em", marginTop: 1 }}>
474
+ CLASSIFIED ACCESS DOCUMENT
475
+ </div>
476
+ </div>
477
+ <div style={{ textAlign: "right" }}>
478
+ <div style={{ fontSize: 9, color: "#555", letterSpacing: "0.1em" }}>Ω-09</div>
479
+ <div style={{ fontSize: 7, color: "#333", marginTop: 1 }}>© 2025</div>
480
+ </div>
481
+ </div>
482
+
483
+ {/* 2 ── BRANDING BLOCK */}
484
+ <div style={{ padding: "22px 32px 14px", position: "relative", zIndex: 20 }}>
485
+ <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 6 }}>
486
+ <svg width="28" height="28" viewBox="0 0 28 28" fill="none">
487
+ <circle cx="14" cy="14" r="13" stroke="white" strokeWidth="1" />
488
+ <path d="M4 14 Q7 8 10 14 Q13 20 16 14 Q19 8 22 14 Q24 18 24 14"
489
+ stroke="white" strokeWidth="1.2" fill="none" strokeLinecap="round" />
490
+ <circle cx="14" cy="14" r="2" fill="white" />
491
+ </svg>
492
+ <div>
493
+ <div style={{
494
+ fontSize: 22, fontWeight: 700, letterSpacing: "0.18em",
495
+ color: "#FFF", textTransform: "uppercase", lineHeight: 1,
496
+ }}>NEURAL</div>
497
+ <div style={{
498
+ fontSize: 22, fontWeight: 400, letterSpacing: "0.34em",
499
+ color: "#666", textTransform: "uppercase", lineHeight: 1, marginTop: 2,
500
+ }}>ACCESS</div>
501
+ </div>
502
+ </div>
503
+ <div style={{
504
+ fontSize: 7.5, color: "#383838", letterSpacing: "0.22em", textTransform: "uppercase",
505
+ }}>
506
+ HIGH-CLEARANCE ADMISSION — SERIES 9 — OMEGA TIER
507
+ </div>
508
+ </div>
509
+
510
+ {/* 3 ── TERMINAL CIRCLE */}
511
+ <div style={{
512
+ padding: "0 28px", position: "relative", zIndex: 20,
513
+ display: "flex", justifyContent: "center",
514
+ }}>
515
+ <div style={{
516
+ width: 250, height: 250,
517
+ borderRadius: "50%",
518
+ border: "1px solid #2a2a2a",
519
+ overflow: "hidden",
520
+ position: "relative",
521
+ boxShadow: "0 0 0 6px #0e0e0e, 0 0 0 7px #1e1e1e",
522
+ }}>
523
+ <TerminalMask />
524
+ <GrainOverlay strength={0.26} />
525
+ </div>
526
+ </div>
527
+
528
+ {/* scan status pill */}
529
+ <div style={{
530
+ display: "flex", justifyContent: "center", marginTop: 12,
531
+ position: "relative", zIndex: 20,
532
+ }}>
533
+ <div style={{
534
+ display: "flex", alignItems: "center", gap: 6,
535
+ border: "1px solid #222", borderRadius: 999,
536
+ padding: "4px 14px",
537
+ background: "#0d0d0d",
538
+ }}>
539
+ <div style={{
540
+ width: 5, height: 5, borderRadius: "50%",
541
+ background: pulse ? "#FFF" : "#333",
542
+ transition: "background 0.4s",
543
+ }} />
544
+ <span style={{ fontSize: 7.5, letterSpacing: "0.2em", color: "#666", textTransform: "uppercase" }}>
545
+ SIGNAL {pulse ? "ACTIVE" : "PINGING"}
546
+ </span>
547
+ </div>
548
+ </div>
549
+
550
+ {/* 4 ── INFO GRID */}
551
+ <div style={{
552
+ padding: "24px 32px 0",
553
+ position: "relative", zIndex: 20,
554
+ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "16px 12px",
555
+ }}>
556
+ {[
557
+ { label: "BEARER", value: "AGENT_NX-44" },
558
+ { label: "ISSUED", value: "2025.03.06" },
559
+ { label: "CLEARANCE", value: "OMEGA / Ω" },
560
+ { label: "EXPIRES", value: "2025.12.31" },
561
+ { label: "SECTOR", value: "DELTA-9" },
562
+ { label: "NODE", value: "0xDEAD·BF9" },
563
+ ].map(({ label, value }) => (
564
+ <div key={label}>
565
+ <div style={{
566
+ fontSize: 7, color: "#3a3a3a", letterSpacing: "0.28em",
567
+ textTransform: "uppercase", marginBottom: 3,
568
+ }}>{label}</div>
569
+ <div style={{
570
+ fontSize: 11, color: "#CDCDCD", letterSpacing: "0.1em",
571
+ fontWeight: 600,
572
+ }}>{value}</div>
573
+ </div>
574
+ ))}
575
+ </div>
576
+
577
+ {/* subtle divider */}
578
+ <div style={{ padding: "22px 32px 0", position: "relative", zIndex: 20 }}>
579
+ <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
580
+ {Array.from({ length: 3 }).map((_, i) => (
581
+ <div key={i} style={{ flex: 1, height: "1px", background: i === 1 ? "#222" : "#161616" }} />
582
+ ))}
583
+ <svg width="10" height="10" viewBox="0 0 10 10" fill="none" style={{ opacity: 0.3 }}>
584
+ <polygon points="5,0 10,10 0,10" stroke="white" strokeWidth="1" fill="none" />
585
+ </svg>
586
+ {Array.from({ length: 3 }).map((_, i) => (
587
+ <div key={i} style={{ flex: 1, height: "1px", background: i === 1 ? "#222" : "#161616" }} />
588
+ ))}
589
+ </div>
590
+ </div>
591
+
592
+ {/* ── STUB SECTION (below tear line) ── */}
593
+ {/* Spacer to push stub below the scalloped tear cutout */}
594
+ <div style={{ height: 36 }} />
595
+
596
+ <div style={{
597
+ padding: "4px 32px 32px",
598
+ position: "relative", zIndex: 20,
599
+ display: "flex", alignItems: "center", justifyContent: "space-between",
600
+ }}>
601
+ {/* Barcode */}
602
+ <div>
603
+ <Barcode />
604
+ <div style={{ fontSize: 7, color: "#2e2e2e", letterSpacing: "0.16em", marginTop: 3 }}>
605
+ NX-9912-DELTA-44-0x2F
606
+ </div>
607
+ </div>
608
+ {/* Stamp area */}
609
+ <div style={{ textAlign: "right" }}>
610
+ <div style={{ display: "flex", gap: 6, justifyContent: "flex-end", marginBottom: 6 }}>
611
+ {["★", "◈", "▲"].map((icon, i) => (
612
+ <span key={i} style={{
613
+ fontSize: i === 0 ? 11 : 9, color: "#3a3a3a", fontFamily: "monospace",
614
+ }}>{icon}</span>
615
+ ))}
616
+ </div>
617
+ <div style={{
618
+ fontSize: 7, color: "#333", letterSpacing: "0.22em",
619
+ textTransform: "uppercase", lineHeight: 1.7,
620
+ }}>
621
+ ADMIT<br />ONE
622
+ </div>
623
+ </div>
624
+ </div>
625
+
626
+ {/* bottom vignette */}
627
+ <div style={{
628
+ position: "absolute", bottom: 0, left: 0, right: 0, height: 80,
629
+ background: "linear-gradient(to top, rgba(0,0,0,0.6), transparent)",
630
+ pointerEvents: "none", zIndex: 8,
631
+ }} />
632
+ </div>
633
+ </TicketShell>
634
+
635
+ {/* ambient page label */}
636
+ <div style={{
637
+ position: "absolute", bottom: 18, left: "50%", transform: "translateX(-50%)",
638
+ fontSize: 7.5, letterSpacing: "0.3em", color: "#222",
639
+ fontFamily: "'IBM Plex Mono', monospace", textTransform: "uppercase",
640
+ zIndex: 20, whiteSpace: "nowrap",
641
+ }}>
642
+ NEXUS PROTOCOL — DOCUMENT RENDER v9.1 — CLASSIFIED
643
+ </div>
644
+ </div>
645
+ );
646
+ }