Created
March 10, 2026 16:42
-
-
Save awwaiid/7c63c0b0543424c422823df8051b2757 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Sci-Fi Horizon Index</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.23.2/babel.min.js"></script> | |
| <style> | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { background: #07080f; } | |
| ::-webkit-scrollbar { width: 4px; background: #111; } | |
| ::-webkit-scrollbar-thumb { background: #333; } | |
| .row-hover:hover { background: rgba(255,255,255,0.04) !important; } | |
| .btn-hover:hover { opacity: 1 !important; filter: brightness(1.2); } | |
| </style> | |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| <link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet" /> | |
| </head> | |
| <body> | |
| <div id="root"></div> | |
| <script type="text/babel"> | |
| const { useState, useMemo } = React; | |
| const NOW = 2026; | |
| const EVENTS = [ | |
| { id: 1, name: "Moon Landing", category: "Space", conceived: 1865, credible: 1957, achieved: 1969, note: "Jules Verne wrote lunar voyages in 1865. Sputnik (1957) turned it from fantasy to a race." }, | |
| { id: 2, name: "World Wide Web", category: "Computing", conceived: 1945, credible: 1969, achieved: 1991, note: "Vannevar Bush's 'memex' (1945) was the conceptual blueprint. ARPANET (1969) proved the network." }, | |
| { id: 3, name: "Video Calling", category: "Computing", conceived: 1879, credible: 1964, achieved: 2010, note: "Speculated since the telephone era. AT&T's 1964 Picturephone made it feel imminent for decades." }, | |
| { id: 4, name: "Human Genome Sequenced", category: "Biology", conceived: 1953, credible: 1977, achieved: 2003, note: "The double helix (1953) sparked the dream. Sanger sequencing (1977) made it a matter of scale and cost." }, | |
| { id: 5, name: "Chess AI Beats Champion", category: "AI", conceived: 1950, credible: 1977, achieved: 1997, note: "Turing described a chess algorithm in 1950. By the late 70s, programs reached master level." }, | |
| { id: 6, name: "Smartphone", category: "Computing", conceived: 1968, credible: 1993, achieved: 2007, note: "Alan Kay's Dynabook (1968) was the vision. The Newton (1993) proved the pocket computer category." }, | |
| { id: 7, name: "Mammal Cloning (Dolly)", category: "Biology", conceived: 1932, credible: 1975, achieved: 1996, note: "Huxley's Brave New World (1932) popularized the idea. By 1975, biologists knew it was a matter of technique." }, | |
| { id: 8, name: "CRISPR Gene Editing", category: "Biology", conceived: 1972, credible: 2007, achieved: 2012, note: "Recombinant DNA (1972) started the dream of editing. The CRISPR mechanism was described in bacteria by 2007." }, | |
| { id: 9, name: "Reusable Orbital Rocket", category: "Space", conceived: 1928, credible: 2008, achieved: 2015, note: "Rocket pioneers dreamed of reusability in the 1920s. Falcon 1's 2008 success made it an engineering problem." }, | |
| { id: 10, name: "Conversational AI", category: "AI", conceived: 1950, credible: 2019, achieved: 2022, note: "The Turing Test (1950) defined the goal. GPT-2 scaling results (2019) made capability feel inevitable." }, | |
| { id: 11, name: "mRNA Vaccine", category: "Biology", conceived: 1961, credible: 2013, achieved: 2020, note: "mRNA was discovered in 1961. Moderna's founding and early trials (2013) moved it firmly to engineering." }, | |
| { id: 12, name: "Nuclear Weapon", category: "Physics", conceived: 1914, credible: 1939, achieved: 1945, note: "H.G. Wells coined 'atomic bomb' in 1914. Hahn's fission discovery (1938) made it suddenly, terrifyingly credible." }, | |
| { id: 13, name: "GPS Navigation", category: "Computing", conceived: 1945, credible: 1983, achieved: 2000, note: "Navigation satellites were conceptualized post-WWII. Reagan's 1983 order made consumer GPS a policy question." }, | |
| { id: 14, name: "Self-Driving Cars", category: "AI", conceived: 1939, credible: 2016, achieved: 2038, overdue: true, note: "GM's 1939 World's Fair promised automated highways. By 2016 every automaker said '5 years away.' Still waiting." }, | |
| { id: 15, name: "Nuclear Fusion Power", category: "Physics", conceived: 1950, credible: 1997, achieved: 2075, overdue: true, note: "Fusion research began in the 1950s. JET's 1997 record proved the physics — but it's been '30 years away' since." }, | |
| { id: 16, name: "Jetpack Commuting", category: "Space", conceived: 1928, credible: 1961, achieved: 2084, overdue: true, note: "Buck Rogers (1928) made jetpacks iconic. Bell's 1961 Rocket Belt proved the hardware — but 21-second flight time doomed scale." }, | |
| { id: 17, name: "Flying Cars (consumer)", category: "Space", conceived: 1917, credible: 2015, achieved: 2050, overdue: true, note: "The first flying car prototype flew in 1917. The eVTOL wave (2015+) made it credible again — adoption keeps receding." }, | |
| ]; | |
| const CATEGORIES = ["All", "AI", "Biology", "Computing", "Physics", "Space"]; | |
| const CATEGORY_COLORS = { AI: "#f59e0b", Biology: "#34d399", Computing: "#60a5fa", Physics: "#f87171", Space: "#a78bfa" }; | |
| const SORT_OPTIONS = [ | |
| { value: "conceived", label: "Conception" }, | |
| { value: "achieved", label: "Event Year" }, | |
| { value: "scifi_span", label: "Sci-Fi Span" }, | |
| { value: "engineering_span", label: "Eng. Span" }, | |
| ]; | |
| function SciFiHorizon() { | |
| const [selectedCategory, setSelectedCategory] = useState("All"); | |
| const [sortBy, setSortBy] = useState("conceived"); | |
| const [hoveredId, setHoveredId] = useState(null); | |
| const [selectedId, setSelectedId] = useState(null); | |
| const filtered = useMemo(() => { | |
| return EVENTS | |
| .filter(e => selectedCategory === "All" || e.category === selectedCategory) | |
| .map(e => ({ ...e, scifi_span: e.credible - e.conceived, engineering_span: e.achieved - e.credible })) | |
| .sort((a, b) => { | |
| if (sortBy === "achieved") return a.achieved - b.achieved; | |
| if (sortBy === "conceived") return a.conceived - b.conceived; | |
| if (sortBy === "scifi_span") return b.scifi_span - a.scifi_span; | |
| if (sortBy === "engineering_span") return b.engineering_span - a.engineering_span; | |
| return 0; | |
| }); | |
| }, [selectedCategory, sortBy]); | |
| const minYear = Math.min(...filtered.map(e => e.conceived)) - 10; | |
| const maxYear = Math.max(...filtered.map(e => e.achieved)) + 10; | |
| const span = maxYear - minYear; | |
| const toX = (year) => `${((year - minYear) / span) * 100}%`; | |
| const toW = (y1, y2) => `${((y2 - y1) / span) * 100}%`; | |
| const nowPct = ((NOW - minYear) / span) * 100; | |
| const active = (selectedId || hoveredId) | |
| ? filtered.find(e => e.id === (selectedId || hoveredId)) | |
| : null; | |
| return ( | |
| <div style={{ minHeight: "100vh", background: "#07080f", color: "#e0e0e0", fontFamily: "'Space Mono', monospace", paddingBottom: 60 }}> | |
| {/* Header */} | |
| <div style={{ padding: "44px 40px 28px", borderBottom: "1px solid #141428", background: "linear-gradient(180deg, #0c0d1e 0%, #07080f 100%)", position: "relative", overflow: "hidden" }}> | |
| <div style={{ position: "absolute", inset: 0, backgroundImage: "radial-gradient(ellipse at 75% 50%, rgba(96,80,200,0.1) 0%, transparent 65%)", pointerEvents: "none" }} /> | |
| <div style={{ fontSize: 10, letterSpacing: 4, color: "#7777bb", marginBottom: 10 }}>SPECULATIVE FUTURES RESEARCH DIVISION</div> | |
| <h1 style={{ fontFamily: "'Orbitron'", fontSize: "clamp(22px, 4vw, 44px)", fontWeight: 900, margin: "0 0 12px", background: "linear-gradient(135deg, #a78bfa 30%, #60a5fa 100%)", WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent" }}> | |
| SCI-FI HORIZON INDEX | |
| </h1> | |
| <p style={{ color: "#9999cc", fontSize: 12, margin: 0, maxWidth: 600, lineHeight: 1.9 }}> | |
| Three phases of every world-changing idea: | |
| <span style={{ color: "#a78bfa" }}>pure imagination</span> → | |
| <span style={{ color: "#60a5fa" }}>engineering problem</span> → | |
| <span style={{ color: "#34d399" }}>reality</span>. | |
| Hover or click any row to inspect. Overdue events stretch past today. | |
| </p> | |
| </div> | |
| {/* Phase key */} | |
| <div style={{ padding: "16px 40px", borderBottom: "1px solid #0e0e1e", display: "flex", gap: 28, flexWrap: "wrap", alignItems: "center" }}> | |
| {[ | |
| { swatch: <div style={{ width: 28, height: 10, background: "linear-gradient(90deg, #a78bfa33, #a78bfa88)", border: "1px solid #a78bfa44", borderRadius: "3px 0 0 3px" }} />, label: "SCI-FI PHASE", sub: "Conceived → Credible" }, | |
| { swatch: <div style={{ width: 28, height: 10, background: "linear-gradient(90deg, #60a5fa66, #60a5facc)", border: "1px solid #60a5fa44", borderRadius: "0 3px 3px 0" }} />, label: "ENGINEERING PHASE", sub: "Credible → Achieved" }, | |
| { swatch: <div style={{ width: 10, height: 10, borderRadius: "50%", background: "#34d399", border: "2px solid #07080f" }} />, label: "ACHIEVED", sub: "Event happened" }, | |
| { swatch: <div style={{ width: 28, height: 10, background: "repeating-linear-gradient(90deg, #60a5fa22 0px, #60a5fa44 8px, #f8717122 8px, #f8717133 16px)", border: "1px solid #f8717144" }} />, label: "OVERDUE", sub: "Engineering phase still running" }, | |
| { swatch: <div style={{ width: 2, height: 14, background: "#f87171", opacity: 0.5 }} />, label: "NOW (2026)", sub: "" }, | |
| ].map(({ swatch, label, sub }) => ( | |
| <div key={label} style={{ display: "flex", alignItems: "center", gap: 8 }}> | |
| <div style={{ display: "flex", alignItems: "center" }}>{swatch}</div> | |
| <div> | |
| <div style={{ fontSize: 9, color: "#aaa", letterSpacing: 1.5 }}>{label}</div> | |
| {sub && <div style={{ fontSize: 8, color: "#555" }}>{sub}</div>} | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| <div style={{ padding: "24px 40px" }}> | |
| {/* Controls */} | |
| <div style={{ display: "flex", gap: 20, marginBottom: 24, flexWrap: "wrap", alignItems: "center" }}> | |
| <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}> | |
| <span style={{ fontSize: 9, color: "#666", letterSpacing: 2 }}>FILTER</span> | |
| {CATEGORIES.map(c => ( | |
| <button key={c} className="btn-hover" onClick={() => setSelectedCategory(c)} style={{ | |
| background: selectedCategory === c ? (c === "All" ? "#a78bfa" : CATEGORY_COLORS[c]) : "transparent", | |
| color: selectedCategory === c ? "#07080f" : (c === "All" ? "#a78bfa" : CATEGORY_COLORS[c] || "#888"), | |
| border: `1px solid ${c === "All" ? "#a78bfa" : CATEGORY_COLORS[c] || "#444"}`, | |
| borderRadius: 20, padding: "4px 13px", fontSize: 9, fontFamily: "'Space Mono'", | |
| letterSpacing: 1, cursor: "pointer", opacity: selectedCategory === c ? 1 : 0.5, transition: "all 0.15s", | |
| }}>{c.toUpperCase()}</button> | |
| ))} | |
| </div> | |
| <div style={{ display: "flex", gap: 6, alignItems: "center", marginLeft: "auto" }}> | |
| <span style={{ fontSize: 9, color: "#666", letterSpacing: 2 }}>SORT</span> | |
| {SORT_OPTIONS.map(opt => ( | |
| <button key={opt.value} className="btn-hover" onClick={() => setSortBy(opt.value)} style={{ | |
| background: sortBy === opt.value ? "rgba(167,139,250,0.15)" : "transparent", | |
| color: sortBy === opt.value ? "#a78bfa" : "#666", | |
| border: `1px solid ${sortBy === opt.value ? "#a78bfa44" : "#222"}`, | |
| borderRadius: 4, padding: "4px 10px", fontSize: 9, fontFamily: "'Space Mono'", | |
| letterSpacing: 1, cursor: "pointer", opacity: sortBy === opt.value ? 1 : 0.65, transition: "all 0.15s", | |
| }}>{opt.label.toUpperCase()}</button> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Detail card */} | |
| {active && ( | |
| <div style={{ | |
| background: `rgba(${active.category === 'AI' ? '245,158,11' : active.category === 'Biology' ? '52,211,153' : active.category === 'Computing' ? '96,165,250' : active.category === 'Physics' ? '248,113,113' : '167,139,250'},0.06)`, | |
| border: `1px solid ${CATEGORY_COLORS[active.category]}33`, | |
| borderRadius: 14, padding: "18px 22px", marginBottom: 20, | |
| display: "flex", gap: 24, flexWrap: "wrap", alignItems: "flex-start", transition: "all 0.15s", | |
| }}> | |
| <div style={{ flex: 1, minWidth: 180 }}> | |
| <div style={{ fontSize: 9, color: CATEGORY_COLORS[active.category], letterSpacing: 3, marginBottom: 6 }}> | |
| {active.category.toUpperCase()}{active.overdue ? " · OVERDUE" : ""} | |
| </div> | |
| <div style={{ fontSize: 18, fontFamily: "'Orbitron'", fontWeight: 700, color: "#fff", marginBottom: 8 }}>{active.name}</div> | |
| <div style={{ fontSize: 11, color: "#aaaacc", lineHeight: 1.8 }}>{active.note}</div> | |
| </div> | |
| <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}> | |
| {[ | |
| ["CONCEIVED", active.conceived, "#a78bfa"], | |
| ["CREDIBLE", active.credible, "#60a5fa"], | |
| ["ACHIEVED", active.overdue ? `~${active.achieved}` : active.achieved, active.overdue ? "#f87171" : "#34d399"], | |
| ["SCI-FI SPAN", `${active.scifi_span}y`, "#a78bfa"], | |
| ["ENG. SPAN", `${active.engineering_span}y`, active.engineering_span > 40 ? "#f87171" : "#60a5fa"], | |
| ].map(([label, val, color]) => ( | |
| <div key={label} style={{ background: "rgba(0,0,0,0.35)", border: "1px solid #1a1a2e", borderRadius: 10, padding: "10px 14px", textAlign: "center", minWidth: 72 }}> | |
| <div style={{ fontSize: 7, color: "#777", letterSpacing: 2, marginBottom: 5 }}>{label}</div> | |
| <div style={{ fontFamily: "'Orbitron'", fontSize: 16, fontWeight: 700, color }}>{val}</div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| {/* Timeline */} | |
| <div style={{ background: "rgba(255,255,255,0.015)", border: "1px solid #141428", borderRadius: 16, padding: "20px 20px 16px", overflowX: "auto" }}> | |
| <div style={{ minWidth: 600 }}> | |
| {/* Year axis */} | |
| <div style={{ position: "relative", height: 20, marginLeft: 190, marginBottom: 6 }}> | |
| {Array.from({ length: Math.ceil(span / 25) + 1 }, (_, i) => { | |
| const yr = Math.ceil(minYear / 25) * 25 + i * 25; | |
| if (yr < minYear || yr > maxYear) return null; | |
| const pct = ((yr - minYear) / span) * 100; | |
| return ( | |
| <div key={yr} style={{ position: "absolute", left: `${pct}%`, transform: "translateX(-50%)" }}> | |
| <div style={{ fontSize: 8, color: yr === NOW ? "#f87171" : "#555", whiteSpace: "nowrap", fontWeight: yr === NOW ? 700 : 400 }}> | |
| {yr === NOW ? "NOW" : yr} | |
| </div> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| {/* Event rows */} | |
| <div style={{ display: "flex", flexDirection: "column", gap: 4 }}> | |
| {filtered.map((e) => { | |
| const color = CATEGORY_COLORS[e.category]; | |
| const isActive = hoveredId === e.id || selectedId === e.id; | |
| return ( | |
| <div key={e.id} className="row-hover" | |
| onMouseEnter={() => setHoveredId(e.id)} | |
| onMouseLeave={() => setHoveredId(null)} | |
| onClick={() => setSelectedId(selectedId === e.id ? null : e.id)} | |
| style={{ display: "flex", alignItems: "center", padding: "5px 8px 5px 0", borderRadius: 8, cursor: "pointer", background: isActive ? "rgba(255,255,255,0.04)" : "transparent", transition: "background 0.1s" }} | |
| > | |
| <div style={{ width: 190, flexShrink: 0, textAlign: "right", paddingRight: 12 }}> | |
| <div style={{ fontSize: 11, color: isActive ? "#fff" : "#ccc" }}>{e.name}</div> | |
| <div style={{ fontSize: 8, color, opacity: 0.8, marginTop: 1 }}>{e.category} · {e.conceived}–{e.achieved}</div> | |
| </div> | |
| <div style={{ flex: 1, position: "relative", height: 30 }}> | |
| {/* Grid lines */} | |
| {Array.from({ length: Math.ceil(span / 25) + 1 }, (_, i) => { | |
| const yr = Math.ceil(minYear / 25) * 25 + i * 25; | |
| if (yr < minYear || yr > maxYear) return null; | |
| const pct = ((yr - minYear) / span) * 100; | |
| return <div key={yr} style={{ position: "absolute", left: `${pct}%`, top: 0, bottom: 0, width: 1, background: yr === NOW ? "#f8717122" : "#ffffff06" }} />; | |
| })} | |
| {/* NOW line */} | |
| <div style={{ position: "absolute", left: `${nowPct}%`, top: -2, bottom: -2, width: 1.5, background: "#f8717155", zIndex: 3 }} /> | |
| {/* Sci-fi phase */} | |
| <div style={{ position: "absolute", left: toX(e.conceived), width: toW(e.conceived, e.credible), top: "50%", transform: "translateY(-50%)", height: isActive ? 20 : 14, background: `linear-gradient(90deg, ${color}22, ${color}77)`, borderRadius: "4px 0 0 4px", border: `1px solid ${color}33`, transition: "height 0.12s", zIndex: 1 }} /> | |
| {/* Engineering phase */} | |
| <div style={{ position: "absolute", left: toX(e.credible), width: toW(e.credible, e.achieved), top: "50%", transform: "translateY(-50%)", height: isActive ? 20 : 14, background: e.overdue ? "repeating-linear-gradient(90deg, #60a5fa1a 0px, #60a5fa44 8px, #f871711a 8px, #f8717133 16px)" : "linear-gradient(90deg, #60a5fa55, #60a5facc)", borderRadius: e.overdue ? "0" : "0 4px 4px 0", border: `1px solid ${e.overdue ? "#f87171" : "#60a5fa"}33`, transition: "height 0.12s", zIndex: 1 }} /> | |
| {/* Conceived dot */} | |
| <div style={{ position: "absolute", left: toX(e.conceived), top: "50%", transform: "translate(-50%, -50%)", width: 6, height: 6, borderRadius: "50%", background: color, border: "1px solid #07080f", opacity: 0.75, zIndex: 2 }} /> | |
| {/* Credible divider */} | |
| <div style={{ position: "absolute", left: toX(e.credible), top: "50%", transform: "translate(-50%, -50%)", width: 2, height: isActive ? 24 : 18, background: "#60a5fa", opacity: 0.5, zIndex: 2 }} /> | |
| {/* Achieved */} | |
| {!e.overdue | |
| ? <div style={{ position: "absolute", left: toX(e.achieved), top: "50%", transform: "translate(-50%, -50%)", width: isActive ? 12 : 8, height: isActive ? 12 : 8, borderRadius: "50%", background: "#34d399", border: "2px solid #07080f", boxShadow: isActive ? "0 0 10px #34d399aa" : "none", zIndex: 2, transition: "all 0.12s" }} /> | |
| : <div style={{ position: "absolute", left: `calc(${toX(e.achieved)} + 2px)`, top: "50%", transform: "translateY(-50%)", fontSize: 13, color: "#f87171", lineHeight: 1, zIndex: 2 }}>▷</div> | |
| } | |
| </div> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| </div> | |
| {/* Stats */} | |
| <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(170px, 1fr))", gap: 10, marginTop: 20 }}> | |
| {[ | |
| { label: "LONGEST SCI-FI PHASE", fn: arr => [...arr].sort((a,b) => b.scifi_span - a.scifi_span)[0], color: "#a78bfa", fmt: e => `${e.name} (${e.scifi_span}y)` }, | |
| { label: "SHORTEST SCI-FI PHASE", fn: arr => [...arr].sort((a,b) => a.scifi_span - b.scifi_span)[0], color: "#a78bfa", fmt: e => `${e.name} (${e.scifi_span}y)` }, | |
| { label: "FASTEST TO BUILD", fn: arr => [...arr].filter(e => !e.overdue).sort((a,b) => a.engineering_span - b.engineering_span)[0], color: "#34d399", fmt: e => `${e.name} (${e.engineering_span}y)` }, | |
| { label: "MOST OVERDUE", fn: arr => [...arr].filter(e => e.overdue).sort((a,b) => b.engineering_span - a.engineering_span)[0], color: "#f87171", fmt: e => `${e.name} (${e.engineering_span}y eng.)` }, | |
| ].map(({ label, fn, color, fmt }) => { | |
| const e = fn(filtered); | |
| return ( | |
| <div key={label} style={{ background: "rgba(255,255,255,0.02)", border: "1px solid #141428", borderRadius: 10, padding: "12px 14px" }}> | |
| <div style={{ fontSize: 7, letterSpacing: 2, color: "#666", marginBottom: 7 }}>{label}</div> | |
| <div style={{ fontSize: 10, color, lineHeight: 1.5 }}>{e ? fmt(e) : "—"}</div> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| ReactDOM.createRoot(document.getElementById("root")).render(<SciFiHorizon />); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment