Skip to content

Instantly share code, notes, and snippets.

@loktar00
Created May 30, 2026 01:38
Show Gist options
  • Select an option

  • Save loktar00/10b3a1918d6136f81f05216b1810c94d to your computer and use it in GitHub Desktop.

Select an option

Save loktar00/10b3a1918d6136f81f05216b1810c94d to your computer and use it in GitHub Desktop.
Virtual boy pages
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>VIRTUAL BOY — The Red Archive / A Retro Hardware Microsite</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Major+Mono+Display&family=Share+Tech+Mono&family=VT323&family=Orbitron:wght@500;700;900&display=swap" rel="stylesheet">
<style>
/* ---------- RESET ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
background:#000;
color:#e8c9c9;
font-family:'Share Tech Mono',monospace;
line-height:1.6;
overflow-x:hidden;
-webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;border:none;background:none;color:inherit}
/* ---------- GLOBAL TEXTURE / SCANLINES ---------- */
body::before{
content:"";position:fixed;inset:0;pointer-events:none;z-index:9998;
background:repeating-linear-gradient(
to bottom,
rgba(0,0,0,0) 0px,
rgba(0,0,0,0) 2px,
rgba(0,0,0,.18) 3px,
rgba(0,0,0,0) 4px
);
mix-blend-mode:multiply;
opacity:.55;
}
body::after{
content:"";position:fixed;inset:0;pointer-events:none;z-index:9999;
background:
radial-gradient(ellipse at center, rgba(0,0,0,0) 55%, rgba(0,0,0,.75) 100%),
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
mix-blend-mode:screen;
opacity:.35;
}
:root{
--red-ink:#ff1033;
--red-bright:#ff3a55;
--red-deep:#a30018;
--red-dark:#4a0008;
--red-glow:rgba(255,20,50,.45);
--panel:#0a0406;
--panel-2:#120608;
--line:#2a0610;
}
/* ---------- UTIL ---------- */
.wrap{max-width:1280px;margin:0 auto;padding:0 28px}
.eyebrow{
font-family:'VT323',monospace;
font-size:18px;letter-spacing:.35em;text-transform:uppercase;
color:var(--red-bright);
display:inline-flex;align-items:center;gap:10px;
}
.eyebrow::before{content:"";width:26px;height:1px;background:var(--red-ink);box-shadow:0 0 12px var(--red-glow)}
.section-title{
font-family:'Major Mono Display',monospace;
font-size:clamp(36px,5vw,64px);
line-height:.95;letter-spacing:-.01em;
color:#fff;text-transform:lowercase;
margin:14px 0 18px;
}
.section-title span.red{color:var(--red-ink);text-shadow:0 0 24px var(--red-glow)}
.lede{max-width:720px;color:#c8a5a5;font-size:17px}
section{padding:110px 0;position:relative}
.grid-2{display:grid;grid-template-columns:1.1fr .9fr;gap:60px;align-items:center}
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
@media (max-width:960px){
.grid-2,.grid-3,.grid-4{grid-template-columns:1fr}
}
/* ---------- HEADER ---------- */
header.site{
position:fixed;top:0;left:0;right:0;z-index:500;
backdrop-filter:blur(8px);
background:linear-gradient(180deg, rgba(0,0,0,.85), rgba(0,0,0,.2));
border-bottom:1px solid rgba(255,16,51,.18);
}
.nav{display:flex;align-items:center;justify-content:space-between;padding:16px 28px;max-width:1440px;margin:0 auto}
.logo{
font-family:'Major Mono Display',monospace;
font-size:20px;color:#fff;letter-spacing:.02em;text-transform:lowercase;
display:flex;align-items:center;gap:12px;
}
.logo .dot{
width:10px;height:10px;background:var(--red-ink);border-radius:50%;
box-shadow:0 0 12px var(--red-ink),0 0 28px var(--red-glow);
animation:pulse 2s infinite ease-in-out;
}
@keyframes pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.3);opacity:.7}}
nav ul{display:flex;gap:28px;list-style:none;font-size:13px;letter-spacing:.25em;text-transform:uppercase}
nav a{color:#b89999;transition:color .25s,text-shadow .25s;position:relative}
nav a:hover{color:#fff;text-shadow:0 0 14px var(--red-glow)}
nav a::after{content:"";position:absolute;left:0;bottom:-6px;width:0;height:1px;background:var(--red-ink);transition:width .3s}
nav a:hover::after{width:100%}
.btn{
display:inline-flex;align-items:center;gap:10px;
padding:12px 20px;border:1px solid var(--red-ink);
color:#fff;text-transform:uppercase;letter-spacing:.25em;font-size:12px;
background:linear-gradient(180deg, rgba(255,16,51,.08), rgba(255,16,51,.02));
transition:all .25s;position:relative;overflow:hidden;
}
.btn::before{content:"";position:absolute;inset:0;background:var(--red-ink);transform:translateY(100%);transition:transform .3s;z-index:-1}
.btn:hover::before{transform:translateY(0)}
.btn:hover{color:#000;border-color:#fff}
.btn.ghost{border-color:rgba(255,255,255,.3)}
.btn.ghost::before{background:#fff}
/* ---------- HERO ---------- */
.hero{
position:relative;min-height:100vh;padding-top:80px;
display:flex;align-items:center;justify-content:center;
overflow:hidden;isolation:isolate;
}
#hero-canvas{position:absolute;inset:0;width:100%;height:100%;z-index:0}
.hero-inner{position:relative;z-index:2;text-align:center;padding:0 24px;max-width:1100px}
.hero-meta{
font-family:'VT323',monospace;font-size:16px;color:var(--red-bright);
letter-spacing:.5em;text-transform:uppercase;margin-bottom:24px;
display:inline-flex;align-items:center;gap:14px;
}
.hero-meta::before,.hero-meta::after{content:"";width:42px;height:1px;background:var(--red-ink);box-shadow:0 0 14px var(--red-glow)}
.hero h1{
font-family:'Major Mono Display',monospace;
font-size:clamp(52px,11vw,180px);line-height:.85;letter-spacing:-.02em;
color:#fff;text-transform:lowercase;margin:0 0 8px;
text-shadow:0 0 40px rgba(255,16,51,.35);
}
.hero h1 .r{color:var(--red-ink);display:inline-block}
.hero h1 .dim{color:var(--red-deep)}
.hero .sub{
font-family:'Orbitron',sans-serif;font-weight:500;
font-size:clamp(14px,1.4vw,18px);letter-spacing:.4em;text-transform:uppercase;
color:#d89ea3;margin:18px auto 32px;max-width:720px;
}
.hero .tagline{
font-family:'VT323',monospace;font-size:22px;color:#f0c2c2;
max-width:620px;margin:0 auto 44px;line-height:1.4;
}
.hero .tagline em{color:var(--red-bright);font-style:normal}
.hero-ctas{display:flex;gap:18px;justify-content:center;flex-wrap:wrap}
.hero-footer{
position:absolute;left:0;right:0;bottom:18px;z-index:3;
display:flex;justify-content:space-between;align-items:center;
padding:0 28px;font-family:'VT323',monospace;font-size:15px;
color:#886;letter-spacing:.2em;text-transform:uppercase;
}
.hero-footer .blink{color:var(--red-bright);animation:blink 1.2s steps(2) infinite}
@keyframes blink{50%{opacity:0}}
.scroll-hint{display:flex;flex-direction:column;align-items:center;gap:8px}
.scroll-hint .line{width:1px;height:34px;background:linear-gradient(180deg,var(--red-ink),transparent);animation:drop 1.8s infinite}
@keyframes drop{0%{transform:scaleY(.2);transform-origin:top}60%{transform:scaleY(1);transform-origin:top}61%{transform-origin:bottom}100%{transform:scaleY(.2);transform-origin:bottom}}
/* ---------- PANELS / CARDS ---------- */
.panel{
background:linear-gradient(180deg,var(--panel-2),var(--panel));
border:1px solid var(--line);
padding:28px;position:relative;
transition:border-color .3s, transform .3s, box-shadow .3s;
}
.panel:hover{border-color:var(--red-deep);box-shadow:0 0 30px rgba(255,16,51,.08)}
.panel::before{
content:"";position:absolute;top:0;left:0;width:18px;height:18px;
border-top:1px solid var(--red-ink);border-left:1px solid var(--red-ink);
}
.panel::after{
content:"";position:absolute;bottom:0;right:0;width:18px;height:18px;
border-bottom:1px solid var(--red-ink);border-right:1px solid var(--red-ink);
}
.tag{
display:inline-block;padding:4px 10px;font-size:11px;letter-spacing:.3em;
text-transform:uppercase;color:var(--red-bright);border:1px solid var(--red-deep);
background:rgba(255,16,51,.05);
}
/* ---------- HARDWARE STORY ---------- */
.story-grid{display:grid;grid-template-columns:1fr 1fr;gap:70px;align-items:start}
@media(max-width:960px){.story-grid{grid-template-columns:1fr}}
.story p{margin-bottom:18px;color:#c5a5a5;font-size:16px}
.story .pull{
font-family:'Major Mono Display',monospace;font-size:28px;line-height:1.25;
color:#fff;padding:28px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
margin:24px 0;
}
.story .pull .r{color:var(--red-ink)}
.artifact{
aspect-ratio:3/4;background:#050203;border:1px solid var(--line);position:relative;overflow:hidden;
}
.artifact svg{width:100%;height:100%;display:block}
.artifact .label{
position:absolute;left:14px;bottom:14px;font-family:'VT323',monospace;
font-size:14px;color:var(--red-bright);letter-spacing:.3em;text-transform:uppercase;
}
/* ---------- PRODUCT OVERVIEW ---------- */
.hw-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:18px}
@media(max-width:1000px){.hw-grid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:600px){.hw-grid{grid-template-columns:repeat(2,1fr)}}
.hw{
background:linear-gradient(180deg,#0c0406,#060203);
border:1px solid var(--line);padding:22px;position:relative;min-height:260px;
display:flex;flex-direction:column;justify-content:space-between;
transition:all .3s;overflow:hidden;
}
.hw:hover{border-color:var(--red-ink);transform:translateY(-4px)}
.hw:hover .hw-icon{filter:drop-shadow(0 0 14px var(--red-glow))}
.hw-num{font-family:'VT323',monospace;font-size:14px;color:var(--red-deep);letter-spacing:.3em}
.hw-icon{width:100%;height:110px;margin:10px 0;display:flex;align-items:center;justify-content:center;transition:filter .3s}
.hw h4{font-family:'Orbitron',sans-serif;font-size:15px;color:#fff;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px}
.hw p{font-size:13px;color:#a88;line-height:1.5}
/* ---------- FEATURES ---------- */
.feat{
padding:32px 28px;border:1px solid var(--line);
background:
linear-gradient(180deg, rgba(255,16,51,.03), rgba(0,0,0,0)),
repeating-linear-gradient(45deg, transparent 0 14px, rgba(255,16,51,.025) 14px 15px);
position:relative;transition:all .35s;
}
.feat:hover{border-color:var(--red-ink);background-color:rgba(255,16,51,.04);transform:translateY(-3px)}
.feat .idx{
font-family:'Major Mono Display',monospace;font-size:36px;color:var(--red-ink);
line-height:1;margin-bottom:18px;text-shadow:0 0 18px var(--red-glow);
}
.feat h4{font-family:'Orbitron',sans-serif;font-size:15px;letter-spacing:.15em;color:#fff;text-transform:uppercase;margin-bottom:10px}
.feat p{font-size:14px;color:#a88;line-height:1.55}
/* ---------- SPECS TABLE ---------- */
.specs-wrap{display:grid;grid-template-columns:1fr 1fr;gap:40px}
@media(max-width:960px){.specs-wrap{grid-template-columns:1fr}}
table.specs{width:100%;border-collapse:collapse;font-size:14px}
table.specs th,table.specs td{
text-align:left;padding:14px 12px;border-bottom:1px solid var(--line);
vertical-align:top;
}
table.specs th{
font-family:'VT323',monospace;font-size:16px;color:var(--red-bright);
letter-spacing:.25em;text-transform:uppercase;width:42%;
}
table.specs td{color:#d0a8a8;font-family:'Share Tech Mono',monospace}
table.specs tr:hover td{color:#fff}
table.specs tr:hover th{text-shadow:0 0 12px var(--red-glow)}
/* ---------- GAMES ---------- */
.game-card{
background:#080304;border:1px solid var(--line);overflow:hidden;
display:flex;flex-direction:column;transition:all .3s;
}
.game-card:hover{border-color:var(--red-ink);transform:translateY(-6px);box-shadow:0 20px 40px rgba(255,16,51,.12)}
.game-thumb{
aspect-ratio:1/1;background:#030101;border-bottom:1px solid var(--line);
position:relative;overflow:hidden;
}
.game-thumb svg{width:100%;height:100%}
.game-thumb::after{
content:"";position:absolute;inset:0;pointer-events:none;
background:repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.35) 2px 3px);
}
.game-info{padding:18px;flex:1;display:flex;flex-direction:column}
.game-info .g-row{display:flex;justify-content:space-between;font-size:11px;letter-spacing:.25em;text-transform:uppercase;color:var(--red-bright);margin-bottom:10px}
.game-info h4{font-family:'Orbitron',sans-serif;color:#fff;font-size:16px;margin-bottom:6px;letter-spacing:.05em}
.game-info .genre{color:#866;font-size:12px;letter-spacing:.2em;text-transform:uppercase;margin-bottom:10px}
.game-info p{font-size:13px;color:#a88;line-height:1.55;flex:1}
.rarity{display:inline-flex;gap:3px;align-items:center}
.rarity i{width:8px;height:8px;background:var(--red-deep);display:inline-block}
.rarity i.on{background:var(--red-ink);box-shadow:0 0 6px var(--red-ink)}
/* ---------- WHY IT FAILED ---------- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:0;border:1px solid var(--line)}
@media(max-width:860px){.split{grid-template-columns:1fr}}
.split .half{padding:50px 44px;position:relative}
.split .half + .half{border-left:1px solid var(--line)}
@media(max-width:860px){.split .half + .half{border-left:none;border-top:1px solid var(--line)}}
.split .half.fail{background:linear-gradient(180deg, #0a0204, #050102)}
.split .half.matter{background:linear-gradient(180deg, #140406, #0a0204)}
.split h3{font-family:'Major Mono Display',monospace;font-size:40px;line-height:1;color:#fff;margin-bottom:22px;text-transform:lowercase}
.split h3 .r{color:var(--red-ink)}
.split ul{list-style:none}
.split li{padding:12px 0;border-top:1px dashed rgba(255,16,51,.2);font-size:15px;color:#c0a0a0;display:flex;gap:12px}
.split li::before{content:"//";color:var(--red-bright);font-family:'VT323',monospace;font-size:18px}
/* ---------- TIMELINE ---------- */
.timeline{position:relative;padding:30px 0}
.timeline::before{
content:"";position:absolute;top:0;bottom:0;left:50%;width:1px;
background:linear-gradient(180deg, transparent, var(--red-ink), var(--red-ink), transparent);
box-shadow:0 0 14px var(--red-glow);
}
.tl-item{display:grid;grid-template-columns:1fr 80px 1fr;gap:20px;margin-bottom:50px;align-items:center}
.tl-item:nth-child(odd) .tl-body{grid-column:1;text-align:right}
.tl-item:nth-child(even) .tl-body{grid-column:3}
.tl-item .tl-dot{grid-column:2;justify-self:center;width:16px;height:16px;border:1px solid var(--red-ink);background:#000;box-shadow:0 0 14px var(--red-glow);transform:rotate(45deg);position:relative;z-index:2}
.tl-year{font-family:'Major Mono Display',monospace;font-size:34px;color:var(--red-ink);margin-bottom:6px}
.tl-body h5{font-family:'Orbitron',sans-serif;color:#fff;font-size:15px;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px}
.tl-body p{font-size:14px;color:#a88;line-height:1.55}
@media(max-width:780px){
.timeline::before{left:20px}
.tl-item{grid-template-columns:40px 1fr;gap:18px}
.tl-item .tl-dot{grid-column:1;grid-row:1}
.tl-item .tl-body,.tl-item:nth-child(odd) .tl-body{grid-column:2;text-align:left}
}
/* ---------- FAUX VB DISPLAY ---------- */
.vb-stage{
aspect-ratio:16/9;max-width:1100px;margin:40px auto 0;
border:2px solid var(--red-deep);background:#000;position:relative;overflow:hidden;
box-shadow:0 0 60px rgba(255,16,51,.25), inset 0 0 80px rgba(255,16,51,.15);
}
.vb-stage canvas{width:100%;height:100%;display:block}
.vb-stage::before{
content:"";position:absolute;inset:0;pointer-events:none;z-index:3;
background:
repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.45) 2px 3px),
radial-gradient(ellipse at center, rgba(0,0,0,0) 40%, rgba(0,0,0,.7) 100%);
}
.vb-hud{
position:absolute;z-index:4;font-family:'VT323',monospace;font-size:16px;color:var(--red-bright);
letter-spacing:.25em;text-shadow:0 0 6px var(--red-ink);text-transform:uppercase;
}
.vb-hud.tl{top:12px;left:14px}
.vb-hud.tr{top:12px;right:14px}
.vb-hud.bl{bottom:12px;left:14px}
.vb-hud.br{bottom:12px;right:14px}
/* ---------- COLLECTOR MARKET ---------- */
.market{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
@media(max-width:960px){.market{grid-template-columns:1fr 1fr}}
@media(max-width:600px){.market{grid-template-columns:1fr}}
.lot{
background:#080304;border:1px solid var(--line);padding:24px;position:relative;
transition:all .3s;
}
.lot:hover{border-color:var(--red-ink);transform:translateY(-4px)}
.lot .lot-tag{
position:absolute;top:14px;right:14px;font-family:'VT323',monospace;font-size:12px;
color:var(--red-bright);letter-spacing:.3em;
}
.lot h4{font-family:'Orbitron',sans-serif;color:#fff;font-size:16px;letter-spacing:.08em;margin-bottom:14px;padding-right:60px}
.lot .meta{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px;margin-bottom:18px;font-size:12px}
.lot .meta span{color:#655;letter-spacing:.2em;text-transform:uppercase}
.lot .meta b{display:block;color:#d0a8a8;font-weight:normal;margin-top:2px;letter-spacing:.05em}
.lot .price{
font-family:'Major Mono Display',monospace;font-size:30px;color:var(--red-ink);
padding-top:16px;border-top:1px dashed var(--red-deep);text-shadow:0 0 12px var(--red-glow);
}
.lot .price small{font-size:11px;color:#866;letter-spacing:.3em;margin-left:8px}
/* ---------- COMPARISON ---------- */
.cmp-wrap{overflow-x:auto;border:1px solid var(--line)}
table.cmp{width:100%;min-width:900px;border-collapse:collapse;font-size:13px}
table.cmp th,table.cmp td{padding:14px 14px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
table.cmp thead th{
font-family:'VT323',monospace;font-size:15px;letter-spacing:.25em;text-transform:uppercase;
color:var(--red-bright);background:#0a0305;position:sticky;top:0;
}
table.cmp th.row{color:#d0a8a8;font-family:'Orbitron',sans-serif;font-size:12px;letter-spacing:.2em;text-transform:uppercase;width:140px}
table.cmp td{color:#b89090}
table.cmp tbody tr:hover td{color:#fff}
table.cmp td.vb{color:var(--red-bright);background:rgba(255,16,51,.04)}
/* ---------- QUOTES ---------- */
.quotes{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
@media(max-width:960px){.quotes{grid-template-columns:1fr}}
.quote{
padding:40px 30px;border:1px solid var(--line);background:linear-gradient(180deg,#0a0305,#040102);
position:relative;
}
.quote::before{
content:"“";position:absolute;top:-10px;left:16px;
font-family:'Major Mono Display',monospace;font-size:80px;color:var(--red-ink);line-height:1;
text-shadow:0 0 20px var(--red-glow);
}
.quote p{font-family:'Major Mono Display',monospace;font-size:18px;color:#fff;line-height:1.35;text-transform:lowercase;margin-bottom:18px}
.quote .who{font-family:'VT323',monospace;font-size:14px;color:var(--red-bright);letter-spacing:.3em;text-transform:uppercase}
/* ---------- FOOTER ---------- */
footer.site{
border-top:1px solid var(--line);padding:70px 0 40px;background:#040102;
position:relative;
}
.foot-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px;margin-bottom:50px}
@media(max-width:860px){.foot-grid{grid-template-columns:1fr 1fr}}
.foot-logo{font-family:'Major Mono Display',monospace;font-size:28px;color:#fff;margin-bottom:16px;text-transform:lowercase}
.foot-logo .r{color:var(--red-ink)}
.foot p{font-size:13px;color:#866;max-width:380px;line-height:1.6}
.foot h6{font-family:'VT323',monospace;font-size:14px;color:var(--red-bright);letter-spacing:.3em;text-transform:uppercase;margin-bottom:16px}
.foot ul{list-style:none}
.foot li{margin-bottom:10px}
.foot a{color:#b89090;font-size:13px;transition:color .2s}
.foot a:hover{color:var(--red-bright)}
.foot-bottom{
border-top:1px solid var(--line);padding-top:22px;
display:flex;justify-content:space-between;flex-wrap:wrap;gap:16px;
font-family:'VT323',monospace;font-size:13px;color:#544;letter-spacing:.2em;text-transform:uppercase;
}
/* ---------- REVEAL ---------- */
.reveal{opacity:0;transform:translateY(30px);transition:opacity .9s ease, transform .9s ease}
.reveal.in{opacity:1;transform:none}
/* ---------- MARQUEE ---------- */
.marquee{
border-top:1px solid var(--line);border-bottom:1px solid var(--line);
overflow:hidden;white-space:nowrap;padding:18px 0;background:#060203;
}
.marquee-inner{display:inline-block;animation:mq 40s linear infinite;font-family:'VT323',monospace;font-size:20px;color:var(--red-bright);letter-spacing:.3em}
.marquee-inner span{margin:0 36px;color:#fff}
.marquee-inner .d{color:var(--red-deep)}
@keyframes mq{from{transform:translateX(0)}to{transform:translateX(-50%)}}
</style>
</head>
<body>
<!-- ================= HEADER ================= -->
<header class="site">
<div class="nav">
<a href="#top" class="logo"><span class="dot"></span>virtual.boy / red.archive</a>
<nav>
<ul>
<li><a href="#story">Hardware</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#games">Library</a></li>
<li><a href="#simulate">Simulate</a></li>
<li><a href="#market">Market</a></li>
</ul>
</nav>
<a class="btn" href="#market">Enter Red Space →</a>
</div>
</header>
<!-- ================= HERO ================= -->
<section class="hero" id="top">
<canvas id="hero-canvas"></canvas>
<div class="hero-inner">
<div class="hero-meta">Est. 1995 · 32-Bit Stereoscopic · Tabletop VR</div>
<h1>virt<span class="r">u</span>al<span class="dim">/</span><span class="r">boy</span></h1>
<div class="sub">The Console That Promised A Third Dimension — And Delivered A Cult Object</div>
<p class="tagline">A <em>crimson</em> wireframe dream, suspended on a tabletop stand. Part headset, part prophecy, part glorious commercial failure. Welcome to the <em>red monochrome</em> archive.</p>
<div class="hero-ctas">
<a class="btn" href="#story">Explore the Hardware</a>
<a class="btn ghost" href="#simulate">Enter Red Space</a>
</div>
</div>
<div class="hero-footer">
<span>// SYS.01 · VUE-001 · POWER ON</span>
<div class="scroll-hint"><span>scroll</span><div class="line"></div></div>
<span class="blink">● REC</span>
</div>
</section>
<!-- ================= MARQUEE ================= -->
<div class="marquee">
<div class="marquee-inner">
<span>STEREOSCOPIC 3D</span><span class="d">//</span>
<span>RED MONOCHROME</span><span class="d">//</span>
<span>32-BIT NEC V810</span><span class="d">//</span>
<span>1995 · KYOTO</span><span class="d">//</span>
<span>22 TITLES RELEASED</span><span class="d">//</span>
<span>COLLECTOR GRADE</span><span class="d">//</span>
<span>STEREOSCOPIC 3D</span><span class="d">//</span>
<span>RED MONOCHROME</span><span class="d">//</span>
<span>32-BIT NEC V810</span><span class="d">//</span>
<span>1995 · KYOTO</span><span class="d">//</span>
<span>22 TITLES RELEASED</span><span class="d">//</span>
<span>COLLECTOR GRADE</span><span class="d">//</span>
</div>
</div>
<!-- ================= HARDWARE STORY ================= -->
<section id="story">
<div class="wrap">
<div class="story-grid reveal">
<div class="story">
<span class="eyebrow">Chapter 01 · The Experiment</span>
<h2 class="section-title">a bold, <span class="red">red</span> experiment in the shape of a console.</h2>
<p>In the summer of 1995, a tabletop headset arrived in stores with a promise no other home system could match: true stereoscopic 3D, rendered in 224 × 224 crimson pixels, delivered one eye at a time through oscillating mirrors and a pair of red LEDs. It was not handheld. It was not a home console. It was something stranger — a machine that asked you to lean forward, press your face to a visor, and look <em style="color:var(--red-bright);font-style:normal">into</em> a video game.</p>
<div class="pull">it was the console that <span class="r">tried</span> to invent the future — and arrived <span class="r">twenty years</span> too early.</div>
<p>Conceived by one of the industry's most revered hardware engineers, the system was a bet on immersion over resolution, on depth over color, on a vision of VR stripped down to its most essential form. What shipped was a peculiar artifact: a visor on a bipod, a twin-grip controller that anticipated modern analog sticks, and a library of games that used parallax and scaling to simulate worlds you could almost step into.</p>
<p>It failed commercially. It succeeded at becoming unforgettable.</p>
</div>
<div class="artifact">
<svg viewBox="0 0 300 400" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice">
<defs>
<radialGradient id="rg" cx="50%" cy="50%" r="60%">
<stop offset="0%" stop-color="#1a0306"/>
<stop offset="100%" stop-color="#000"/>
</radialGradient>
</defs>
<rect width="300" height="400" fill="url(#rg)"/>
<!-- grid -->
<g stroke="#550012" stroke-width=".5">
<line x1="0" y1="260" x2="300" y2="260"/>
<line x1="0" y1="300" x2="300" y2="300"/>
<line x1="0" y1="340" x2="300" y2="340"/>
<line x1="0" y1="380" x2="300" y2="380"/>
<line x1="0" y1="260" x2="150" y2="400"/>
<line x1="300" y1="260" x2="150" y2="400"/>
<line x1="60" y1="260" x2="150" y2="400"/>
<line x1="240" y1="260" x2="150" y2="400"/>
</g>
<!-- headset silhouette -->
<g fill="none" stroke="#ff1033" stroke-width="1.5">
<ellipse cx="110" cy="170" rx="45" ry="34"/>
<ellipse cx="190" cy="170" rx="45" ry="34"/>
<rect x="140" y="158" width="20" height="24"/>
<path d="M70 190 L70 210 L230 210 L230 190"/>
<!-- stand -->
<line x1="150" y1="210" x2="150" y2="290"/>
<path d="M110 310 L150 290 L190 310"/>
<ellipse cx="150" cy="315" rx="50" ry="6"/>
</g>
<!-- scanline flicker -->
<g stroke="#ff1033" stroke-width=".6" opacity=".5">
<line x1="0" y1="80" x2="300" y2="80"/>
<line x1="0" y1="120" x2="300" y2="120"/>
<line x1="0" y1="240" x2="300" y2="240"/>
</g>
<!-- data overlay -->
<text x="14" y="26" fill="#ff1033" font-family="monospace" font-size="10">VUE-001 / SPEC.04</text>
<text x="14" y="42" fill="#a30018" font-family="monospace" font-size="10">3D.STEREO · RED.LED</text>
<text x="14" y="386" fill="#ff1033" font-family="monospace" font-size="10">▲ TABLETOP UNIT — ARCHIVE REF</text>
</svg>
<div class="label">FILE 001 / TABLETOP VISOR</div>
</div>
</div>
</div>
</section>
<!-- ================= PRODUCT OVERVIEW ================= -->
<section id="hardware" style="padding-top:40px">
<div class="wrap">
<div class="reveal" style="margin-bottom:50px">
<span class="eyebrow">Chapter 02 · System Anatomy</span>
<h2 class="section-title">the <span class="red">hardware</span>, reintroduced.</h2>
<p class="lede">Six components that, together, form one of the most unusual consumer electronics designs ever mass-produced. Every piece reflects a different bet on what gaming might become.</p>
</div>
<div class="hw-grid">
<div class="hw reveal">
<div class="hw-num">01 / 06</div>
<div class="hw-icon">
<svg viewBox="0 0 120 80" width="100%" height="100%">
<g fill="none" stroke="#ff1033" stroke-width="1.3">
<ellipse cx="35" cy="40" rx="25" ry="18"/>
<ellipse cx="85" cy="40" rx="25" ry="18"/>
<rect x="55" y="33" width="10" height="14"/>
</g>
</svg>
</div>
<div>
<h4>The Visor</h4>
<p>Dual red LED displays, one per eye, with oscillating mirror scanning.</p>
</div>
</div>
<div class="hw reveal">
<div class="hw-num">02 / 06</div>
<div class="hw-icon">
<svg viewBox="0 0 120 80" width="100%" height="100%">
<g fill="none" stroke="#ff1033" stroke-width="1.3">
<line x1="60" y1="10" x2="60" y2="60"/>
<path d="M30 75 L60 60 L90 75"/>
<ellipse cx="60" cy="75" rx="35" ry="4"/>
</g>
</svg>
</div>
<div>
<h4>Bipod Stand</h4>
<p>Tabletop-mounted cradle with adjustable tilt and folding legs.</p>
</div>
</div>
<div class="hw reveal">
<div class="hw-num">03 / 06</div>
<div class="hw-icon">
<svg viewBox="0 0 120 80" width="100%" height="100%">
<g fill="none" stroke="#ff1033" stroke-width="1.3">
<rect x="20" y="25" width="80" height="34" rx="8"/>
<circle cx="35" cy="42" r="5"/>
<circle cx="85" cy="42" r="5"/>
<line x1="50" y1="32" x2="50" y2="52"/>
<line x1="70" y1="32" x2="70" y2="52"/>
</g>
</svg>
</div>
<div>
<h4>Dual-Grip Controller</h4>
<p>Twin D-pads, dual sticks, and shoulder buttons — a prototype of the modern pad.</p>
</div>
</div>
<div class="hw reveal">
<div class="hw-num">04 / 06</div>
<div class="hw-icon">
<svg viewBox="0 0 120 80" width="100%" height="100%">
<g fill="none" stroke="#ff1033" stroke-width="1.3">
<rect x="40" y="12" width="40" height="56" rx="2"/>
<rect x="48" y="20" width="24" height="16"/>
<line x1="46" y1="54" x2="74" y2="54"/>
<line x1="46" y1="60" x2="74" y2="60"/>
</g>
</svg>
</div>
<div>
<h4>Cartridges</h4>
<p>Slide-in ROM carts with up to 16MB of addressable storage per title.</p>
</div>
</div>
<div class="hw reveal">
<div class="hw-num">05 / 06</div>
<div class="hw-icon">
<svg viewBox="0 0 120 80" width="100%" height="100%">
<g fill="none" stroke="#ff1033" stroke-width="1.3">
<rect x="15" y="20" width="90" height="44"/>
<g stroke-width="0.8" opacity=".7">
<line x1="15" y1="30" x2="105" y2="30"/>
<line x1="15" y1="40" x2="105" y2="40"/>
<line x1="15" y1="50" x2="105" y2="50"/>
</g>
<circle cx="60" cy="42" r="4" fill="#ff1033"/>
</g>
</svg>
</div>
<div>
<h4>Red Monochrome Display</h4>
<p>224 × 224 per eye. Four shades of red. Pure, unapologetic monochrome.</p>
</div>
</div>
<div class="hw reveal">
<div class="hw-num">06 / 06</div>
<div class="hw-icon">
<svg viewBox="0 0 120 80" width="100%" height="100%">
<g fill="none" stroke="#ff1033" stroke-width="1.3">
<ellipse cx="35" cy="40" rx="22" ry="16"/>
<ellipse cx="85" cy="40" rx="22" ry="16"/>
<line x1="57" y1="40" x2="63" y2="40"/>
<line x1="25" y1="40" x2="45" y2="40" opacity=".5"/>
<line x1="75" y1="40" x2="95" y2="40" opacity=".5"/>
</g>
</svg>
</div>
<div>
<h4>Stereoscopic 3D</h4>
<p>True binocular depth, driven by offset sprite rendering between eyes.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ================= FEATURES ================= -->
<section id="features">
<div class="wrap">
<div class="reveal" style="margin-bottom:50px">
<span class="eyebrow">Chapter 03 · Specifications of the Strange</span>
<h2 class="section-title">eight reasons it was <span class="red">unlike</span> anything else.</h2>
</div>
<div class="grid-4">
<div class="feat reveal"><div class="idx">01</div><h4>Red Monochrome Display</h4><p>Two LED panels, 224×224 pixels each, rendering the world in four shades of crimson.</p></div>
<div class="feat reveal"><div class="idx">02</div><h4>Stereoscopic 3D Gameplay</h4><p>True binocular depth, not a red/blue trick — rendered frame-by-frame into each eye.</p></div>
<div class="feat reveal"><div class="idx">03</div><h4>Tabletop Headset Design</h4><p>A visor on a bipod. Not handheld. Not home. Something else entirely.</p></div>
<div class="feat reveal"><div class="idx">04</div><h4>Dual-Grip Controller</h4><p>Twin D-pads and shoulder triggers, a blueprint for the next two decades of pads.</p></div>
<div class="feat reveal"><div class="idx">05</div><h4>Cartridge-Based Games</h4><p>22 official titles on slide-in ROM carts, each a compact artifact of 90s ambition.</p></div>
<div class="feat reveal"><div class="idx">06</div><h4>Portable — Not Handheld</h4><p>Carried in a soft case, set on a desk, played leaning forward. A ritual, not a commute.</p></div>
<div class="feat reveal"><div class="idx">07</div><h4>Experimental '90s VR Concept</h4><p>Affordable virtual reality, two decades before the term became mainstream.</p></div>
<div class="feat reveal"><div class="idx">08</div><h4>Collector Rarity</h4><p>Short production run, cult following, and a market that has only grown more obsessive.</p></div>
</div>
</div>
</section>
<!-- ================= SPECS ================= -->
<section id="specs" style="padding-top:40px">
<div class="wrap">
<div class="reveal" style="margin-bottom:40px">
<span class="eyebrow">Chapter 04 · The Datasheet</span>
<h2 class="section-title">technical <span class="red">dossier</span>.</h2>
</div>
<div class="specs-wrap reveal">
<table class="specs">
<tr><th>System ID</th><td>VUE-001 / "Virtual Boy"</td></tr>
<tr><th>Manufacturer</th><td>Kyoto-based consumer electronics house, 1995</td></tr>
<tr><th>Processor</th><td>NEC V810 · 32-bit RISC · 20 MHz</td></tr>
<tr><th>Display Type</th><td>Dual red LED, 1×224 pixel line, mirrored scan</td></tr>
<tr><th>Resolution</th><td>384 × 224 effective (stereo combined)</td></tr>
<tr><th>Color Palette</th><td>4 shades of red (monochrome)</td></tr>
<tr><th>Refresh Rate</th><td>50.2 Hz per eye</td></tr>
<tr><th>Audio</th><td>Stereo 16-bit PCM, dual speakers</td></tr>
</table>
<table class="specs">
<tr><th>Controller</th><td>Twin-grip, 2 D-pads, 6 face buttons, 2 shoulders</td></tr>
<tr><th>Game Format</th><td>ROM cartridge, 8–16 MB</td></tr>
<tr><th>Power Source</th><td>6× AA batteries or AC adapter</td></tr>
<tr><th>Weight</th><td>~760 g (visor only)</td></tr>
<tr><th>Release Era</th><td>1995 · 5th generation</td></tr>
<tr><th>Visual Style</th><td>Red monochrome wireframe + sprite</td></tr>
<tr><th>Player Mode</th><td>Single player only</td></tr>
<tr><th>Collector Status</th><td>Cult · Rising · Archive-grade</td></tr>
</table>
</div>
</div>
</section>
<!-- ================= GAMES ================= -->
<section id="games">
<div class="wrap">
<div class="reveal" style="margin-bottom:50px">
<span class="eyebrow">Chapter 05 · The Library</span>
<h2 class="section-title">twenty-two <span class="red">cartridges</span>, twenty-two worlds.</h2>
<p class="lede">A small catalog with outsized influence. Each title pushed the red monochrome display to do things color consoles of the era could not attempt.</p>
</div>
<div class="grid-3">
<!-- Mario's Tennis -->
<div class="game-card reveal">
<div class="game-thumb">
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice">
<rect width="200" height="200" fill="#080203"/>
<g stroke="#ff1033" stroke-width="1.4" fill="none">
<path d="M0 140 Q100 100 200 140 L200 200 L0 200 Z"/>
<line x1="0" y1="150" x2="200" y2="150"/>
<line x1="0" y1="165" x2="200" y2="165"/>
<line x1="0" y1="185" x2="200" y2="185"/>
<line x1="100" y1="140" x2="100" y2="200"/>
<line x1="50" y1="145" x2="40" y2="200"/>
<line x1="150" y1="145" x2="160" y2="200"/>
</g>
<circle cx="120" cy="90" r="8" fill="#ff1033"/>
<rect x="85" y="100" width="20" height="30" fill="#ff1033"/>
<rect x="110" y="95" width="14" height="18" fill="none" stroke="#ff1033"/>
</svg>
</div>
<div class="game-info">
<div class="g-row"><span>VB-001</span><span>1995</span></div>
<h4>Mario's Tennis</h4>
<div class="genre">Sports · 1P/2P</div>
<p>Pack-in launch title. Stereoscopic court with depth-based ball tracking that still reads as elegant.</p>
<div class="rarity" title="Rarity: 3/5"><i class="on"></i><i class="on"></i><i class="on"></i><i></i><i></i></div>
</div>
</div>
<!-- Red Alarm -->
<div class="game-card reveal">
<div class="game-thumb">
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice">
<rect width="200" height="200" fill="#080203"/>
<g stroke="#ff1033" stroke-width="1" fill="none">
<polygon points="100,40 170,90 170,150 100,180 30,150 30,90"/>
<polygon points="100,60 150,95 150,140 100,160 50,140 50,95"/>
<polygon points="100,80 130,100 130,130 100,145 70,130 70,100"/>
<line x1="100" y1="40" x2="100" y2="80"/>
<line x1="30" y1="90" x2="70" y2="100"/>
<line x1="170" y1="90" x2="130" y2="100"/>
</g>
<circle cx="100" cy="112" r="4" fill="#ff1033"/>
</svg>
</div>
<div class="game-info">
<div class="g-row"><span>VB-004</span><span>1995</span></div>
<h4>Red Alarm</h4>
<div class="genre">Shooter · Wireframe 3D</div>
<p>A wireframe tunnel shooter that weaponized the display's parallax. Brutal, hypnotic, essential.</p>
<div class="rarity" title="Rarity: 4/5"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i></i></div>
</div>
</div>
<!-- Wario Land -->
<div class="game-card reveal">
<div class="game-thumb">
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice">
<rect width="200" height="200" fill="#080203"/>
<g fill="#ff1033">
<rect x="0" y="160" width="200" height="40"/>
<rect x="20" y="140" width="30" height="20"/>
<rect x="70" y="120" width="30" height="40"/>
<rect x="130" y="100" width="40" height="60"/>
<rect x="80" y="80" width="20" height="30"/>
<rect x="85" y="60" width="10" height="20"/>
<circle cx="90" cy="55" r="6"/>
</g>
<g stroke="#ff1033" stroke-width=".5" opacity=".4">
<line x1="0" y1="170" x2="200" y2="170"/>
<line x1="0" y1="180" x2="200" y2="180"/>
<line x1="0" y1="190" x2="200" y2="190"/>
</g>
</svg>
</div>
<div class="game-info">
<div class="g-row"><span>VB-009</span><span>1995</span></div>
<h4>Virtual Boy Wario Land</h4>
<div class="genre">Platformer · Puzzle</div>
<p>Widely considered the system's masterpiece. Layered foreground/background traversal uses depth as a mechanic.</p>
<div class="rarity" title="Rarity: 5/5"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i></div>
</div>
</div>
<!-- Teleroboxer -->
<div class="game-card reveal">
<div class="game-thumb">
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice">
<rect width="200" height="200" fill="#080203"/>
<g stroke="#ff1033" stroke-width="1.3" fill="none">
<rect x="70" y="60" width="60" height="70"/>
<rect x="80" y="75" width="12" height="12" fill="#ff1033"/>
<rect x="108" y="75" width="12" height="12" fill="#ff1033"/>
<line x1="85" y1="105" x2="115" y2="105"/>
<rect x="50" y="130" width="100" height="10"/>
<line x1="60" y1="140" x2="50" y2="180"/>
<line x1="140" y1="140" x2="150" y2="180"/>
<line x1="50" y1="60" x2="30" y2="100"/>
<line x1="150" y1="60" x2="170" y2="100"/>
</g>
</svg>
</div>
<div class="game-info">
<div class="g-row"><span>VB-002</span><span>1995</span></div>
<h4>Teleroboxer</h4>
<div class="genre">Fighting · Sports</div>
<p>Robotic boxing in first person. Leans hard into the display's stereoscopic pop and depth-punching impact.</p>
<div class="rarity" title="Rarity: 3/5"><i class="on"></i><i class="on"></i><i class="on"></i><i></i><i></i></div>
</div>
</div>
<!-- Galactic Pinball -->
<div class="game-card reveal">
<div class="game-thumb">
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice">
<rect width="200" height="200" fill="#080203"/>
<g stroke="#ff1033" stroke-width="1.2" fill="none">
<path d="M50 20 L150 20 L160 180 L40 180 Z"/>
<circle cx="80" cy="70" r="10"/>
<circle cx="120" cy="90" r="10"/>
<circle cx="100" cy="130" r="14"/>
<circle cx="60" cy="120" r="6" fill="#ff1033"/>
<line x1="60" y1="160" x2="80" y2="170"/>
<line x1="140" y1="160" x2="120" y2="170"/>
</g>
</svg>
</div>
<div class="game-info">
<div class="g-row"><span>VB-005</span><span>1995</span></div>
<h4>Galactic Pinball</h4>
<div class="genre">Pinball · Arcade</div>
<p>Four cosmic tables with genuine stereoscopic bumpers. One of the purest uses of the display's depth layering.</p>
<div class="rarity" title="Rarity: 4/5"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i></i></div>
</div>
</div>
<!-- Vertical Force -->
<div class="game-card reveal">
<div class="game-thumb">
<svg viewBox="0 0 200 200" preserveAspectRatio="xMidYMid slice">
<rect width="200" height="200" fill="#080203"/>
<g stroke="#ff1033" stroke-width="1" fill="none">
<polygon points="100,140 85,170 115,170"/>
<line x1="100" y1="140" x2="100" y2="30"/>
<g opacity=".8">
<rect x="92" y="110" width="16" height="4" fill="#ff1033"/>
<rect x="92" y="90" width="16" height="4" fill="#ff1033"/>
<rect x="92" y="70" width="16" height="4" fill="#ff1033"/>
<rect x="92" y="50" width="16" height="4" fill="#ff1033"/>
</g>
<circle cx="60" cy="60" r="8"/>
<circle cx="140" cy="80" r="10"/>
<circle cx="50" cy="120" r="6"/>
<circle cx="150" cy="130" r="7"/>
</g>
</svg>
</div>
<div class="game-info">
<div class="g-row"><span>VB-014</span><span>1995</span></div>
<h4>Vertical Force</h4>
<div class="genre">Shoot 'em up · Vertical</div>
<p>Layered foreground/background ships create a genuine sense of volumetric airspace. Rare and tightly designed.</p>
<div class="rarity" title="Rarity: 4/5"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i></i></div>
</div>
</div>
</div>
</div>
</section>
<!-- ================= WHY IT FAILED / MATTERS ================= -->
<section id="legacy">
<div class="wrap">
<div class="reveal" style="margin-bottom:40px">
<span class="eyebrow">Chapter 06 · The Reckoning</span>
<h2 class="section-title">why it failed. <span class="red">why it matters</span>.</h2>
</div>
<div class="split reveal">
<div class="half fail">
<h3>why it <span class="r">failed</span>.</h3>
<ul>
<li>Monochrome red was a hard sell in a market already moving to full color polygons.</li>
<li>The tabletop form factor was neither truly portable nor comfortably domestic.</li>
<li>Extended sessions caused eye strain and headaches for some players.</li>
<li>The launch library was thin; third-party support was almost nonexistent.</li>
<li>It arrived in the same window as far more conventional 32-bit consoles.</li>
<li>The marketing never quite explained what it was — because nothing like it had existed before.</li>
</ul>
</div>
<div class="half matter">
<h3>why it <span class="r">matters</span>.</h3>
<ul>
<li>It was the first consumer system to ship true stereoscopic 3D as a core feature.</li>
<li>Its controller anticipated dual analog sticks years before they became standard.</li>
<li>It represents a pure, uncompromised bet on a single idea — rare in consumer electronics.</li>
<li>The visual identity is instantly recognizable, haunting, and uniquely beautiful.</li>
<li>It proved that "failed" hardware can become the most fascinating hardware of all.</li>
<li>Two decades later, the industry finally built the VR market this console tried to invent.</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ================= TIMELINE ================= -->
<section id="timeline">
<div class="wrap">
<div class="reveal" style="margin-bottom:40px;text-align:center">
<span class="eyebrow">Chapter 07 · The Chronicle</span>
<h2 class="section-title">a <span class="red">brief</span>, intense life.</h2>
</div>
<div class="timeline">
<div class="tl-item reveal">
<div class="tl-body">
<div class="tl-year">1991</div>
<h5>Concept Initiated</h5>
<p>A veteran hardware designer begins exploring a "portable 3D" concept based on oscillating mirror scanning and red LEDs — cheaper and sharper than LCD alternatives of the time.</p>
</div>
<div class="tl-dot"></div>
<div></div>
</div>
<div class="tl-item reveal">
<div></div>
<div class="tl-dot"></div>
<div class="tl-body">
<div class="tl-year">1994</div>
<h5>Public Prototype</h5>
<p>A working prototype is demonstrated at a major Japanese trade show. Industry press reacts with fascination and uncertainty — it looks like nothing else in the room.</p>
</div>
</div>
<div class="tl-item reveal">
<div class="tl-body">
<div class="tl-year">JUL 1995</div>
<h5>Japan Launch</h5>
<p>The system goes on sale in Japan with a small launch lineup. First-week sales are respectable; long-term demand drops sharply as word of eye strain spreads.</p>
</div>
<div class="tl-dot"></div>
<div></div>
</div>
<div class="tl-item reveal">
<div></div>
<div class="tl-dot"></div>
<div class="tl-body">
<div class="tl-year">AUG 1995</div>
<h5>North American Launch</h5>
<p>Bundled with a tennis title and a sci-fi shooter. Positioned as a bold new category. Positioned, ultimately, against the wrong competitors.</p>
</div>
</div>
<div class="tl-item reveal">
<div class="tl-body">
<div class="tl-year">1996</div>
<h5>Quiet Discontinuation</h5>
<p>Production is halted without a formal announcement. Fewer than 800,000 units have shipped worldwide. The library ends at 22 titles.</p>
</div>
<div class="tl-dot"></div>
<div></div>
</div>
<div class="tl-item reveal">
<div></div>
<div class="tl-dot"></div>
<div class="tl-body">
<div class="tl-year">2001–2010</div>
<h5>Cult Object</h5>
<p>A dedicated retro-collecting community begins to document, preserve, and mythologize the hardware. Prices for complete-in-box units begin to climb.</p>
</div>
</div>
<div class="tl-item reveal">
<div class="tl-body">
<div class="tl-year">2016+</div>
<h5>Modern VR Arrives</h5>
<p>Consumer VR headsets finally reach mass market. Historians note: the ideas were all here, twenty years earlier, in red and black.</p>
</div>
<div class="tl-dot"></div>
<div></div>
</div>
<div class="tl-item reveal">
<div></div>
<div class="tl-dot"></div>
<div class="tl-body">
<div class="tl-year">TODAY</div>
<h5>Collector Rediscovery</h5>
<p>Sealed copies of launch titles trade for four figures. The hardware is exhibited in design museums. A failed console becomes an archive piece.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ================= VISUAL EXPERIENCE ================= -->
<section id="simulate">
<div class="wrap">
<div class="reveal" style="text-align:center;margin-bottom:30px">
<span class="eyebrow">Chapter 08 · The Simulation</span>
<h2 class="section-title">look <span class="red">into</span> the visor.</h2>
<p class="lede" style="margin:18px auto 0">A faithful simulation of the display's visual language — wireframe terrain, parallax sprites, scanline sweep, and four shades of crimson. Move your mouse to steer the horizon.</p>
</div>
<div class="vb-stage reveal">
<canvas id="vb-canvas"></canvas>
<div class="vb-hud tl">VB-SIM · v1.0</div>
<div class="vb-hud tr">PWR 87% ● STEREO</div>
<div class="vb-hud bl">FRM 60 · DEPTH +04</div>
<div class="vb-hud br">REC ◆ <span class="blink">LIVE</span></div>
</div>
</div>
</section>
<!-- ================= COLLECTOR MARKET ================= -->
<section id="market">
<div class="wrap">
<div class="reveal" style="margin-bottom:50px">
<span class="eyebrow">Chapter 09 · The Market</span>
<h2 class="section-title">the <span class="red">collector</span> floor.</h2>
<p class="lede">Representative lots from the current secondary market. Prices are illustrative of the collector-grade tier and reflect completeness, condition, and provenance.</p>
</div>
<div class="market">
<div class="lot reveal">
<div class="lot-tag">LOT 001</div>
<h4>Loose Console Unit</h4>
<div class="meta">
<div><span>Condition</span><b>Tested · Yellowed</b></div>
<div><span>Completeness</span><b>Visor + Stand</b></div>
<div><span>Rarity</span><b>Common</b></div>
<div><span>Notes</span><b>Controller sold separate</b></div>
</div>
<div class="price">$180 <small>USD</small></div>
</div>
<div class="lot reveal">
<div class="lot-tag">LOT 002</div>
<h4>Complete In Box</h4>
<div class="meta">
<div><span>Condition</span><b>Near Mint</b></div>
<div><span>Completeness</span><b>All Inserts · Styro</b></div>
<div><span>Rarity</span><b>Scarce</b></div>
<div><span>Notes</span><b>Pack-in cart included</b></div>
</div>
<div class="price">$650 <small>USD</small></div>
</div>
<div class="lot reveal">
<div class="lot-tag">LOT 003</div>
<h4>Factory Sealed Game</h4>
<div class="meta">
<div><span>Condition</span><b>VGA-Ready</b></div>
<div><span>Completeness</span><b>Sealed · Y-Fold</b></div>
<div><span>Rarity</span><b>Rare</b></div>
<div><span>Notes</span><b>First-party title</b></div>
</div>
<div class="price">$1,400 <small>USD</small></div>
</div>
<div class="lot reveal">
<div class="lot-tag">LOT 004</div>
<h4>Controller Only</h4>
<div class="meta">
<div><span>Condition</span><b>Excellent</b></div>
<div><span>Completeness</span><b>Controller · Caps</b></div>
<div><span>Rarity</span><b>Uncommon</b></div>
<div><span>Notes</span><b>Tested · Responsive</b></div>
</div>
<div class="price">$95 <small>USD</small></div>
</div>
<div class="lot reveal">
<div class="lot-tag">LOT 005</div>
<h4>Full Collector Bundle</h4>
<div class="meta">
<div><span>Condition</span><b>Archive Grade</b></div>
<div><span>Completeness</span><b>CIB + 6 Games</b></div>
<div><span>Rarity</span><b>Very Rare</b></div>
<div><span>Notes</span><b>Documented provenance</b></div>
</div>
<div class="price">$3,200 <small>USD</small></div>
</div>
<div class="lot reveal">
<div class="lot-tag">LOT 006</div>
<h4>Japanese Import — Mint</h4>
<div class="meta">
<div><span>Condition</span><b>Mint · Tested</b></div>
<div><span>Completeness</span><b>OBI · Manual</b></div>
<div><span>Rarity</span><b>Scarce</b></div>
<div><span>Notes</span><b>Low serial · 1995</b></div>
</div>
<div class="price">$820 <small>USD</small></div>
</div>
</div>
</div>
</section>
<!-- ================= COMPARISON ================= -->
<section id="compare">
<div class="wrap">
<div class="reveal" style="margin-bottom:40px">
<span class="eyebrow">Chapter 10 · Context</span>
<h2 class="section-title">where it <span class="red">fits</span> in the hardware tree.</h2>
</div>
<div class="cmp-wrap reveal">
<table class="cmp">
<thead>
<tr>
<th class="row">Axis</th>
<th>Handheld Consoles</th>
<th>Home Consoles</th>
<th>Arcade Cabinets</th>
<th>Modern VR Headsets</th>
<th class="vb">Virtual Boy</th>
</tr>
</thead>
<tbody>
<tr><th class="row">Era</th><td>1989–Present</td><td>1977–Present</td><td>1972–Present</td><td>2016–Present</td><td class="vb">1995 only</td></tr>
<tr><th class="row">Display</th><td>LCD, Color</td><td>CRT → HDMI</td><td>CRT / LCD</td><td>OLED / LCD, stereo</td><td class="vb">Red LED monochrome</td></tr>
<tr><th class="row">Portability</th><td>High</td><td>None</td><td>None</td><td>Medium</td><td class="vb">Low (tabletop only)</td></tr>
<tr><th class="row">3D Support</th><td>Rare</td><td>Rare</td><td>Occasional</td><td>Native</td><td class="vb">Native · Stereoscopic</td></tr>
<tr><th class="row">Comfort</th><td>High</td><td>High</td><td>Medium</td><td>Variable</td><td class="vb">Low · Eye strain noted</td></tr>
<tr><th class="row">Game Library</th><td>Hundreds</td><td>Thousands</td><td>Thousands</td><td>Hundreds</td><td class="vb">22 titles</td></tr>
<tr><th class="row">Legacy</th><td>Defining</td><td>Defining</td><td>Defining</td><td>Emerging</td><td class="vb">Cult · Prophetic</td></tr>
<tr><th class="row">Collector Appeal</th><td>Medium</td><td>High</td><td>High</td><td>Low</td><td class="vb">Very High</td></tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- ================= QUOTES ================= -->
<section id="quotes" style="padding-top:40px">
<div class="wrap">
<div class="reveal" style="margin-bottom:40px;text-align:center">
<span class="eyebrow">Chapter 11 · The Record</span>
<h2 class="section-title">voices from the <span class="red">red</span> archive.</h2>
</div>
<div class="quotes">
<div class="quote reveal">
<p>it was not a product. it was a <span style="color:var(--red-ink)">thesis</span> about where games were going.</p>
<div class="who">— Hardware Historian, Kyoto</div>
</div>
<div class="quote reveal">
<p>i remember pressing my face to the visor and thinking: this is what <span style="color:var(--red-ink)">tomorrow</span> looks like. it was.</p>
<div class="who">— Retail Buyer, 1995</div>
</div>
<div class="quote reveal">
<p>twenty-two games. eight hundred thousand units. one of the most <span style="color:var(--red-ink)">important</span> consoles ever made.</p>
<div class="who">— Archive Curator</div>
</div>
</div>
</div>
</section>
<!-- ================= FOOTER ================= -->
<footer class="site">
<div class="wrap">
<div class="foot-grid">
<div class="foot">
<div class="foot-logo">virtual<span class="r">/</span>boy · red.archive</div>
<p>A retro technology microsite dedicated to one of the strangest, most ambitious, and most fascinating pieces of consumer gaming hardware ever released. An editorial archive, not an official product page.</p>
</div>
<div class="foot">
<h6>Archive</h6>
<ul>
<li><a href="#story">Hardware Story</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#specs">Datasheet</a></li>
<li><a href="#games">Library</a></li>
</ul>
</div>
<div class="foot">
<h6>Collector</h6>
<ul>
<li><a href="#market">Market Lots</a></li>
<li><a href="#compare">Compare Hardware</a></li>
<li><a href="#timeline">Timeline</a></li>
<li><a href="#">Museum Loan (fictional)</a></li>
</ul>
</div>
<div class="foot">
<h6>Resources</h6>
<ul>
<li><a href="#">Retro Archive (fictional)</a></li>
<li><a href="#">Preservation Project</a></li>
<li><a href="#">Newsletter</a></li>
<li><a href="#">Social Feed</a></li>
</ul>
</div>
</div>
<div class="foot-bottom">
<span>© Red Archive · Editorial Project · Not Affiliated With Any Manufacturer</span>
<span>SYS.01 · 60HZ · STEREO · v2.4</span>
</div>
</div>
</footer>
<!-- ================= THREE.JS ================= -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
/* ============================================================
HERO · THREE.JS WIREFRAME SCENE
============================================================ */
(function(){
const canvas = document.getElementById('hero-canvas');
if(!canvas || typeof THREE === 'undefined') return;
const scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x000000, 0.045);
const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 400);
camera.position.set(0, 0.4, 7);
const renderer = new THREE.WebGLRenderer({canvas, antialias:true, alpha:true});
renderer.setPixelRatio(Math.min(window.devicePixelRatio,2));
function resize(){
const w = canvas.clientWidth = canvas.parentElement.clientWidth;
const h = canvas.clientHeight = canvas.parentElement.clientHeight;
renderer.setSize(w, h, false);
camera.aspect = w/h;
camera.updateProjectionMatrix();
}
resize();
window.addEventListener('resize', resize);
/* ----- Materials ----- */
const wire = new THREE.MeshBasicMaterial({color:0xff1033, wireframe:true, transparent:true, opacity:.9});
const wireDim = new THREE.MeshBasicMaterial({color:0x880012, wireframe:true, transparent:true, opacity:.55});
const wireGhost = new THREE.MeshBasicMaterial({color:0x3a0008, wireframe:true, transparent:true, opacity:.35});
/* ----- Headset ----- */
const headset = new THREE.Group();
// lenses
const lensGeo = new THREE.TorusGeometry(0.85, 0.32, 10, 28);
const lensL = new THREE.Mesh(lensGeo, wire);
const lensR = new THREE.Mesh(lensGeo, wire);
lensL.position.x = -0.95;
lensR.position.x = 0.95;
lensL.rotation.y = Math.PI/2;
lensR.rotation.y = Math.PI/2;
// inner pupil rings
const pupilGeo = new THREE.RingGeometry(0.28, 0.38, 24);
const pupilL = new THREE.Mesh(pupilGeo, new THREE.MeshBasicMaterial({color:0xff1033, side:THREE.DoubleSide, transparent:true, opacity:.85}));
const pupilR = pupilL.clone();
pupilL.position.set(-0.95, 0, 0.32);
pupilR.position.set(0.95, 0, 0.32);
// bridge
const bridge = new THREE.Mesh(new THREE.BoxGeometry(0.55, 0.5, 0.5, 3, 3, 3), wire);
// visor shell
const shell = new THREE.Mesh(new THREE.BoxGeometry(2.7, 1.4, 1.05, 6, 4, 3), wireDim);
shell.position.z = -0.1;
// back plate
const back = new THREE.Mesh(new THREE.BoxGeometry(2.3, 1.1, 0.2, 4, 3, 1), wireGhost);
back.position.z = -0.75;
// cartridge slot
const cart = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.25, 0.35, 2, 1, 1), wireDim);
cart.position.set(0, 0.85, -0.2);
headset.add(lensL, lensR, pupilL, pupilR, bridge, shell, back, cart);
headset.position.y = 0.8;
scene.add(headset);
/* ----- Stand ----- */
const stand = new THREE.Group();
const pole = new THREE.Mesh(new THREE.CylinderGeometry(0.07, 0.09, 2.1, 8), wire);
pole.position.y = -1.05;
const neck = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.08, 0.3, 8), wireDim);
neck.position.y = 0.05;
const baseL = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.8, 0.6, 1, 3, 2), wire);
baseL.position.set(-0.6, -2.5, 0); baseL.rotation.z = 0.35;
const baseR = baseL.clone(); baseR.position.x = 0.6; baseR.rotation.z = -0.35;
const foot = new THREE.Mesh(new THREE.TorusGeometry(1.2, 0.05, 6, 24), wireDim);
foot.rotation.x = Math.PI/2; foot.position.y = -2.85;
stand.add(pole, neck, baseL, baseR, foot);
scene.add(stand);
/* ----- Floor Grid ----- */
const grid = new THREE.GridHelper(80, 40, 0xff1033, 0x550010);
grid.position.y = -3;
grid.material.transparent = true;
grid.material.opacity = 0.55;
scene.add(grid);
// second receding grid (perspective horizon)
const grid2 = new THREE.GridHelper(200, 60, 0x990018, 0x2a0006);
grid2.position.y = -3.02;
grid2.material.transparent = true;
grid2.material.opacity = 0.25;
scene.add(grid2);
/* ----- Floating Cartridges ----- */
const floaters = new THREE.Group();
const cartGeo = new THREE.BoxGeometry(0.6, 0.9, 0.12, 2, 3, 1);
for(let i=0;i<14;i++){
const c = new THREE.Mesh(cartGeo, (i%3===0)?wire:wireDim);
const a = (i/14) * Math.PI * 2;
const r = 5 + Math.random()*3;
c.position.set(Math.cos(a)*r, (Math.random()-.5)*4, Math.sin(a)*r - 2);
c.rotation.set(Math.random()*Math.PI, Math.random()*Math.PI, Math.random()*Math.PI);
c.userData = {a, r, s:0.15 + Math.random()*0.3, y0:c.position.y};
floaters.add(c);
}
scene.add(floaters);
/* ----- Particles ----- */
const pCount = 600;
const pGeo = new THREE.BufferGeometry();
const pos = new Float32Array(pCount*3);
for(let i=0;i<pCount;i++){
pos[i*3] = (Math.random()-.5)*80;
pos[i*3+1] = (Math.random()-.5)*40;
pos[i*3+2] = (Math.random()-.5)*80;
}
pGeo.setAttribute('position', new THREE.BufferAttribute(pos,3));
const pMat = new THREE.PointsMaterial({color:0xff1033, size:0.06, transparent:true, opacity:.8, sizeAttenuation:true});
const particles = new THREE.Points(pGeo, pMat);
scene.add(particles);
/* ----- Distant mountains (wireframe) ----- */
const mtGeo = new THREE.ConeGeometry(4, 6, 4);
for(let i=0;i<10;i++){
const m = new THREE.Mesh(mtGeo, wireGhost);
const ang = (i/10)*Math.PI*2;
m.position.set(Math.cos(ang)*28, -3 + Math.random()*0.5, Math.sin(ang)*28 - 10);
m.scale.set(0.6+Math.random()*0.9, 0.6+Math.random()*1.2, 0.6+Math.random()*0.9);
scene.add(m);
}
/* ----- Mouse Parallax ----- */
const mouse = {x:0, y:0, tx:0, ty:0};
window.addEventListener('mousemove', (e)=>{
mouse.tx = (e.clientX / window.innerWidth - 0.5) * 2;
mouse.ty = (e.clientY / window.innerHeight - 0.5) * 2;
});
window.addEventListener('touchmove', (e)=>{
if(!e.touches[0]) return;
mouse.tx = (e.touches[0].clientX / window.innerWidth - 0.5) * 2;
mouse.ty = (e.touches[0].clientY / window.innerHeight - 0.5) * 2;
}, {passive:true});
/* ----- Animate ----- */
const clock = new THREE.Clock();
function tick(){
const t = clock.getElapsedTime();
// smooth mouse
mouse.x += (mouse.tx - mouse.x) * 0.05;
mouse.y += (mouse.ty - mouse.y) * 0.05;
// camera
camera.position.x = mouse.x * 1.4;
camera.position.y = 0.4 - mouse.y * 0.6;
camera.lookAt(0, 0.2, 0);
// headset
headset.rotation.y = Math.sin(t*0.3) * 0.25 + mouse.x * 0.35;
headset.rotation.x = Math.sin(t*0.25) * 0.05 - mouse.y * 0.15;
headset.position.y = 0.8 + Math.sin(t*0.8)*0.15;
// pupils pulsing
const pScale = 1 + Math.sin(t*3)*0.08;
pupilL.scale.set(pScale,pScale,1);
pupilR.scale.set(pScale,pScale,1);
// floaters orbit
floaters.children.forEach((c,i)=>{
const u = c.userData;
const a = u.a + t * u.s * 0.15;
c.position.x = Math.cos(a) * u.r;
c.position.z = Math.sin(a) * u.r - 2;
c.position.y = u.y0 + Math.sin(t*u.s + i)*0.4;
c.rotation.x += 0.005;
c.rotation.y += 0.008;
});
// particles slow drift
particles.rotation.y = t * 0.02;
particles.rotation.x = t * 0.01;
// grid scroll (fake motion)
grid.position.z = (t*1.2) % 2;
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
tick();
})();
/* ============================================================
FAUX VB DISPLAY · CANVAS
============================================================ */
(function(){
const canvas = document.getElementById('vb-canvas');
if(!canvas) return;
const ctx = canvas.getContext('2d');
let W=0,H=0;
function size(){
const r = canvas.getBoundingClientRect();
W = canvas.width = Math.floor(r.width * (window.devicePixelRatio>1?1.2:1));
H = canvas.height = Math.floor(r.height * (window.devicePixelRatio>1?1.2:1));
}
size();
window.addEventListener('resize', size);
const mouse = {x:0.5};
canvas.parentElement.addEventListener('mousemove',(e)=>{
const r = canvas.parentElement.getBoundingClientRect();
mouse.x = (e.clientX - r.left) / r.width;
});
// stars
const stars = [];
for(let i=0;i<60;i++){
stars.push({x:Math.random(), y:Math.random()*0.55, s:Math.random()*1.5+0.3});
}
// ships
const ships = [];
for(let i=0;i<5;i++){
ships.push({x:Math.random(), y:0.2+Math.random()*0.4, z:Math.random(), v:0.0008+Math.random()*0.001, a:Math.random()*Math.PI*2});
}
function draw(t){
// background
const grd = ctx.createLinearGradient(0,0,0,H);
grd.addColorStop(0,'#18020a');
grd.addColorStop(0.55,'#060103');
grd.addColorStop(0.55,'#0a0206');
grd.addColorStop(1,'#000');
ctx.fillStyle = grd;
ctx.fillRect(0,0,W,H);
// horizon line
const horizon = H*0.55;
ctx.strokeStyle = '#ff1033';
ctx.lineWidth = 1.2;
ctx.beginPath();
ctx.moveTo(0,horizon); ctx.lineTo(W,horizon); ctx.stroke();
// sun
const sunX = W*(0.3 + mouse.x*0.4);
const sunY = horizon - 20;
const sunR = Math.min(W,H)*0.18;
ctx.save();
ctx.beginPath();
ctx.arc(sunX, sunY, sunR, Math.PI, 0);
ctx.closePath();
ctx.fillStyle = '#ff1033';
ctx.shadowColor = '#ff1033';
ctx.shadowBlur = 40;
ctx.fill();
ctx.restore();
// sun stripes
ctx.fillStyle = '#060103';
for(let i=1;i<=5;i++){
const y = sunY - sunR + (i/6)*sunR;
ctx.fillRect(sunX-sunR, y, sunR*2, 2 + i*0.6);
}
// stars
ctx.fillStyle = '#ff1033';
for(const s of stars){
const tw = Math.sin(t*0.002 + s.x*20)*0.5+0.5;
ctx.globalAlpha = 0.4 + tw*0.6;
ctx.fillRect(s.x*W, s.y*H, s.s, s.s);
}
ctx.globalAlpha = 1;
// mountains (distant)
ctx.strokeStyle = '#a30018';
ctx.lineWidth = 1;
ctx.beginPath();
const offA = t*0.02;
for(let x=0;x<=W;x+=4){
const y = horizon - 20 - Math.abs(Math.sin((x+offA)*0.02))*40 - Math.abs(Math.sin((x+offA)*0.05))*18;
if(x===0) ctx.moveTo(x,y); else ctx.lineTo(x,y);
}
ctx.stroke();
ctx.strokeStyle = '#ff1033';
ctx.beginPath();
const offB = t*0.04;
for(let x=0;x<=W;x+=3){
const y = horizon - 10 - Math.abs(Math.sin((x+offB)*0.03))*28 - Math.abs(Math.cos((x+offB)*0.07))*14;
if(x===0) ctx.moveTo(x,y); else ctx.lineTo(x,y);
}
ctx.stroke();
// perspective grid (floor)
ctx.strokeStyle = '#ff1033';
ctx.lineWidth = 1;
// vertical (converging)
const vanishX = sunX;
const lines = 18;
for(let i=-lines;i<=lines;i++){
const bx = W/2 + i * (W/lines) * 1.5;
ctx.globalAlpha = 1 - Math.min(1, Math.abs(i)/lines*0.8);
ctx.beginPath();
ctx.moveTo(vanishX, horizon);
ctx.lineTo(bx, H);
ctx.stroke();
}
ctx.globalAlpha = 1;
// horizontal depth lines (scrolling)
const depthLines = 18;
const scroll = (t*0.0015) % 1;
for(let i=0;i<depthLines;i++){
let p = (i/depthLines + scroll);
if(p>1) p -= 1;
// exponential distribution: closer lines are denser
const pp = Math.pow(p, 2.4);
const y = horizon + pp * (H - horizon);
ctx.globalAlpha = 0.25 + pp*0.75;
ctx.beginPath();
ctx.moveTo(0,y); ctx.lineTo(W,y); ctx.stroke();
}
ctx.globalAlpha = 1;
// ships
for(const s of ships){
s.x += Math.cos(s.a) * s.v;
if(s.x>1.2) s.x = -0.2;
if(s.x<-0.2) s.x = 1.2;
const size = 6 + s.z*14;
const sx = s.x*W;
const sy = horizon*0.4 + s.y*(horizon*0.5) + Math.sin(t*0.003 + s.z*10)*4;
ctx.strokeStyle = '#ff1033';
ctx.fillStyle = '#ff1033';
ctx.lineWidth = 1.2;
ctx.beginPath();
ctx.moveTo(sx, sy-size);
ctx.lineTo(sx+size, sy+size*0.6);
ctx.lineTo(sx, sy+size*0.3);
ctx.lineTo(sx-size, sy+size*0.6);
ctx.closePath();
ctx.stroke();
// trail
ctx.globalAlpha = 0.4;
ctx.beginPath();
ctx.moveTo(sx, sy+size*0.3);
ctx.lineTo(sx, sy+size*2);
ctx.stroke();
ctx.globalAlpha = 1;
}
// HUD crosshair
const cx = W/2 + (mouse.x-0.5)*W*0.3;
const cy = H*0.5;
ctx.strokeStyle = '#ff1033';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(cx, cy, 14, 0, Math.PI*2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(cx-22,cy); ctx.lineTo(cx-8,cy);
ctx.moveTo(cx+8,cy); ctx.lineTo(cx+22,cy);
ctx.moveTo(cx,cy-22); ctx.lineTo(cx,cy-8);
ctx.moveTo(cx,cy+8); ctx.lineTo(cx,cy+22);
ctx.stroke();
// flicker overlay
if(Math.random()<0.03){
ctx.fillStyle = 'rgba(255,16,51,0.06)';
ctx.fillRect(0,0,W,H);
}
}
function loop(t){
draw(t||0);
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
})();
/* ============================================================
SCROLL REVEAL
============================================================ */
(function(){
const els = document.querySelectorAll('.reveal');
if(!('IntersectionObserver' in window)){
els.forEach(e=>e.classList.add('in')); return;
}
const io = new IntersectionObserver((entries)=>{
entries.forEach(en=>{
if(en.isIntersecting){
en.target.classList.add('in');
io.unobserve(en.target);
}
});
},{threshold:0.12, rootMargin:'0px 0px -60px 0px'});
els.forEach(e=>io.observe(e));
})();
/* ============================================================
SMOOTH HEADER SHADOW ON SCROLL
============================================================ */
(function(){
const h = document.querySelector('header.site');
window.addEventListener('scroll',()=>{
if(window.scrollY>40) h.style.boxShadow = '0 8px 30px rgba(255,16,51,.1)';
else h.style.boxShadow = 'none';
});
})();
</script>
</body>
</html>
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nintendo Virtual Boy — The Red Horizon</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&family=Inter:wght@300;400;600;700&display=swap');
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--red-primary: #ff0000;
--red-bright: #ff1a1a;
--red-deep: #cc0000;
--red-dark: #8b0000;
--red-glow: rgba(255, 0, 0, 0.4);
--red-subtle: rgba(255, 0, 0, 0.08);
--black: #000000;
--black-light: #0a0a0a;
--gray-dark: #111111;
--gray-mid: #1a1a1a;
--gray: #2a2a2a;
--gray-light: #444444;
--text: #e0e0e0;
--text-dim: #888888;
}
html { scroll-behavior: smooth; }
body {
background: var(--black);
color: var(--text);
font-family: 'Inter', sans-serif;
overflow-x: hidden;
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0,0,0,0.15) 2px,
rgba(0,0,0,0.15) 4px
);
pointer-events: none;
z-index: 10000;
}
body::after {
content: '';
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.5) 100%);
pointer-events: none;
z-index: 9999;
}
::selection { background: var(--red-primary); color: var(--black); }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--black); }
::-webkit-scrollbar-thumb { background: var(--red-dark); border-radius: 3px; }
a { color: var(--red-primary); text-decoration: none; transition: all 0.3s; }
a:hover { color: var(--red-bright); text-shadow: 0 0 10px var(--red-glow); }
.section-label {
font-family: 'Share Tech Mono', monospace;
font-size: 0.75rem;
letter-spacing: 4px;
text-transform: uppercase;
color: var(--red-primary);
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.section-label::before {
content: '';
display: inline-block;
width: 30px;
height: 1px;
background: var(--red-primary);
}
.section-title {
font-family: 'Orbitron', sans-serif;
font-size: clamp(1.8rem, 4vw, 3rem);
font-weight: 900;
color: #fff;
margin-bottom: 1.5rem;
letter-spacing: 1px;
line-height: 1.2;
}
.section-title .red { color: var(--red-primary); }
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
/* NAV */
nav {
position: fixed;
top: 0; left: 0; right: 0;
z-index: 9000;
padding: 1rem 2rem;
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(0,0,0,0.85);
backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255,0,0,0.15);
transition: all 0.4s;
}
nav.scrolled { padding: 0.6rem 2rem; background: rgba(0,0,0,0.95); }
.nav-logo {
font-family: 'Orbitron', sans-serif;
font-weight: 900;
font-size: 1.1rem;
color: #fff;
letter-spacing: 2px;
display: flex;
align-items: center;
gap: 0.5rem;
}
.nav-logo .nintendo { color: var(--text-dim); font-weight: 400; font-size: 0.8rem; margin-right: 0.5rem; }
.nav-logo .vb { color: var(--red-primary); text-shadow: 0 0 20px var(--red-glow); }
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
align-items: center;
}
.nav-links a {
font-family: 'Share Tech Mono', monospace;
font-size: 0.75rem;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--text-dim);
transition: all 0.3s;
}
.nav-links a:hover { color: var(--red-primary); }
.nav-cta {
font-family: 'Share Tech Mono', monospace;
font-size: 0.7rem;
letter-spacing: 2px;
text-transform: uppercase;
padding: 0.5rem 1.2rem;
border: 1px solid var(--red-primary);
color: var(--red-primary) !important;
transition: all 0.3s;
}
.nav-cta:hover {
background: var(--red-primary);
color: var(--black) !important;
box-shadow: 0 0 20px var(--red-glow);
}
/* HERO */
#hero {
position: relative;
height: 100vh;
min-height: 700px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
#hero-canvas {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: 1;
}
.hero-overlay {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: linear-gradient(180deg, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.6) 60%, var(--black) 100%);
z-index: 2;
}
.hero-content {
position: relative;
z-index: 3;
text-align: center;
max-width: 800px;
padding: 0 2rem;
}
.hero-badge {
font-family: 'Share Tech Mono', monospace;
font-size: 0.7rem;
letter-spacing: 6px;
text-transform: uppercase;
color: var(--red-primary);
margin-bottom: 1.5rem;
display: inline-flex;
align-items: center;
gap: 0.75rem;
border: 1px solid rgba(255,0,0,0.3);
padding: 0.5rem 1.5rem;
background: rgba(255,0,0,0.05);
}
.hero-badge::before {
content: '◆';
font-size: 0.5rem;
}
.hero-title {
font-family: 'Orbitron', sans-serif;
font-weight: 900;
font-size: clamp(2.5rem, 7vw, 5.5rem);
color: #fff;
line-height: 1.05;
margin-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: -1px;
}
.hero-title .red {
color: var(--red-primary);
text-shadow: 0 0 40px rgba(255,0,0,0.5), 0 0 80px rgba(255,0,0,0.3);
}
.hero-subtitle {
font-family: 'Orbitron', sans-serif;
font-weight: 700;
font-size: clamp(1.2rem, 3vw, 2rem);
color: var(--red-deep);
text-transform: uppercase;
letter-spacing: 6px;
margin-bottom: 1.5rem;
text-shadow: 0 0 30px rgba(255,0,0,0.3);
}
.hero-tagline {
font-family: 'Share Tech Mono', monospace;
font-size: 0.85rem;
color: var(--text-dim);
letter-spacing: 2px;
margin-bottom: 2.5rem;
line-height: 1.6;
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.hero-buttons {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
.btn-primary {
font-family: 'Orbitron', sans-serif;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 3px;
text-transform: uppercase;
padding: 1rem 2.5rem;
background: var(--red-primary);
color: var(--black);
border: none;
cursor: pointer;
transition: all 0.3s;
position: relative;
overflow: hidden;
}
.btn-primary:hover {
background: var(--red-bright);
box-shadow: 0 0 40px rgba(255,0,0,0.5);
color: #000;
transform: translateY(-2px);
}
.btn-secondary {
font-family: 'Orbitron', sans-serif;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 3px;
text-transform: uppercase;
padding: 1rem 2.5rem;
background: transparent;
color: var(--red-primary);
border: 1px solid var(--red-primary);
cursor: pointer;
transition: all 0.3s;
}
.btn-secondary:hover {
background: rgba(255,0,0,0.1);
box-shadow: 0 0 30px rgba(255,0,0,0.2);
transform: translateY(-2px);
}
.hero-scroll {
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
z-index: 3;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
font-family: 'Share Tech Mono', monospace;
font-size: 0.65rem;
letter-spacing: 3px;
color: var(--text-dim);
text-transform: uppercase;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
}
.hero-scroll .arrow {
width: 1px;
height: 40px;
background: linear-gradient(to bottom, var(--red-primary), transparent);
}
/* SECTIONS */
section {
padding: 6rem 0;
position: relative;
}
.section-divider {
width: 100%;
height: 1px;
background: linear-gradient(to right, transparent, var(--red-dark), transparent);
margin: 0;
}
/* STORY */
.story-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
align-items: start;
}
.story-text p {
font-size: 1rem;
line-height: 1.8;
color: var(--text-dim);
margin-bottom: 1.5rem;
}
.story-text p:first-child {
font-size: 1.15rem;
color: var(--text);
line-height: 1.7;
}
.story-visual {
position: relative;
height: 400px;
border: 1px solid rgba(255,0,0,0.15);
background: var(--gray-dark);
overflow: hidden;
}
.story-visual-inner {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
display: flex;
align-items: center;
justify-content: center;
}
/* PRODUCT OVERVIEW */
.product-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.product-card {
border: 1px solid rgba(255,0,0,0.12);
background: var(--gray-dark);
padding: 2rem;
transition: all 0.4s;
position: relative;
overflow: hidden;
}
.product-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 2px;
background: linear-gradient(to right, transparent, var(--red-primary), transparent);
opacity: 0;
transition: opacity 0.4s;
}
.product-card:hover {
border-color: rgba(255,0,0,0.3);
transform: translateY(-4px);
box-shadow: 0 10px 40px rgba(255,0,0,0.1);
}
.product-card:hover::before { opacity: 1; }
.product-icon {
width: 48px;
height: 48px;
margin-bottom: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
}
.product-icon svg { width: 100%; height: 100%; }
.product-card h3 {
font-family: 'Orbitron', sans-serif;
font-size: 0.85rem;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: #fff;
margin-bottom: 0.75rem;
}
.product-card p {
font-size: 0.85rem;
line-height: 1.6;
color: var(--text-dim);
}
/* FEATURES */
.features-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
}
.feature-card {
border: 1px solid rgba(255,0,0,0.1);
background: var(--gray-dark);
padding: 1.5rem;
transition: all 0.4s;
position: relative;
}
.feature-card:hover {
border-color: var(--red-primary);
background: rgba(255,0,0,0.03);
}
.feature-number {
font-family: 'Orbitron', sans-serif;
font-size: 2rem;
font-weight: 900;
color: rgba(255,0,0,0.15);
margin-bottom: 0.75rem;
}
.feature-card h3 {
font-family: 'Orbitron', sans-serif;
font-size: 0.7rem;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--red-primary);
margin-bottom: 0.5rem;
}
.feature-card p {
font-size: 0.8rem;
line-height: 1.5;
color: var(--text-dim);
}
/* SPECS */
.specs-wrapper {
border: 1px solid rgba(255,0,0,0.12);
overflow: hidden;
}
.specs-header {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
background: rgba(255,0,0,0.05);
border-bottom: 1px solid rgba(255,0,0,0.15);
}
.specs-header span {
font-family: 'Share Tech Mono', monospace;
font-size: 0.7rem;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--red-primary);
padding: 1rem 1.5rem;
}
.spec-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
border-bottom: 1px solid rgba(255,255,255,0.04);
transition: background 0.3s;
}
.spec-row:hover { background: rgba(255,0,0,0.02); }
.spec-row span {
font-size: 0.8rem;
padding: 0.8rem 1.5rem;
display: flex;
align-items: center;
}
.spec-row span:first-child { color: var(--text-dim); font-family: 'Share Tech Mono', monospace; font-size: 0.7rem; letter-spacing: 1px; }
.spec-row span:nth-child(2) { color: var(--text); }
.spec-row span:nth-child(3) { color: var(--red-primary); font-family: 'Share Tech Mono', monospace; font-size: 0.7rem; }
/* GAMES */
.games-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.game-card {
border: 1px solid rgba(255,0,0,0.12);
background: var(--gray-dark);
overflow: hidden;
transition: all 0.4s;
}
.game-card:hover {
border-color: var(--red-primary);
transform: translateY(-4px);
box-shadow: 0 10px 40px rgba(255,0,0,0.15);
}
.game-art {
height: 200px;
background: var(--black);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.game-art canvas { width: 100%; height: 100%; }
.game-info {
padding: 1.25rem;
}
.game-genre {
font-family: 'Share Tech Mono', monospace;
font-size: 0.65rem;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--red-primary);
margin-bottom: 0.5rem;
}
.game-info h3 {
font-family: 'Orbitron', sans-serif;
font-size: 0.9rem;
font-weight: 700;
color: #fff;
margin-bottom: 0.5rem;
letter-spacing: 0.5px;
}
.game-info p {
font-size: 0.8rem;
line-height: 1.5;
color: var(--text-dim);
margin-bottom: 0.75rem;
}
.game-meta {
display: flex;
gap: 1rem;
font-family: 'Share Tech Mono', monospace;
font-size: 0.65rem;
letter-spacing: 1px;
color: var(--text-dim);
text-transform: uppercase;
}
.game-meta span { color: var(--red-primary); }
/* WHY FAILED */
.failed-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3rem;
}
.failed-col h3 {
font-family: 'Orbitron', sans-serif;
font-size: 0.85rem;
font-weight: 700;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 1.5rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid rgba(255,0,0,0.2);
}
.failed-col.fail h3 { color: var(--red-dark); }
.failed-col.legacy h3 { color: var(--red-primary); }
.failed-col ul { list-style: none; }
.failed-col ul li {
font-size: 0.9rem;
line-height: 1.7;
color: var(--text-dim);
padding: 0.5rem 0;
padding-left: 1.2rem;
position: relative;
}
.failed-col.fail ul li::before {
content: '▸';
position: absolute;
left: 0;
color: var(--red-dark);
}
.failed-col.legacy ul li::before {
content: '◆';
position: absolute;
left: 0;
color: var(--red-primary);
}
/* TIMELINE */
.timeline {
position: relative;
padding: 2rem 0;
}
.timeline::before {
content: '';
position: absolute;
left: 50%;
top: 0; bottom: 0;
width: 1px;
background: linear-gradient(to bottom, transparent, var(--red-dark), var(--red-primary), var(--red-dark), transparent);
}
.timeline-item {
display: flex;
align-items: flex-start;
margin-bottom: 3rem;
position: relative;
}
.timeline-item:nth-child(odd) { flex-direction: row-reverse; }
.timeline-content {
width: 45%;
padding: 1.5rem;
border: 1px solid rgba(255,0,0,0.1);
background: var(--gray-dark);
transition: all 0.4s;
}
.timeline-content:hover {
border-color: rgba(255,0,0,0.3);
box-shadow: 0 5px 30px rgba(255,0,0,0.1);
}
.timeline-dot {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 12px;
height: 12px;
background: var(--red-primary);
border-radius: 50%;
box-shadow: 0 0 20px var(--red-glow);
z-index: 2;
}
.timeline-year {
font-family: 'Orbitron', sans-serif;
font-size: 0.7rem;
font-weight: 700;
color: var(--red-primary);
letter-spacing: 2px;
margin-bottom: 0.5rem;
}
.timeline-content h3 {
font-family: 'Orbitron', sans-serif;
font-size: 0.85rem;
font-weight: 700;
color: #fff;
margin-bottom: 0.5rem;
}
.timeline-content p {
font-size: 0.8rem;
line-height: 1.6;
color: var(--text-dim);
}
/* RED DISPLAY SIM */
.red-display-section {
padding: 6rem 0;
background: var(--gray-dark);
}
.display-sim {
position: relative;
width: 100%;
max-width: 700px;
margin: 0 auto;
aspect-ratio: 16/10;
border: 2px solid var(--red-primary);
background: var(--black);
overflow: hidden;
box-shadow: 0 0 60px rgba(255,0,0,0.2), inset 0 0 60px rgba(255,0,0,0.05);
}
.display-sim canvas {
width: 100%;
height: 100%;
display: block;
}
.display-overlay {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 1px,
rgba(0,0,0,0.4) 1px,
rgba(0,0,0,0.4) 2px
);
pointer-events: none;
}
.display-overlay::after {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.6) 100%);
pointer-events: none;
}
.display-label {
position: absolute;
bottom: 0.75rem;
right: 0.75rem;
font-family: 'Share Tech Mono', monospace;
font-size: 0.6rem;
color: var(--red-primary);
letter-spacing: 2px;
opacity: 0.7;
text-transform: uppercase;
}
.display-fps {
position: absolute;
top: 0.75rem;
left: 0.75rem;
font-family: 'Share Tech Mono', monospace;
font-size: 0.6rem;
color: var(--red-primary);
letter-spacing: 2px;
}
/* COLLECTOR MARKET */
.market-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.market-card {
border: 1px solid rgba(255,0,0,0.12);
background: var(--gray-dark);
padding: 1.5rem;
transition: all 0.4s;
position: relative;
}
.market-card:hover {
border-color: var(--red-primary);
transform: translateY(-3px);
}
.market-card .rarity {
position: absolute;
top: 1rem;
right: 1rem;
font-family: 'Share Tech Mono', monospace;
font-size: 0.6rem;
letter-spacing: 2px;
text-transform: uppercase;
padding: 0.25rem 0.75rem;
border: 1px solid;
}
.rarity.common { color: var(--text-dim); border-color: var(--text-dim); }
.rarity.uncommon { color: var(--text); border-color: var(--text); }
.rarity.rare { color: var(--red-primary); border-color: var(--red-primary); }
.rarity.legendary { color: var(--red-bright); border-color: var(--red-bright); box-shadow: 0 0 10px var(--red-glow); }
.market-card h3 {
font-family: 'Orbitron', sans-serif;
font-size: 0.85rem;
font-weight: 700;
color: #fff;
margin-bottom: 0.75rem;
margin-top: 0.5rem;
}
.market-details {
font-family: 'Share Tech Mono', monospace;
font-size: 0.7rem;
color: var(--text-dim);
line-height: 1.8;
}
.market-details strong { color: var(--text); }
.market-price {
font-family: 'Orbitron', sans-serif;
font-size: 1.2rem;
font-weight: 700;
color: var(--red-primary);
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid rgba(255,0,0,0.1);
}
/* COMPARISON */
.comparison-table {
width: 100%;
border-collapse: collapse;
border: 1px solid rgba(255,0,0,0.12);
}
.comparison-table thead th {
font-family: 'Orbitron', sans-serif;
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--red-primary);
padding: 1rem;
background: rgba(255,0,0,0.05);
text-align: left;
border-bottom: 1px solid rgba(255,0,0,0.15);
}
.comparison-table tbody td {
font-size: 0.8rem;
padding: 0.8rem 1rem;
border-bottom: 1px solid rgba(255,255,255,0.03);
color: var(--text-dim);
}
.comparison-table tbody td:first-child {
font-family: 'Orbitron', sans-serif;
font-size: 0.7rem;
font-weight: 700;
color: #fff;
letter-spacing: 1px;
}
.comparison-table tbody tr:hover { background: rgba(255,0,0,0.02); }
.comparison-table .highlight { background: rgba(255,0,0,0.04); }
.comparison-table .highlight td { color: var(--text); border-left: 2px solid var(--red-primary); }
/* QUOTES */
.quotes-section {
padding: 6rem 0;
background: var(--gray-dark);
text-align: center;
}
.quote-block {
max-width: 700px;
margin: 0 auto 3rem;
position: relative;
}
.quote-block::before {
content: '"';
font-family: 'Orbitron', sans-serif;
font-size: 4rem;
color: rgba(255,0,0,0.15);
position: absolute;
top: -1.5rem;
left: -1rem;
}
.quote-block blockquote {
font-size: 1.1rem;
line-height: 1.8;
color: var(--text);
font-style: italic;
margin-bottom: 1rem;
}
.quote-block cite {
font-family: 'Share Tech Mono', monospace;
font-size: 0.7rem;
letter-spacing: 2px;
color: var(--red-primary);
text-transform: uppercase;
}
/* FOOTER */
footer {
padding: 4rem 0 2rem;
border-top: 1px solid rgba(255,0,0,0.1);
background: var(--black);
}
.footer-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr;
gap: 3rem;
margin-bottom: 3rem;
}
.footer-brand .logo {
font-family: 'Orbitron', sans-serif;
font-weight: 900;
font-size: 1rem;
color: #fff;
letter-spacing: 2px;
margin-bottom: 1rem;
}
.footer-brand .logo .red { color: var(--red-primary); }
.footer-brand p {
font-size: 0.8rem;
line-height: 1.6;
color: var(--text-dim);
max-width: 300px;
}
.footer-col h4 {
font-family: 'Orbitron', sans-serif;
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--red-primary);
margin-bottom: 1rem;
}
.footer-col ul { list-style: none; }
.footer-col ul li { margin-bottom: 0.5rem; }
.footer-col ul li a {
font-size: 0.8rem;
color: var(--text-dim);
}
.footer-col ul li a:hover { color: var(--red-primary); }
.footer-bottom {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 2rem;
border-top: 1px solid rgba(255,255,255,0.05);
font-family: 'Share Tech Mono', monospace;
font-size: 0.65rem;
letter-spacing: 1px;
color: var(--text-dim);
}
.footer-bottom .disclaimer {
max-width: 600px;
line-height: 1.5;
}
/* ANIMATIONS */
.fade-in {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.8s ease, transform 0.8s ease;
}
.fade-in.visible {
opacity: 1;
transform: translateY(0);
}
/* RESPONSIVE */
@media (max-width: 1024px) {
.features-grid { grid-template-columns: repeat(2, 1fr); }
.product-grid { grid-template-columns: repeat(2, 1fr); }
.games-grid { grid-template-columns: repeat(2, 1fr); }
.market-grid { grid-template-columns: repeat(2, 1fr); }
.story-grid { grid-template-columns: 1fr; }
.failed-grid { grid-template-columns: 1fr; }
.footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 768px) {
.features-grid { grid-template-columns: 1fr; }
.product-grid { grid-template-columns: 1fr; }
.games-grid { grid-template-columns: 1fr; }
.market-grid { grid-template-columns: 1fr; }
.nav-links { display: none; }
.specs-header, .spec-row { grid-template-columns: 1fr; }
.specs-header span, .spec-row span { padding: 0.5rem 1rem; }
.comparison-table { font-size: 0.7rem; }
.comparison-table thead th, .comparison-table tbody td { padding: 0.5rem; }
.timeline::before { left: 1rem; }
.timeline-item, .timeline-item:nth-child(odd) { flex-direction: row; padding-left: 3rem; }
.timeline-content { width: 100%; }
.timeline-dot { left: 1rem; }
.footer-grid { grid-template-columns: 1fr; }
.footer-bottom { flex-direction: column; gap: 1rem; text-align: center; }
}
/* NOISE TEXTURE */
.noise {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
pointer-events: none;
z-index: 9998;
opacity: 0.03;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* GLOW TEXT */
.glow-red {
color: var(--red-primary);
text-shadow: 0 0 10px rgba(255,0,0,0.5);
}
/* RED LINE ACCENTS */
.red-line {
width: 60px;
height: 2px;
background: var(--red-primary);
margin-bottom: 2rem;
box-shadow: 0 0 10px var(--red-glow);
}
/* STATS */
.stats-bar {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1rem;
padding: 3rem 0;
}
.stat-item {
text-align: center;
padding: 1.5rem;
border: 1px solid rgba(255,0,0,0.1);
background: var(--gray-dark);
}
.stat-number {
font-family: 'Orbitron', sans-serif;
font-size: 2rem;
font-weight: 900;
color: var(--red-primary);
text-shadow: 0 0 20px var(--red-glow);
}
.stat-label {
font-family: 'Share Tech Mono', monospace;
font-size: 0.65rem;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--text-dim);
margin-top: 0.5rem;
}
@media (max-width: 768px) {
.stats-bar { grid-template-columns: repeat(2, 1fr); }
}
</style>
</head>
<body>
<div class="noise"></div>
<!-- NAV -->
<nav id="navbar">
<div class="nav-logo">
<span class="nintendo">NINTENDO</span>
<span class="vb">VIRTUAL BOY</span>
</div>
<ul class="nav-links">
<li><a href="#story">Story</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#specs">Specs</a></li>
<li><a href="#games">Games</a></li>
<li><a href="#collectors">Collect</a></li>
<li><a href="#timeline">Timeline</a></li>
<li><a href="#hero" class="nav-cta">Enter Red Space</a></li>
</ul>
</nav>
<!-- HERO -->
<section id="hero">
<canvas id="hero-canvas"></canvas>
<div class="hero-overlay"></div>
<div class="hero-content">
<div class="hero-badge">Nintendo Experimental Hardware — 1995</div>
<h1 class="hero-title">
<span class="red">VIRTUAL</span><br>BOY
</h1>
<div class="hero-subtitle">The Red Horizon</div>
<p class="hero-tagline">
A bold experiment in immersive 3D gaming. A tabletop VR headset rendered in monochrome red.
The hardware that dared to imagine a future of stereoscopic play — before the world was ready.
</p>
<div class="hero-buttons">
<button class="btn-primary" onclick="document.getElementById('story').scrollIntoView({behavior:'smooth'})">Explore the Hardware</button>
<button class="btn-secondary" onclick="document.getElementById('display-sim').scrollIntoView({behavior:'smooth'})">Enter Red Space</button>
</div>
</div>
<div class="hero-scroll">
<span>Scroll</span>
<div class="arrow"></div>
</div>
</section>
<!-- STATS -->
<div class="container">
<div class="stats-bar fade-in">
<div class="stat-item">
<div class="stat-number">22</div>
<div class="stat-label">Games Released</div>
</div>
<div class="stat-item">
<div class="stat-number">1995</div>
<div class="stat-label">Launch Year</div>
</div>
<div class="stat-item">
<div class="stat-number">$179</div>
<div class="stat-label">Launch Price</div>
</div>
<div class="stat-item">
<div class="stat-number"></div>
<div class="stat-label">Cult Legacy</div>
</div>
</div>
</div>
<div class="section-divider"></div>
<!-- STORY -->
<section id="story">
<div class="container">
<div class="story-grid fade-in">
<div class="story-text">
<div class="section-label">The Story</div>
<h2 class="section-title">A Bold Experiment in <span class="red">Immersive</span> Play</h2>
<p>
In 1995, Nintendo released one of the most unusual consumer electronics devices ever conceived.
The Virtual Boy was not a handheld. Not a home console. Not an arcade machine. It was a tabletop
stereoscopic display system — a personal VR headset that promised to deliver full 3D gaming
on a red monochrome screen.
</p>
<p>
Born from the ambition of a young engineer named Genyo Takeda, the device was conceived during
a trans-Pacific flight where the idea for a tabletop 3D gaming system was sketched on a
napkin. What followed was a remarkably fast development cycle — roughly six months — that
produced a device both visionary and deeply flawed.
</p>
<p>
The Virtual Boy sold nearly 800,000 units before being discontinued. Commercially, it was a failure.
But in the decades since, it has become one of the most fascinating artifacts in gaming history —
a relic of early VR ambition, a collector's treasure, and a testament to the courage (and risk)
of radical product experimentation.
</p>
</div>
<div class="story-visual">
<div class="story-visual-inner">
<svg viewBox="0 0 300 300" width="250" height="250">
<!-- Virtual Boy headset silhouette - stylized wireframe -->
<defs>
<filter id="glow">
<feGaussianBlur stdDeviation="3" result="coloredBlur"/>
<feMerge>
<feMergeNode in="coloredBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<!-- Main headband -->
<path d="M80,100 Q150,40 220,100" fill="none" stroke="#ff0000" stroke-width="2" filter="url(#glow)" opacity="0.8"/>
<!-- Left lens -->
<ellipse cx="115" cy="130" rx="35" ry="30" fill="none" stroke="#ff0000" stroke-width="1.5" filter="url(#glow)" opacity="0.6"/>
<!-- Right lens -->
<ellipse cx="185" cy="130" rx="35" ry="30" fill="none" stroke="#ff0000" stroke-width="1.5" filter="url(#glow)" opacity="0.6"/>
<!-- Display housing -->
<rect x="100" y="145" width="100" height="40" rx="5" fill="none" stroke="#ff0000" stroke-width="1.5" filter="url(#glow)" opacity="0.5"/>
<!-- Grid lines in display -->
<line x1="115" y1="145" x2="115" y2="185" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="130" y1="145" x2="130" y2="185" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="145" y1="145" x2="145" y2="185" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="160" y1="145" x2="160" y2="185" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="175" y1="145" x2="175" y2="185" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="100" y1="155" x2="200" y2="155" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="100" y1="165" x2="200" y2="165" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<line x1="100" y1="175" x2="200" y2="175" stroke="#ff0000" stroke-width="0.5" opacity="0.3"/>
<!-- Stand -->
<line x1="120" y1="185" x2="100" y2="230" stroke="#ff0000" stroke-width="1.5" opacity="0.5"/>
<line x1="180" y1="185" x2="200" y2="230" stroke="#ff0000" stroke-width="1.5" opacity="0.5"/>
<line x1="85" y1="230" x2="215" y2="230" stroke="#ff0000" stroke-width="2" filter="url(#glow)" opacity="0.6"/>
<!-- Controller ports -->
<rect x="120" y="190" width="20" height="15" rx="2" fill="none" stroke="#ff0000" stroke-width="1" opacity="0.4"/>
<rect x="160" y="190" width="20" height="15" rx="2" fill="none" stroke="#ff0000" stroke-width="1" opacity="0.4"/>
<!-- Particles -->
<circle cx="60" cy="80" r="1.5" fill="#ff0000" opacity="0.5"/>
<circle cx="240" cy="70" r="1" fill="#ff0000" opacity="0.4"/>
<circle cx="50" cy="200" r="1" fill="#ff0000" opacity="0.3"/>
<circle cx="250" cy="180" r="1.5" fill="#ff0000" opacity="0.4"/>
<circle cx="150" cy="50" r="1" fill="#ff0000" opacity="0.5"/>
<circle cx="90" cy="250" r="1" fill="#ff0000" opacity="0.3"/>
<circle cx="210" cy="250" r="1" fill="#ff0000" opacity="0.3"/>
<!-- Label -->
<text x="150" y="260" text-anchor="middle" fill="#ff0000" font-family="monospace" font-size="10" letter-spacing="4" opacity="0.6">VIRTUAL BOY</text>
</svg>
</div>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- PRODUCT OVERVIEW -->
<section id="product">
<div class="container">
<div class="fade-in">
<div class="section-label">Product Overview</div>
<h2 class="section-title">The Hardware <span class="red">Reimagined</span></h2>
<p style="color:var(--text-dim); max-width:600px; margin-bottom:3rem; font-size:0.9rem; line-height:1.7;">
Presented here as the complete hardware ecosystem — the headset, the stand, the controller,
and the game cartridges that powered one of gaming's most ambitious experiments.
</p>
</div>
<div class="product-grid fade-in">
<div class="product-card">
<div class="product-icon">
<svg viewBox="0 0 48 48" fill="none" stroke="#ff0000" stroke-width="1.5">
<rect x="8" y="12" width="32" height="24" rx="3"/>
<line x1="16" y1="12" x2="16" y2="36"/>
<line x1="24" y1="12" x2="24" y2="36"/>
<line x1="32" y1="12" x2="32" y2="36"/>
<circle cx="24" cy="24" r="4"/>
</svg>
</div>
<h3>Stereoscopic Headset</h3>
<p>Dual OLED displays delivering 224×172 pixels per eye, creating a stereoscopic 3D effect through a single monochrome LED panel system. Head-mounted with adjustable focus.</p>
</div>
<div class="product-card">
<div class="product-icon">
<svg viewBox="0 0 48 48" fill="none" stroke="#ff0000" stroke-width="1.5">
<path d="M10,30 L24,8 L38,30 Z"/>
<line x1="10" y1="30" x2="38" y2="30"/>
<line x1="17" y1="30" x2="17" y2="38"/>
<line x1="31" y1="30" x2="31" y2="38"/>
<line x1="14" y1="38" x2="34" y2="38"/>
</svg>
</div>
<h3>Tabletop Stand</h3>
<p>Folding tripod-style stand that transforms the Virtual Boy from a tabletop experience to a fully portable headset setup. Compact and portable for the era.</p>
</div>
<div class="product-card">
<div class="product-icon">
<svg viewBox="0 0 48 48" fill="none" stroke="#ff0000" stroke-width="1.5">
<rect x="6" y="18" width="36" height="18" rx="9"/>
<circle cx="16" cy="27" r="3"/>
<circle cx="32" cy="27" r="3"/>
<circle cx="24" cy="22" r="2"/>
<line x1="24" y1="24" x2="24" y2="20"/>
</svg>
</div>
<h3>Dual-Grip Controller</h3>
<p>Unique ergonomic controller with a directional pad on the left grip, action buttons on the right, and a distinctive shoulder button. Designed for seated tabletop play.</p>
</div>
<div class="product-card">
<div class="product-icon">
<svg viewBox="0 0 48 48" fill="none" stroke="#ff0000" stroke-width="1.5">
<rect x="12" y="6" width="24" height="36" rx="2"/>
<line x1="12" y1="14" x2="36" y2="14"/>
<circle cx="24" cy="26" r="4"/>
<line x1="18" y1="34" x2="30" y2="34"/>
</svg>
</div>
<h3>Cartridge System</h3>
<p>ROM cartridge-based game format with proprietary connector. 22 titles released during the console's lifecycle, from sports to shooters to platformers.</p>
</div>
<div class="product-card">
<div class="product-icon">
<svg viewBox="0 0 48 48" fill="none" stroke="#ff0000" stroke-width="1.5">
<circle cx="24" cy="24" r="16"/>
<circle cx="24" cy="24" r="10"/>
<circle cx="24" cy="24" r="4"/>
<line x1="24" y1="8" x2="24" y2="4"/>
<line x1="24" y1="40" x2="24" y2="44"/>
<line x1="8" y1="24" x2="4" y2="24"/>
<line x1="40" y1="24" x2="44" y2="24"/>
</svg>
</div>
<h3>60Hz Refresh Rate</h3>
<p>Red LED display running at 60 frames per second to eliminate flicker and maintain the illusion of continuous 3D imagery. A technical achievement for its time.</p>
</div>
<div class="product-card">
<div class="product-icon">
<svg viewBox="0 0 48 48" fill="none" stroke="#ff0000" stroke-width="1.5">
<path d="M12,36 L12,12 L36,12 L36,36 Z"/>
<path d="M12,12 L36,36"/>
<path d="M36,12 L12,36"/>
<circle cx="24" cy="24" r="3"/>
</svg>
</div>
<h3>Stereoscopic Depth</h3>
<p>True parallax-based 3D rendering using separate images for each eye. One of the first consumer devices to deliver genuine stereoscopic depth without head tracking.</p>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- FEATURES -->
<section id="features">
<div class="container">
<div class="fade-in">
<div class="section-label">Key Features</div>
<h2 class="section-title">Eight Pillars of <span class="red">Innovation</span></h2>
</div>
<div class="features-grid fade-in">
<div class="feature-card">
<div class="feature-number">01</div>
<h3>Red Monochrome Display</h3>
<p>A single red LED panel driving dual displays. The monochrome palette was both a cost-saving measure and a defining aesthetic choice that gave the Virtual Boy its signature look.</p>
</div>
<div class="feature-card">
<div class="feature-number">02</div>
<h3>Stereoscopic 3D</h3>
<p>Genuine parallax-based 3D rendering. Each eye received a separate image, creating depth perception without the need for head-tracking or motion sensors.</p>
</div>
<div class="feature-card">
<div class="feature-number">03</div>
<h3>Tabletop Design</h3>
<p>A compact tabletop form factor with a folding stand. Unlike VR headsets of today, the Virtual Boy was designed to sit on a flat surface at eye level.</p>
</div>
<div class="feature-card">
<div class="feature-number">04</div>
<h3>Dual-Grip Controller</h3>
<p>An ergonomic controller split into two grips, with the D-pad on the left and action buttons on the right. A unique input device designed for seated play sessions.</p>
</div>
<div class="feature-card">
<div class="feature-number">05</div>
<h3>Cartridge-Based Games</h3>
<p>22 official titles released across genres including sports, action, platformers, and fighting games. Each game was a self-contained ROM cartridge.</p>
</div>
<div class="feature-card">
<div class="feature-number">06</div>
<h3>Portable, Not Handheld</h3>
<p>While portable in the sense that it could be set up anywhere, the Virtual Boy was not a handheld like the Game Boy. It required a flat surface and external power.</p>
</div>
<div class="feature-card">
<div class="feature-number">07</div>
<h3>1990s VR Concept</h3>
<p>One of the earliest consumer attempts at virtual reality in gaming. Predated the VR revolution of today by decades, representing a bold vision of immersive play.</p>
</div>
<div class="feature-card">
<div class="feature-number">08</div>
<h3>Collector Rarity</h3>
<p>Discontinued after less than a year on the market. Complete-in-box units and sealed cartridges command premium prices among retro gaming collectors worldwide.</p>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- SPECS -->
<section id="specs">
<div class="container">
<div class="fade-in">
<div class="section-label">Technical Specifications</div>
<h2 class="section-title">Hardware <span class="red">Specifications</span></h2>
</div>
<div class="specs-wrapper fade-in">
<div class="specs-header">
<span>Parameter</span>
<span>Specification</span>
<span>Notes</span>
</div>
<div class="spec-row"><span>Display Type</span><span>Dual Red LED panels, 224×172 per eye</span><span>Monochrome only</span></div>
<div class="spec-row"><span>Color Palette</span><span>Red (#FF0000) on black</span><span>1-bit color</span></div>
<div class="spec-row"><span>Processor</span><span>Sharp L3H10001 (custom CPU)</span><span>~20 MHz equivalent</span></div>
<div class="spec-row"><span>Graphics</span><span>Custom GPU with stereoscopic rendering</span><span>Parallax-based 3D</span></div>
<div class="spec-row"><span>Refresh Rate</span><span>60 Hz</span><span>Flicker-free target</span></div>
<div class="spec-row"><span>Sound</span><span>Stereo audio via headset earpieces</span><span>8-bit PCM audio</span></div>
<div class="spec-row"><span>Controller</span><span>Dual-grip with D-pad, 4 buttons, shoulder switch</span><span>Proprietary connector</span></div>
<div class="spec-row"><span>Game Format</span><span>ROM Cartridge</span><span>1 MB storage capacity</span></div>
<div class="spec-row"><span>Release Era</span><span>1995 (July 21, Japan / August 14, NA)</span><span>5th generation</span></div>
<div class="spec-row"><span>Visual Style</span><span>Wireframe & raster red monochrome</span><span>Signature aesthetic</span></div>
<div class="spec-row"><span>Power Source</span><span>6× AA batteries or AC adapter</span><span>~30 min battery life</span></div>
<div class="spec-row"><span>Player Mode</span><span>Single player, tabletop</span><span>Not handheld</span></div>
<div class="spec-row"><span>Collector Status</span><span>High demand, limited supply</span><span>Complete units $400–$1200</span></div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- GAMES -->
<section id="games">
<div class="container">
<div class="fade-in">
<div class="section-label">Games Library</div>
<h2 class="section-title">Collector's <span class="red">Game Selection</span></h2>
<p style="color:var(--text-dim); max-width:600px; margin-bottom:3rem; font-size:0.9rem; line-height:1.7;">
A curated overview of the 22 official Virtual Boy titles. Each cartridge represents a piece of gaming history —
bold experiments in stereoscopic 3D that remain unique to this hardware.
</p>
</div>
<div class="games-grid fade-in" id="games-grid">
<!-- Games injected by JS -->
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- WHY FAILED -->
<section id="why">
<div class="container">
<div class="fade-in">
<div class="section-label">Historical Context</div>
<h2 class="section-title">Why It Failed, <span class="red">Why It Matters</span></h2>
</div>
<div class="failed-grid fade-in">
<div class="failed-col fail">
<h3>Why It Failed</h3>
<ul>
<li>The red monochrome display was perceived as limiting and gimmicky by mainstream consumers</li>
<li>Extended play sessions caused eye strain and discomfort for many users</li>
<li>The tabletop form factor required a flat surface — limiting true portability</li>
<li>Rushed six-month development cycle resulted in unresolved hardware issues</li>
<li>Launched in direct competition with the Sega Saturn and Sony PlayStation, overshadowing its impact</li>
<li> Nintendo's own Game Boy franchise made the Virtual Boy seem redundant to many players</li>
<li>Pricing at $179 (1995) was steep for a device with limited software support</li>
<li>No multiplayer capability out of the box, despite the potential for linked play</li>
</ul>
</div>
<div class="failed-col legacy">
<h3>Why It Matters</h3>
<ul>
<li>One of the earliest consumer attempts at virtual reality in gaming history</li>
<li>Bold experimentation in stereoscopic 3D — a technology that would define future gaming</li>
<li>Unique industrial design that remains instantly recognizable decades later</li>
<li>Inspired a generation of indie developers and retro hardware enthusiasts</li>
<li>Collector market has grown steadily, with complete units commanding premium prices</li>
<li>The games themselves showcase creative use of the hardware's unique 3D capabilities</li>
<li>Represents a moment when Nintendo was willing to take massive risks on new technology</li>
<li>Proved the concept of head-mounted immersive gaming — long before the VR boom of the 2010s</li>
</ul>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- TIMELINE -->
<section id="timeline">
<div class="container">
<div class="fade-in">
<div class="section-label">Timeline</div>
<h2 class="section-title">A Brief <span class="red">Chronology</span></h2>
</div>
<div class="timeline fade-in">
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">1994 — Q3</div>
<h3>Concept Development</h3>
<p>Engineer Genyo Takeda conceives the tabletop 3D gaming concept during a flight from Tokyo to Los Angeles. Development begins in earnest.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">1995 — March</div>
<h3>First Public Reveal</h3>
<p>Nintendo announces the Virtual Boy at a press event. Early technical demonstrations generate both excitement and skepticism from the gaming press.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">1995 — July</div>
<h3>Japanese Launch</h3>
<p>The Virtual Boy launches in Japan on July 21, priced at ¥9,800. Initial stock sells out quickly, generating significant collector interest.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">1995 — August</div>
<h3>North American Launch</h3>
<p>The device arrives in North America on August 14 for $179. Mixed reviews cite the monochrome display and comfort issues, but the 3D effect draws praise.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">1995 — Late</div>
<h3>Public Reaction & Decline</h3>
<p>Reports of eye strain and headaches circulate. Sales slow significantly. Nintendo faces mounting criticism from both media and consumers.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">1996 — Spring</div>
<h3>Discontinuation</h3>
<p>After less than a year on the market, Nintendo discontinues the Virtual Boy. Nearly 800,000 units sold. Remaining inventory is liquidated.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">2000s — 2010s</div>
<h3>Cult Status & Rediscovery</h3>
<p>The Virtual Boy gains cult status among retro gaming enthusiasts. Online communities form, preserving games and sharing hardware modifications.</p>
</div>
<div class="timeline-dot"></div>
</div>
<div class="timeline-item">
<div class="timeline-content">
<div class="timeline-year">2020s — Present</div>
<h3>Modern Collector Renaissance</h3>
<p>Complete-in-box units and sealed cartridges command premium prices. The Virtual Boy is recognized as one of gaming's most fascinating artifacts — a bold experiment that defined a moment in history.</p>
</div>
<div class="timeline-dot"></div>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- RED DISPLAY SIMULATION -->
<section id="display-sim" class="red-display-section">
<div class="container">
<div class="fade-in">
<div class="section-label" style="justify-content:center;">Live Simulation</div>
<h2 class="section-title" style="text-align:center;">Experience the <span class="red">Red Display</span></h2>
<p style="color:var(--text-dim); text-align:center; max-width:600px; margin:0 auto 3rem; font-size:0.9rem; line-height:1.7;">
A simulated recreation of the Virtual Boy's red monochrome display. This canvas-based visualization
demonstrates the wireframe aesthetic, scanline effect, and stereoscopic depth that defined the experience.
</p>
</div>
<div class="display-sim fade-in" id="sim-container">
<canvas id="sim-canvas"></canvas>
<div class="display-overlay"></div>
<div class="display-fps" id="sim-fps">60 FPS</div>
<div class="display-label">VB DISPLAY SIMULATOR v1.0</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- COLLECTOR MARKET -->
<section id="collectors">
<div class="container">
<div class="fade-in">
<div class="section-label">Collector Market</div>
<h2 class="section-title">Market <span class="red">Place</span></h2>
<p style="color:var(--text-dim); max-width:600px; margin-bottom:3rem; font-size:0.9rem; line-height:1.7;">
Current collector marketplace data for Virtual Boy hardware and software. Prices fluctuate based on
condition, completeness, and provenance. These are estimated ranges based on recent auction and marketplace data.
</p>
</div>
<div class="market-grid fade-in">
<div class="market-card">
<div class="rarity rare">Rare</div>
<h3>Loose Console Unit</h3>
<div class="market-details">
<strong>Condition:</strong> Used, cosmetic wear<br>
<strong>Completeness:</strong> Console only, no accessories<br>
<strong>Notes:</strong> Functional, may need cleaning<br>
<strong>Includes:</strong> Headset + stand only
</div>
<div class="market-price">$180 — $300</div>
</div>
<div class="market-card">
<div class="rarity legendary">Legendary</div>
<h3>Complete-in-Box Unit</h3>
<div class="market-details">
<strong>Condition:</strong> Excellent, minimal wear<br>
<strong>Completeness:</strong> Full set with box & manual<br>
<strong>Notes:</strong> All original packaging included<br>
<strong>Includes:</strong> Console, stand, controller, box, manual
</div>
<div class="market-price">$500 — $1,200</div>
</div>
<div class="market-card">
<div class="rarity legendary">Legendary</div>
<h3>Sealed Game Cartridge</h3>
<div class="market-details">
<strong>Condition:</strong> Factory sealed<br>
<strong>Completeness:</strong> New, unopened<br>
<strong>Notes:</strong> Varies by title, some rarer than others<br>
<strong>Includes:</strong> Cartridge in original shrink
</div>
<div class="market-price">$80 — $400</div>
</div>
<div class="market-card">
<div class="rarity uncommon">Uncommon</div>
<h3>Controller Replacement</h3>
<div class="market-details">
<strong>Condition:</strong> Used or refurbished<br>
<strong>Completeness:</strong> Controller only<br>
<strong>Notes:</strong> Hard to find, many controllers lost<br>
<strong>Includes:</strong> Standalone controller
</div>
<div class="market-price">$60 — $120</div>
</div>
<div class="market-card">
<div class="rarity rare">Rare</div>
<h3>AC Adapter</h3>
<div class="market-details">
<strong>Condition:</strong> Used<br>
<strong>Completeness:</strong> Adapter + cable<br>
<strong>Notes:</strong> Optional accessory, frequently missing<br>
<strong>Includes:</strong> Power adapter unit
</div>
<div class="market-price">$25 — $50</div>
</div>
<div class="market-card">
<div class="rarity legendary">Legendary</div>
<h3>Full Collector Bundle</h3>
<div class="market-details">
<strong>Condition:</strong> Excellent to mint<br>
<strong>Completeness:</strong> Complete system + multiple games<br>
<strong>Notes:</strong> Rare find, includes accessories & games<br>
<strong>Includes:</strong> Full set + 3+ games + manual + box
</div>
<div class="market-price">$800 — $2,500</div>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- COMPARISON -->
<section id="comparison">
<div class="container">
<div class="fade-in">
<div class="section-label">Hardware Comparison</div>
<h2 class="section-title">Where the Virtual Boy <span class="red">Stands</span></h2>
</div>
<div class="fade-in" style="overflow-x:auto;">
<table class="comparison-table">
<thead>
<tr>
<th>Category</th>
<th>Virtual Boy</th>
<th>Game Boy</th>
<th>Saturn / PlayStation</th>
<th>Arcade Cabinet</th>
<th>Modern VR (Quest)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Era</td>
<td>1995</td>
<td>1989 — present</td>
<td>1994 — 1998</td>
<td>1970s — present</td>
<td>2019 — present</td>
</tr>
<tr>
<td>Display</td>
<td>Red LED monochrome</td>
<td>Green LCD, 160×144</td>
<td>TV output, 320×224+</td>
<td>Custom CRT/LED</td>
<td>RGB LCD/OLED, 1800×1600+</td>
</tr>
<tr>
<td>Portability</td>
<td>Tabletop only</td>
<td>True handheld</td>
<td>Home console</td>
<td>Floor-standing</td>
<td>Wireless standalone</td>
</tr>
<tr>
<td>3D Support</td>
<td>Stereoscopic true 3D</td>
<td>2D only</td>
<td>2D / polygonal 3D</td>
<td>2D / sprite 3D</td>
<td>Full 6DOF stereoscopic 3D</td>
</tr>
<tr>
<td>Comfort</td>
<td>Variable, eye strain reported</td>
<td>High</td>
<td>High</td>
<td>High (seated)</td>
<td>Variable (weight, heat)</td>
</tr>
<tr>
<td>Game Library</td>
<td>22 titles</td>
<td>1,500+ titles</td>
<td>Thousands</td>
<td>Thousands</td>
<td>1,000+ titles</td>
</tr>
<tr>
<td>Legacy</td>
<td>Fascinating failure</td>
<td>Iconic success</td>
<td>Pivot to modern era</td>
<td>Foundation of arcade culture</td>
<td>Current frontier</td>
</tr>
<tr>
<td>Collector Appeal</td>
<td>Very High</td>
<td>High</td>
<td>Moderate</td>
<td>Moderate (arcade)</td>
<td>Low (current gen)</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<div class="section-divider"></div>
<!-- QUOTES -->
<section class="quotes-section">
<div class="container">
<div class="fade-in">
<div class="section-label" style="justify-content:center;">Legacy</div>
<h2 class="section-title" style="text-align:center;">Words on the <span class="red">Red Horizon</span></h2>
</div>
<div class="quotes-section fade-in" style="padding-top:2rem;">
<div class="quote-block">
<blockquote>"The Virtual Boy was never supposed to be the future of gaming. But it showed us what the future of gaming could be — and that's why it still matters."</blockquote>
<cite>— Retro Gaming Historian, 2021</cite>
</div>
<div class="quote-block">
<blockquote>"In a world obsessed with color and resolution, the Virtual Boy reminds us that imagination is the most powerful display technology ever invented."</blockquote>
<cite>— Digital Arts Quarterly, 2019</cite>
</div>
<div class="quote-block">
<blockquote>"Eight hundred thousand units sold in less than a year. Not a triumph. Not a disaster. A bold experiment that asked the right questions, even if the answers were wrong."</blockquote>
<cite>— Console Architecture Journal, 2020</cite>
</div>
</div>
</div>
</section>
<!-- FOOTER -->
<footer>
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="logo">VIRTUAL <span class="red">BOY</span> ARCHIVE</div>
<p>A collector-focused retrospective on one of gaming's most bold and fascinating experiments. This microsite is an independent tribute to the Virtual Boy and its place in gaming history.</p>
</div>
<div class="footer-col">
<h4>Explore</h4>
<ul>
<li><a href="#story">The Story</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#specs">Specifications</a></li>
<li><a href="#games">Games Library</a></li>
<li><a href="#display-sim">Red Display Sim</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Resources</h4>
<ul>
<li><a href="#">Virtual Boy Wiki</a></li>
<li><a href="#">Collector's Database</a></li>
<li><a href="#">Hardware Preservation</a></li>
<li><a href="#">Emulation Archive</a></li>
<li><a href="#">Museum of Game Design</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Community</h4>
<ul>
<li><a href="#">Retro Gaming Forum</a></li>
<li><a href="#">Collector Network</a></li>
<li><a href="#">Hardware Modding</a></li>
<li><a href="#">Game Preservation</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
<div class="disclaimer">
This is an independent fan tribute microsite. Nintendo, Virtual Boy, Mario, Wario, and all related trademarks are property of Nintendo Co., Ltd. This site is not affiliated with, endorsed by, or connected to Nintendo. All content is for educational and archival purposes.
</div>
<div>© 2024 Virtual Boy Archive — A Collector's Tribute</div>
</div>
</div>
</footer>
<script>
// ===== NAV SCROLL EFFECT =====
const nav = document.getElementById('navbar');
window.addEventListener('scroll', () => {
nav.classList.toggle('scrolled', window.scrollY > 50);
});
// ===== FADE-IN ON SCROLL =====
const fadeEls = document.querySelectorAll('.fade-in');
const fadeObserver = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('visible');
}
});
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
fadeEls.forEach(el => fadeObserver.observe(el));
// ===== THREE.JS HERO =====
(function() {
const canvas = document.getElementById('hero-canvas');
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setClearColor(0x000000, 1);
const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x000000, 5, 25);
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 2, 8);
camera.lookAt(0, 0, 0);
// Lights
const ambientLight = new THREE.AmbientLight(0x330000, 0.5);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xff0000, 2, 20);
pointLight.position.set(0, 5, 5);
scene.add(pointLight);
const pointLight2 = new THREE.PointLight(0xff0000, 1, 15);
pointLight2.position.set(-5, -2, 3);
scene.add(pointLight2);
// Wireframe grid floor
const gridHelper = new THREE.GridHelper(30, 30, 0x330000, 0x110000);
gridHelper.position.y = -3;
scene.add(gridHelper);
// Floating wireframe headset
const headsetGroup = new THREE.Group();
// Main visor
const visorGeo = new THREE.BoxGeometry(3.2, 1.2, 0.8, 4, 2, 2);
const visorMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.7 });
const visor = new THREE.Mesh(visorGeo, visorMat);
headsetGroup.add(visor);
// Visor fill
const visorFillGeo = new THREE.BoxGeometry(3, 1, 0.78);
const visorFillMat = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.05 });
const visorFill = new THREE.Mesh(visorFillGeo, visorFillMat);
headsetGroup.add(visorFill);
// Left lens
const lensGeo = new THREE.CylinderGeometry(0.5, 0.5, 0.15, 16);
const lensMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.8 });
const leftLens = new THREE.Mesh(lensGeo, lensMat);
leftLens.rotation.x = Math.PI / 2;
leftLens.position.set(-0.7, 0, 0.5);
headsetGroup.add(leftLens);
// Right lens
const rightLens = new THREE.Mesh(lensGeo, lensMat);
rightLens.rotation.x = Math.PI / 2;
rightLens.position.set(0.7, 0, 0.5);
headsetGroup.add(rightLens);
// Headband
const bandGeo = new THREE.TorusGeometry(1.2, 0.06, 4, 20, Math.PI);
const bandMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.5 });
const headband = new THREE.Mesh(bandGeo, bandMat);
headband.rotation.y = Math.PI / 2;
headband.position.set(0, 0.3, -0.3);
headsetGroup.add(headband);
// Stand
const standGeo = new THREE.CylinderGeometry(0.03, 0.03, 1.5, 6);
const standMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.6 });
const leftStand = new THREE.Mesh(standGeo, standMat);
leftStand.position.set(-1.2, -1.5, 0);
leftStand.rotation.z = 0.15;
headsetGroup.add(leftStand);
const rightStand = new THREE.Mesh(standGeo, standMat);
rightStand.position.set(1.2, -1.5, 0);
rightStand.rotation.z = -0.15;
headsetGroup.add(rightStand);
// Base plate
const baseGeo = new THREE.BoxGeometry(3.5, 0.05, 1.5);
const baseMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.4 });
const base = new THREE.Mesh(baseGeo, baseMat);
base.position.set(0, -2.2, 0);
headsetGroup.add(base);
// Controller
const ctrlGeo = new THREE.BoxGeometry(1.2, 0.5, 0.3);
const ctrlMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.5 });
const controller = new THREE.Mesh(ctrlGeo, ctrlMat);
controller.position.set(0, -2.8, 2);
headsetGroup.add(controller);
scene.add(headsetGroup);
// Floating cartridges
const cartridgeGeo = new THREE.BoxGeometry(0.3, 0.6, 0.15);
const cartridgeMat = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, transparent: true, opacity: 0.4 });
for (let i = 0; i < 12; i++) {
const cart = new THREE.Mesh(cartridgeGeo, cartridgeMat);
cart.position.set(
(Math.random() - 0.5) * 15,
(Math.random() - 0.5) * 8,
(Math.random() - 0.5) * 10 - 2
);
cart.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, Math.random() * Math.PI);
cart.userData = {
rotSpeed: { x: (Math.random() - 0.5) * 0.02, y: (Math.random() - 0.5) * 0.02 },
floatSpeed: Math.random() * 0.01 + 0.005,
floatOffset: Math.random() * Math.PI * 2
};
scene.add(cart);
}
// Wireframe terrain patches
for (let i = 0; i < 5; i++) {
const terrainGeo = new THREE.PlaneGeometry(4, 4, 8, 8);
const positions = terrainGeo.attributes.position;
for (let j = 0; j < positions.count; j++) {
positions.setZ(j, Math.random() * 0.3);
}
terrainGeo.computeVertexNormals();
const terrainMat = new THREE.MeshBasicMaterial({
color: 0xff0000,
wireframe: true,
transparent: true,
opacity: 0.15,
side: THREE.DoubleSide
});
const terrain = new THREE.Mesh(terrainGeo, terrainMat);
terrain.position.set(
(Math.random() - 0.5) * 12,
-2.5 + Math.random() * 0.5,
-5 - Math.random() * 8
);
terrain.rotation.x = -Math.PI / 2 + (Math.random() - 0.5) * 0.3;
scene.add(terrain);
}
// Particle system
const particleCount = 200;
const particleGeo = new THREE.BufferGeometry();
const particlePositions = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
particlePositions[i * 3] = (Math.random() - 0.5) * 20;
particlePositions[i * 3 + 1] = (Math.random() - 0.5) * 15;
particlePositions[i * 3 + 2] = (Math.random() - 0.5) * 20;
}
particleGeo.setAttribute('position', new THREE.BufferAttribute(particlePositions, 3));
const particleMat = new THREE.PointsMaterial({
color: 0xff0000,
size: 0.04,
transparent: true,
opacity: 0.6,
sizeAttenuation: true
});
const particles = new THREE.Points(particleGeo, particleMat);
scene.add(particles);
// Mouse interaction
let mouseX = 0, mouseY = 0;
let targetMouseX = 0, targetMouseY = 0;
document.addEventListener('mousemove', (e) => {
targetMouseX = (e.clientX / window.innerWidth - 0.5) * 2;
targetMouseY = (e.clientY / window.innerHeight - 0.5) * 2;
});
// Animation
let time = 0;
function animate() {
requestAnimationFrame(animate);
time += 0.01;
mouseX += (targetMouseX - mouseX) * 0.05;
mouseY += (targetMouseY - mouseY) * 0.05;
// Camera subtle movement
camera.position.x = mouseX * 1.5;
camera.position.y = 2 + mouseY * -0.8;
camera.lookAt(0, 0, 0);
// Headset rotation
headsetGroup.rotation.y = Math.sin(time * 0.3) * 0.3 + mouseX * 0.2;
headsetGroup.rotation.x = Math.sin(time * 0.2) * 0.1 + mouseY * 0.1;
headsetGroup.position.y = Math.sin(time * 0.5) * 0.3;
// Floating cartridges
scene.children.forEach(child => {
if (child.userData && child.userData.rotSpeed) {
child.rotation.x += child.userData.rotSpeed.x;
child.rotation.y += child.userData.rotSpeed.y;
child.position.y += Math.sin(time * 2 + child.userData.floatOffset) * child.userData.floatSpeed;
}
});
// Particles
const pPositions = particles.geometry.attributes.position;
for (let i = 0; i < particleCount; i++) {
pPositions.array[i * 3 + 1] += Math.sin(time + i) * 0.002;
}
pPositions.needsUpdate = true;
particles.rotation.y = time * 0.05;
// Grid subtle animation
gridHelper.position.z = (time * 0.5) % 1;
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
})();
// ===== GAMES DATA & RENDERING =====
const gamesData = [
{
name: "Mario's Tennis",
genre: "Sports",
rarity: "Common",
desc: "The launch title that introduced players to the Virtual Boy's stereoscopic 3D tennis court. Features a 3D perspective that makes the ball appear to fly at you.",
art: "tennis"
},
{
name: "Red Alarm",
genre: "Action / Shooter",
rarity: "Common",
desc: "A space combat simulator where you pilot a fighter through asteroid fields and enemy formations. The 3D depth makes dogfights feel visceral and immediate.",
art: "space"
},
{
name: "Wario Land",
genre: "Platformer",
rarity: "Common",
desc: "Wario's debut as a playable character in a 3D platformer. Treasure hunting through depth-oriented levels with unique 3D puzzles.",
art: "platformer"
},
{
name: "Teleroboxer",
genre: "Fighting / VR",
rarity: "Uncommon",
desc: "A boxing simulator that feels like an early VR experience. Punch through the screen with opponents that seem to leap from the display in true 3D.",
art: "boxing"
},
{
name: "Galactic Pinball",
genre: "Pinball",
rarity: "Uncommon",
desc: "A pinball machine that uses the Virtual Boy's 3D display to create depth in flippers, bumpers, and scoring zones. A technical showcase.",
art: "pinball"
},
{
name: "Vertical Force",
genre: "Shoot 'em up",
rarity: "Rare",
desc: "A vertical-scrolling shooter that uses the stereoscopic display to create layers of depth between enemy waves and foreground elements.",
art: "shooter"
}
];
function generateGameArt(canvas, type) {
const ctx = canvas.getContext('2d');
const w = canvas.width = 400;
const h = canvas.height = 200;
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = '#ff0000';
ctx.lineWidth = 1;
ctx.shadowColor = '#ff0000';
ctx.shadowBlur = 3;
switch(type) {
case 'tennis':
// Tennis court perspective
ctx.beginPath();
ctx.moveTo(50, 160);
ctx.lineTo(350, 160);
ctx.lineTo(300, 80);
ctx.lineTo(100, 80);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(200, 80);
ctx.lineTo(200, 160);
ctx.stroke();
// Ball
ctx.beginPath();
ctx.arc(220, 100, 6, 0, Math.PI * 2);
ctx.stroke();
// Depth lines
for(let i = 0; i < 5; i++) {
ctx.beginPath();
ctx.moveTo(100 + i*25, 80);
ctx.lineTo(50 + i*50, 160);
ctx.stroke();
}
break;
case 'space':
// Spaceship silhouette
ctx.beginPath();
ctx.moveTo(200, 30);
ctx.lineTo(170, 80);
ctx.lineTo(150, 120);
ctx.lineTo(200, 110);
ctx.lineTo(250, 120);
ctx.lineTo(230, 80);
ctx.closePath();
ctx.stroke();
// Stars
for(let i = 0; i < 20; i++) {
const x = Math.random() * w;
const y = Math.random() * h;
ctx.beginPath();
ctx.arc(x, y, Math.random() * 1.5, 0, Math.PI * 2);
ctx.stroke();
}
// Asteroids
for(let i = 0; i < 8; i++) {
ctx.beginPath();
const x = Math.random() * w;
const y = Math.random() * h;
const r = 3 + Math.random() * 8;
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.stroke();
}
break;
case 'platformer':
// Platforms
for(let i = 0; i < 6; i++) {
ctx.strokeRect(30 + i * 60, 140 - i * 15, 40, 4);
}
// Wario-like character
ctx.beginPath();
ctx.arc(100, 120, 10, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(95, 130);
ctx.lineTo(105, 130);
ctx.stroke();
// Coins
for(let i = 0; i < 4; i++) {
ctx.beginPath();
ctx.arc(60 + i * 60, 100 - i * 10, 5, 0, Math.PI * 2);
ctx.stroke();
}
break;
case 'boxing':
// Boxing ring
ctx.strokeRect(60, 60, 280, 120);
ctx.strokeRect(80, 70, 240, 100);
// Corner posts
ctx.beginPath();
ctx.moveTo(60, 60); ctx.lineTo(60, 50);
ctx.moveTo(340, 60); ctx.lineTo(340, 50);
ctx.stroke();
// Boxers
ctx.beginPath();
ctx.arc(150, 110, 12, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(145, 122); ctx.lineTo(155, 122);
ctx.lineTo(152, 140); ctx.lineTo(148, 140);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(250, 115, 12, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(245, 127); ctx.lineTo(255, 127);
ctx.lineTo(252, 145); ctx.lineTo(248, 145);
ctx.closePath();
ctx.stroke();
break;
case 'pinball':
// Pinball machine outline
ctx.beginPath();
ctx.moveTo(100, 180);
ctx.lineTo(150, 30);
ctx.lineTo(250, 30);
ctx.lineTo(300, 180);
ctx.stroke();
// Flipper area
ctx.strokeRect(130, 150, 140, 30);
// Bumpers
for(let i = 0; i < 5; i++) {
ctx.beginPath();
ctx.arc(160 + Math.random() * 80, 50 + i * 25, 6, 0, Math.PI * 2);
ctx.stroke();
}
// Ball
ctx.beginPath();
ctx.arc(200, 70, 4, 0, Math.PI * 2);
ctx.stroke();
break;
case 'shooter':
// Ship
ctx.beginPath();
ctx.moveTo(200, 150);
ctx.lineTo(180, 100);
ctx.lineTo(200, 80);
ctx.lineTo(220, 100);
ctx.closePath();
ctx.stroke();
// Enemies
for(let row = 0; row < 3; row++) {
for(let col = 0; col < 6; col++) {
ctx.strokeRect(100 + col * 35, 20 + row * 30, 20, 15);
ctx.beginPath();
ctx.moveTo(105 + col * 35, 35 + row * 30);
ctx.lineTo(110 + col * 35, 45 + row * 30);
ctx.moveTo(115 + col * 35, 35 + row * 30);
ctx.lineTo(115 + col * 35, 45 + row * 30);
ctx.stroke();
}
}
// Laser
ctx.beginPath();
ctx.moveTo(200, 80);
ctx.lineTo(200, 20);
ctx.stroke();
break;
}
// Scanline overlay
ctx.fillStyle = 'rgba(0,0,0,0.15)';
for(let y = 0; y < h; y += 3) {
ctx.fillRect(0, y, w, 1);
}
// Vignette
const grad = ctx.createRadialGradient(w/2, h/2, h*0.3, w/2, h/2, w*0.6);
grad.addColorStop(0, 'transparent');
grad.addColorStop(1, 'rgba(0,0,0,0.5)');
ctx.fillStyle = grad;
ctx.fillRect(0, 0, w, h);
}
const gamesGrid = document.getElementById('games-grid');
gamesData.forEach(game => {
const card = document.createElement('div');
card.className = 'game-card';
card.innerHTML = `
<div class="game-art"><canvas id="art-${game.name.replace(/'/g, '')}"></canvas></div>
<div class="game-info">
<div class="game-genre">${game.genre}</div>
<h3>${game.name}</h3>
<p>${game.desc}</p>
<div class="game-meta">
<span>Rarity:</span> ${game.rarity}
</div>
</div>
`;
gamesGrid.appendChild(card);
setTimeout(() => {
const c = document.getElementById(`art-${game.name.replace(/'/g, '')}`);
if (c) generateGameArt(c, game.art);
}, 100);
});
// ===== RED DISPLAY SIMULATION =====
(function() {
const canvas = document.getElementById('sim-canvas');
const ctx = canvas.getContext('2d');
const container = document.getElementById('sim-container');
const fpsDisplay = document.getElementById('sim-fps');
let w, h;
let time = 0;
let frameCount = 0;
let lastFpsTime = performance.now();
function resize() {
const rect = container.getBoundingClientRect();
w = canvas.width = rect.width * (window.devicePixelRatio > 1 ? 1 : 1);
h = canvas.height = rect.height * (window.devicePixelRatio > 1 ? 1 : 1);
}
resize();
window.addEventListener('resize', resize);
// Terrain grid
const gridSize = 30;
const gridSpacing = 12;
const offsetZ = 0;
function drawTerrain() {
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = '#ff0000';
ctx.shadowColor = '#ff0000';
ctx.shadowBlur = 2;
// Draw grid lines from vanishing point
const vanishX = w / 2;
const vanishY = h * 0.4;
for (let z = 0; z < gridSize; z++) {
const zNorm = z / gridSize;
const scale = 0.1 + zNorm * 1.5;
const yBase = vanishY + (h - vanishY) * zNorm;
for (let x = 0; x < 20; x++) {
const xNorm = x / 20;
const lx = vanishX + (xNorm - 0.5) * w * scale * 2;
const lx2 = vanishX + ((x + 1) / 20 - 0.5) * w * scale * 2;
const y2Base = vanishY + (h - vanishY) * ((z + 1) / gridSize);
// Height variation
const height = Math.sin(xNorm * 3 + time * 0.5) * Math.cos(zNorm * 2 + time * 0.3) * 20;
const height2 = Math.sin(((x + 1) / 20) * 3 + time * 0.5) * Math.cos(((z + 1) / gridSize) * 2 + time * 0.3) * 20;
const alpha = zNorm * 0.6 + 0.1;
ctx.strokeStyle = `rgba(255, 0, 0, ${alpha})`;
ctx.lineWidth = zNorm > 0.5 ? 0.5 : 0.3;
// Horizontal lines
ctx.beginPath();
ctx.moveTo(lx, yBase + height);
ctx.lineTo(lx2, yBase + height2);
ctx.stroke();
// Vertical lines
if (x < 19) {
const nextScale = 0.1 + ((z + 1) / gridSize) * 1.5;
const nx = vanishX + (xNorm - 0.5) * w * nextScale * 2;
const nx2 = vanishX + ((x + 1) / 20 - 0.5) * w * nextScale * 2;
const nyBase = vanishY + (h - vanishY) * ((z + 1) / gridSize);
ctx.beginPath();
ctx.moveTo(lx, yBase + height);
ctx.lineTo(nx, nyBase + height2);
ctx.stroke();
}
}
}
// Floating sprite - small alien/ship
const spriteX = w * 0.5 + Math.sin(time * 0.8) * w * 0.15;
const spriteY = h * 0.35 + Math.cos(time * 0.5) * h * 0.08;
const spriteSize = 12 + Math.sin(time * 2) * 3;
ctx.fillStyle = '#ff0000';
ctx.shadowBlur = 8;
ctx.beginPath();
ctx.moveTo(spriteX, spriteY - spriteSize);
ctx.lineTo(spriteX - spriteSize * 0.7, spriteY + spriteSize * 0.5);
ctx.lineTo(spriteX, spriteY + spriteSize * 0.2);
ctx.lineTo(spriteX + spriteSize * 0.7, spriteY + spriteSize * 0.5);
ctx.closePath();
ctx.fill();
// Engine glow
ctx.fillStyle = 'rgba(255, 100, 100, 0.4)';
ctx.beginPath();
ctx.arc(spriteX, spriteY + spriteSize * 0.6, 4, 0, Math.PI * 2);
ctx.fill();
// Depth indicators (parallax dots)
ctx.shadowBlur = 0;
for (let i = 0; i < 30; i++) {
const px = (Math.sin(i * 7.3 + time * 0.2) * 0.5 + 0.5) * w;
const py = (Math.cos(i * 3.7 + time * 0.15) * 0.5 + 0.5) * h * 0.35;
const size = 1 + Math.sin(i + time) * 0.5;
ctx.fillStyle = `rgba(255, 0, 0, ${0.1 + Math.sin(i * 2 + time) * 0.1})`;
ctx.fillRect(px, py, size, size);
}
// HUD elements
ctx.shadowBlur = 3;
ctx.fillStyle = '#ff0000';
ctx.font = '10px monospace';
ctx.fillText('DEPTH: 3D', 10, 20);
ctx.fillText(`T:${time.toFixed(1)}s`, 10, 35);
ctx.fillText(`Z:${(time * 2).toFixed(0)}`, w - 60, 20);
// Crosshair
ctx.strokeStyle = 'rgba(255, 0, 0, 0.4)';
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.arc(w / 2, h * 0.4, 15, 0, Math.PI * 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(w / 2 - 20, h * 0.4);
ctx.lineTo(w / 2 - 8, h * 0.4);
ctx.moveTo(w / 2 + 8, h * 0.4);
ctx.lineTo(w / 2 + 20, h * 0.4);
ctx.moveTo(w / 2, h * 0.4 - 20);
ctx.lineTo(w / 2, h * 0.4 - 8);
ctx.moveTo(w / 2, h * 0.4 + 8);
ctx.lineTo(w / 2, h * 0.4 + 20);
ctx.stroke();
}
function animate() {
time += 0.016;
frameCount++;
const now = performance.now();
if (now - lastFpsTime >= 1000) {
fpsDisplay.textContent = `${frameCount} FPS`;
frameCount = 0;
lastFpsTime = now;
}
drawTerrain();
requestAnimationFrame(animate);
}
animate();
})();
// ===== SMOOTH SCROLL FOR NAV LINKS =====
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nintendo Virtual Boy | Red Space Archive</title>
<style>
:root {
--black: #030303;
--dark: #0a0a0a;
--mid: #111111;
--gray: #1a1a1a;
--red: #ff0a0a;
--crimson: #dc143c;
--deep: #8b0000;
--bright: #ff1a1a;
--text: #e0e0e0;
--dim: #777;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
background: var(--black);
color: var(--text);
font-family: 'Courier New', Courier, monospace;
line-height: 1.6;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
/* Vignette */
body::before {
content: "";
position: fixed;
inset: 0;
background: radial-gradient(circle, transparent 40%, rgba(0,0,0,0.7) 100%);
pointer-events: none;
z-index: 9996;
}
/* Scanlines */
body::after {
content: "";
position: fixed;
inset: 0;
background: repeating-linear-gradient(0deg, rgba(0,0,0,0.12), rgba(0,0,0,0.12) 1px, transparent 1px, transparent 2px);
pointer-events: none;
z-index: 9995;
}
/* Noise */
.noise {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9994;
opacity: 0.04;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABZJREFUeNpi2r9//38gYGAEESAAEGAAasgJOgzOKCoAAAAASUVORK5CYII=');
}
/* Header */
header {
position: fixed;
top: 0; left: 0; right: 0;
padding: 1rem 2rem;
background: rgba(3,3,3,0.92);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--deep);
z-index: 1000;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
}
.logo {
font-size: 1.1rem;
font-weight: bold;
letter-spacing: 3px;
color: var(--red);
text-shadow: 0 0 8px var(--crimson);
text-transform: uppercase;
cursor: pointer;
transition: all 0.3s;
}
.logo:hover {
animation: glitch 0.3s infinite;
color: var(--bright);
}
nav ul {
display: flex;
list-style: none;
gap: 2rem;
flex-wrap: wrap;
}
nav a {
color: var(--text);
text-decoration: none;
font-size: 0.8rem;
letter-spacing: 1.5px;
text-transform: uppercase;
transition: all 0.3s;
position: relative;
}
nav a::after {
content: "";
position: absolute;
bottom: -4px; left: 0;
width: 0; height: 1px;
background: var(--red);
transition: width 0.3s;
}
nav a:hover { color: var(--red); text-shadow: 0 0 6px var(--crimson); }
nav a:hover::after { width: 100%; }
.cta-btn {
background: transparent;
border: 1px solid var(--red);
color: var(--red);
padding: 0.5rem 1.5rem;
font-family: inherit;
font-size: 0.8rem;
letter-spacing: 2px;
text-transform: uppercase;
cursor: pointer;
transition: all 0.3s;
position: relative;
overflow: hidden;
}
.cta-btn::before {
content: "";
position: absolute;
inset: 0;
background: var(--red);
transform: scaleX(0);
transform-origin: right;
transition: transform 0.3s;
z-index: -1;
}
.cta-btn:hover {
color: var(--black);
box-shadow: 0 0 25px var(--crimson);
}
.cta-btn:hover::before { transform: scaleX(1); transform-origin: left; }
.pulse { animation: pulse 2s infinite; }
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(255,10,10,0.4); }
70% { box-shadow: 0 0 0 12px rgba(255,10,10,0); }
100% { box-shadow: 0 0 0 0 rgba(255,10,10,0); }
}
/* Hero */
.hero {
position: relative;
height: 100vh;
min-height: 700px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
#heroCanvas {
position: absolute;
inset: 0;
width: 100%; height: 100%;
z-index: 1;
}
.hero-overlay {
position: relative;
z-index: 2;
text-align: center;
pointer-events: none;
padding: 0 1rem;
}
.hero-overlay h1 {
font-size: clamp(2.5rem, 8vw, 6rem);
letter-spacing: 0.3em;
margin-bottom: 1rem;
color: var(--red);
text-shadow: 0 0 40px var(--crimson), 0 0 80px var(--deep);
animation: flicker 5s infinite;
text-transform: uppercase;
}
.hero-overlay .tagline {
font-size: clamp(0.9rem, 2vw, 1.3rem);
color: var(--text);
letter-spacing: 0.3em;
margin-bottom: 2.5rem;
opacity: 0.85;
text-transform: uppercase;
}
.hero-buttons {
pointer-events: auto;
display: flex;
gap: 1.5rem;
justify-content: center;
flex-wrap: wrap;
}
.hero-buttons .cta-btn { padding: 0.9rem 2.5rem; font-size: 0.9rem; }
@keyframes flicker {
0%,100% { opacity: 1; }
92% { opacity: 1; }
93% { opacity: 0.7; }
94% { opacity: 1; }
96% { opacity: 0.85; }
97% { opacity: 1; }
}
@keyframes glitch {
0% { transform: translate(0); }
20% { transform: translate(-2px,2px); }
40% { transform: translate(-2px,-2px); }
60% { transform: translate(2px,2px); }
80% { transform: translate(2px,-2px); }
100% { transform: translate(0); }
}
/* Sections */
section {
padding: 7rem 2rem;
position: relative;
}
.container {
max-width: 1100px;
margin: 0 auto;
}
.section-title {
font-size: clamp(1.5rem, 4vw, 2.5rem);
color: var(--red);
margin-bottom: 3rem;
letter-spacing: 4px;
text-transform: uppercase;
border-bottom: 1px solid var(--deep);
padding-bottom: 1rem;
display: inline-block;
text-shadow: 0 0 10px rgba(220,20,60,0.3);
}
/* Hardware Story */
.hardware-story {
background: linear-gradient(180deg, var(--black) 0%, var(--dark) 100%);
}
.story-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
align-items: center;
}
.story-text p {
margin-bottom: 1.5rem;
font-size: 1.05rem;
line-height: 1.9;
color: #bbb;
}
.story-visual {
position: relative;
height: 420px;
background: var(--mid);
border: 1px solid var(--deep);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.wireframe-console {
width: 220px;
height: 320px;
border: 2px solid var(--red);
position: relative;
transform: perspective(600px) rotateY(-12deg) rotateX(5deg);
box-shadow: 0 0 30px var(--crimson), inset 0 0 20px rgba(255,0,0,0.1);
animation: consoleFloat 6s ease-in-out infinite;
}
.wireframe-console::before {
content: "";
position: absolute;
top: 25px; left: 25px; right: 25px; bottom: 25px;
border: 1px solid var(--red);
opacity: 0.6;
}
.wireframe-console::after {
content: "";
position: absolute;
top: 50%; left: 15%; width: 70%; height: 2px;
background: var(--red);
box-shadow: 0 0 15px var(--crimson);
}
@keyframes consoleFloat {
0%,100% { transform: perspective(600px) rotateY(-12deg) rotateX(5deg) translateY(0); }
50% { transform: perspective(600px) rotateY(-12deg) rotateX(5deg) translateY(-15px); }
}
/* Product Overview */
.product-overview { background: var(--black); }
.product-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.product-card {
background: var(--gray);
border: 1px solid #222;
padding: 2rem;
transition: all 0.4s;
position: relative;
overflow: hidden;
}
.product-card::before {
content: "";
position: absolute;
top: 0; left: 0; width: 100%; height: 2px;
background: var(--red);
transform: scaleX(0);
transform-origin: left;
transition: transform 0.4s;
}
.product-card:hover {
border-color: var(--crimson);
box-shadow: 0 0 35px rgba(220,20,60,0.15);
}
.product-card:hover::before { transform: scaleX(1); }
.product-icon { font-size: 2rem; margin-bottom: 1rem; color: var(--red); }
.product-card h3 { color: var(--text); margin-bottom: 0.5rem; font-size: 1.1rem; letter-spacing: 1px; }
.product-card p { color: var(--dim); font-size: 0.9rem; line-height: 1.6; }
/* Features */
.features {
background: var(--dark);
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1.5rem;
}
.feature-card {
background: var(--gray);
padding: 2rem;
border-left: 3px solid var(--red);
transition: all 0.3s;
}
.feature-card:hover {
background: #1f1f1f;
border-left-color: var(--bright);
box-shadow: inset 0 0 25px rgba(255,0,0,0.04);
}
.feature-card h4 {
color: var(--red);
margin-bottom: 0.8rem;
letter-spacing: 1.5px;
text-transform: uppercase;
font-size: 0.95rem;
}
.feature-card p { color: #999; font-size: 0.9rem; line-height: 1.6; }
/* Specs */
.specs { background: var(--black); }
.specs-table {
width: 100%;
border-collapse: collapse;
margin-top: 2rem;
}
.specs-table th, .specs-table td {
padding: 1.1rem 1.2rem;
text-align: left;
border-bottom: 1px solid #1a1a1a;
}
.specs-table th {
background: var(--gray);
color: var(--red);
letter-spacing: 2px;
font-weight: normal;
text-transform: uppercase;
font-size: 0.75rem;
width: 30%;
}
.specs-table tr:hover td { background: rgba(255,0,0,0.02); }
/* Games */
.games {
background: linear-gradient(180deg, var(--black) 0%, var(--dark) 50%, var(--black) 100%);
}
.games-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.game-card {
background: var(--gray);
border: 1px solid #222;
transition: all 0.4s;
cursor: pointer;
}
.game-card:hover {
transform: translateY(-6px);
box-shadow: 0 12px 35px rgba(0,0,0,0.6), 0 0 25px rgba(220,20,60,0.15);
border-color: var(--crimson);
}
.game-thumb {
height: 150px;
background: #000;
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid #222;
position: relative;
overflow: hidden;
}
.game-thumb svg { width: 75%; height: 75%; filter: drop-shadow(0 0 4px rgba(255,0,0,0.4)); }
.game-thumb::after {
content: "";
position: absolute;
inset: 0;
background: repeating-linear-gradient(0deg, rgba(0,0,0,0.25), rgba(0,0,0,0.25) 1px, transparent 1px, transparent 2px);
pointer-events: none;
}
.game-info { padding: 1.2rem; }
.game-info h4 { color: var(--red); font-size: 1rem; margin-bottom: 0.3rem; letter-spacing: 1px; }
.game-info .genre {
font-size: 0.7rem;
color: var(--dim);
text-transform: uppercase;
letter-spacing: 1.5px;
margin-bottom: 0.6rem;
display: block;
}
.game-info p { font-size: 0.85rem; color: #888; line-height: 1.5; }
.rarity-badge {
display: inline-block;
font-size: 0.7rem;
padding: 0.2rem 0.6rem;
background: var(--deep);
color: #fff;
margin-top: 0.6rem;
letter-spacing: 1px;
text-transform: uppercase;
}
/* Failed & Matters */
.failed-matters { background: var(--dark); }
.split-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
}
.split-column h3 {
color: var(--red);
margin-bottom: 1.5rem;
font-size: 1.4rem;
letter-spacing: 2px;
text-transform: uppercase;
}
.split-column p {
color: #aaa;
margin-bottom: 1.2rem;
line-height: 1.8;
font-size: 0.95rem;
}
.split-column .highlight {
color: var(--red);
font-weight: bold;
}
/* Timeline */
.timeline { background: var(--black); }
.timeline-container {
position: relative;
max-width: 900px;
margin: 0 auto;
}
.timeline-line {
position: absolute;
left: 50%;
top: 0; bottom: 0;
width: 2px;
background: var(--deep);
transform: translateX(-50%);
}
.timeline-item {
position: relative;
margin-bottom: 4rem;
width: 45%;
padding: 0 2rem;
}
.timeline-item:nth-child(odd) { left: 0; text-align: right; }
.timeline-item:nth-child(even) { left: 55%; }
.timeline-item::after {
content: "";
position: absolute;
top: 1.5rem;
width: 14px; height: 14px;
background: var(--red);
border-radius: 50%;
box-shadow: 0 0 12px var(--crimson);
}
.timeline-item:nth-child(odd)::after { right: -7px; }
.timeline-item:nth-child(even)::after { left: -7px; }
.timeline-year {
color: var(--red);
font-size: 1.6rem;
font-weight: bold;
margin-bottom: 0.5rem;
letter-spacing: 2px;
}
.timeline-content {
background: var(--gray);
padding: 1.5rem;
border: 1px solid #1a1a1a;
transition: all 0.3s;
}
.timeline-content:hover {
border-color: var(--crimson);
box-shadow: 0 0 20px rgba(220,20,60,0.1);
}
.timeline-content h4 { color: var(--text); margin-bottom: 0.5rem; font-size: 1rem; }
.timeline-content p { color: #999; font-size: 0.85rem; line-height: 1.6; }
/* Visual Experience */
.visual-experience {
background: #000;
padding: 6rem 2rem;
text-align: center;
}
.vb-screen-wrapper {
display: inline-block;
padding: 25px;
background: #0a0a0a;
border: 2px solid #222;
border-radius: 12px;
box-shadow: 0 0 60px rgba(220,20,60,0.2), 0 20px 40px rgba(0,0,0,0.8);
position: relative;
}
.vb-screen {
width: 320px;
height: 240px;
background: #000;
border: 3px solid var(--deep);
position: relative;
overflow: hidden;
}
#vbCanvas { width: 100%; height: 100%; display: block; }
.scanlines-overlay {
position: absolute;
inset: 0;
background: repeating-linear-gradient(0deg, rgba(0,0,0,0.3), rgba(0,0,0,0.3) 1px, transparent 1px, transparent 2px);
pointer-events: none;
animation: scanlineScroll 0.08s linear infinite;
}
@keyframes scanlineScroll {
0% { background-position: 0 0; }
100% { background-position: 0 2px; }
}
.screen-label {
margin-top: 1rem;
color: var(--dim);
font-size: 0.75rem;
letter-spacing: 3px;
text-transform: uppercase;
}
/* Collector Market */
.collector-market { background: var(--dark); }
.market-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.market-card {
background: var(--gray);
border: 1px solid #222;
padding: 2rem;
position: relative;
transition: all 0.3s;
}
.market-card:hover {
border-color: var(--crimson);
box-shadow: 0 0 30px rgba(220,20,60,0.1);
}
.market-card .condition {
position: absolute;
top: 1rem; right: 1rem;
font-size: 0.7rem;
padding: 0.2rem 0.6rem;
border: 1px solid var(--dim);
color: var(--dim);
letter-spacing: 1px;
text-transform: uppercase;
}
.market-card h4 { color: var(--text); margin-bottom: 0.5rem; font-size: 1.05rem; }
.market-card .price {
color: var(--red);
font-size: 1.6rem;
font-weight: bold;
margin: 0.5rem 0;
text-shadow: 0 0 10px var(--crimson);
}
.market-card .rarity { color: var(--dim); font-size: 0.85rem; margin-bottom: 1rem; text-transform: uppercase; letter-spacing: 1px; }
.market-card p { color: #888; font-size: 0.9rem; line-height: 1.5; }
/* Comparison */
.comparison { background: var(--black); }
.comparison-table {
width: 100%;
border-collapse: collapse;
margin-top: 2rem;
font-size: 0.9rem;
}
.comparison-table th, .comparison-table td {
padding: 1rem;
text-align: center;
border: 1px solid #1a1a1a;
}
.comparison-table th {
background: var(--gray);
color: var(--red);
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.7rem;
}
.comparison-table td:first-child {
text-align: left;
color: var(--text);
font-weight: bold;
}
.comparison-table tr:hover td { background: rgba(255,0,0,0.02); }
/* Quote */
.quote {
background: linear-gradient(180deg, var(--black) 0%, var(--gray) 100%);
text-align: center;
padding: 8rem 2rem;
}
.quote blockquote {
font-size: clamp(1.2rem, 3vw, 1.8rem);
color: var(--text);
max-width: 800px;
margin: 0 auto;
line-height: 1.5;
font-style: italic;
border-left: 3px solid var(--red);
padding-left: 2rem;
text-align: left;
}
.quote cite {
display: block;
margin-top: 1.5rem;
color: var(--dim);
font-style: normal;
letter-spacing: 2px;
font-size: 0.85rem;
text-transform: uppercase;
}
/* Footer */
footer {
background: var(--black);
border-top: 1px solid var(--deep);
padding: 4rem 2rem 2rem;
}
.footer-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 3rem;
max-width: 1100px;
margin: 0 auto;
}
.footer-col h5 {
color: var(--red);
margin-bottom: 1rem;
letter-spacing: 2px;
font-size: 0.8rem;
text-transform: uppercase;
}
.footer-col ul { list-style: none; }
.footer-col ul li { margin-bottom: 0.6rem; }
.footer-col a {
color: var(--dim);
text-decoration: none;
font-size: 0.85rem;
transition: color 0.3s;
}
.footer-col a:hover { color: var(--red); }
.footer-bottom {
max-width: 1100px;
margin: 3rem auto 0;
padding-top: 2rem;
border-top: 1px solid #1a1a1a;
text-align: center;
color: #444;
font-size: 0.75rem;
letter-spacing: 1px;
}
/* Scroll Animations */
.fade-in {
opacity: 0;
transform: translateY(40px);
transition: opacity 0.9s ease, transform 0.9s ease;
}
.fade-in.visible { opacity: 1; transform: translateY(0); }
.fade-in-delay-1 { transition-delay: 0.1s; }
.fade-in-delay-2 { transition-delay: 0.2s; }
.fade-in-delay-3 { transition-delay: 0.3s; }
/* Responsive */
@media (max-width: 768px) {
header { padding: 0.8rem 1rem; }
nav ul { gap: 1rem; }
.story-grid, .split-layout { grid-template-columns: 1fr; gap: 2rem; }
.timeline-item { width: 100%; left: 0 !important; text-align: left !important; padding-left: 2.5rem; }
.timeline-item::after { left: 6px !important; }
.timeline-line { left: 12px; }
.comparison-table { font-size: 0.75rem; }
.comparison-table th, .comparison-table td { padding: 0.6rem; }
}
</style>
</head>
<body>
<div class="noise"></div>
<header>
<div class="logo">Red Space // Archive</div>
<nav>
<ul>
<li><a href="#hardware-story">Hardware</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#games">Games</a></li>
<li><a href="#timeline">Timeline</a></li>
<li><a href="#collector-market">Collect</a></li>
</ul>
</nav>
<button class="cta-btn pulse" onclick="document.getElementById('visual-experience').scrollIntoView({behavior:'smooth'})">Enter Red Space</button>
</header>
<section class="hero" id="hero">
<canvas id="heroCanvas"></canvas>
<div class="hero-overlay">
<h1 class="fade-in">Virtual Boy</h1>
<p class="tagline fade-in fade-in-delay-1">The Failed Dream of Stereoscopic 3D</p>
<div class="hero-buttons fade-in fade-in-delay-2">
<button class="cta-btn" onclick="document.getElementById('hardware-story').scrollIntoView({behavior:'smooth'})">Explore the Hardware</button>
<button class="cta-btn pulse" onclick="document.getElementById('visual-experience').scrollIntoView({behavior:'smooth'})">Enter Red Space</button>
</div>
</div>
</section>
<section class="hardware-story" id="hardware-story">
<div class="container">
<h2 class="section-title fade-in">Hardware Story</h2>
<div class="story-grid">
<div class="story-text fade-in fade-in-delay-1">
<p>In 1995, Nintendo unveiled a device that defied every convention of its era. The Virtual Boy was not a handheld. It was not a home console. It was a tabletop stereoscopic visor that promised to transport players into a world of red-lit 3D space.</p>
<p>Conceived by Gunpei Yokoi, the legendary mind behind the Game Boy, it was an audacious experiment born from a desire to push gaming into the third dimension. The hardware was striking, unsettling, and utterly unique—a black monolith with a red glowing visor, perched on a table like some artifact from a parallel timeline where gaming evolved along a stranger, more experimental path.</p>
<p>It required a stable surface, a power outlet, and a willingness to sit in a darkened room and stare into the abyss of Nintendo's most ambitious misstep. For those who did, it offered an experience unlike anything else in the 16-bit era.</p>
</div>
<div class="story-visual fade-in fade-in-delay-2">
<div class="wireframe-console"></div>
</div>
</div>
</div>
</section>
<section class="product-overview" id="product-overview">
<div class="container">
<h2 class="section-title fade-in">Collector Reintroduction</h2>
<p class="fade-in" style="color:#aaa; max-width:700px; margin-bottom:2rem; line-height:1.8;">
The Virtual Boy Tabletop System. A collector's masterpiece of experimental design. Featuring a stereoscopic red LED display, a dual-grip controller with 360-degree control, and a sturdy tabletop stand. Each unit is a testament to an era when gaming dared to be different.
</p>
<div class="product-grid">
<div class="product-card fade-in">
<div class="product-icon"></div>
<h3>Visor Unit</h3>
<p>The stereoscopic display headset. A single red LED panel per eye creates a stark, immersive field of view. The adjustable headrest ensures proper positioning for depth perception.</p>
</div>
<div class="product-card fade-in fade-in-delay-1">
<div class="product-icon"></div>
<h3>Tabletop Stand</h3>
<p>A sturdy, articulated stand that anchors the visor to any flat surface. Designed for stability during intense sessions of 3D gameplay.</p>
</div>
<div class="product-card fade-in fade-in-delay-2">
<div class="product-icon"></div>
<h3>Dual-Grip Controller</h3>
<p>An unconventional controller with two independent grips, a directional pad, A/B buttons, and shoulder triggers. Ergonomic and strange in equal measure.</p>
</div>
<div class="product-card fade-in">
<div class="product-icon"></div>
<h3>Cartridge Slot</h3>
<p>Accepts 16 MB ROM cartridges with red-tinted labels. A library of 22 unique titles, each a compact experiment in stereoscopic design.</p>
</div>
</div>
</div>
</section>
<section class="features" id="features">
<div class="container">
<h2 class="section-title fade-in">Core Features</h2>
<div class="features-grid">
<div class="feature-card fade-in">
<h4>Red Monochrome Display</h4>
<p>A single-color LED matrix creating a stark, immersive visual experience. The red glow defines the Virtual Boy aesthetic—harsh, hypnotic, and unmistakable.</p>
</div>
<div class="feature-card fade-in fade-in-delay-1">
<h4>Stereoscopic 3D Gameplay</h4>
<p>Dual screens project slightly offset images, creating a genuine sense of depth without glasses. A technical marvel ahead of its commercial timeline.</p>
</div>
<div class="feature-card fade-in fade-in-delay-2">
<h4>Tabletop Headset Design</h4>
<p>Designed for stable surfaces. The visor-like form factor places you at the center of the action, isolating you from the world around you.</p>
</div>
<div class="feature-card fade-in">
<h4>Unique Dual-Grip Controller</h4>
<p>A controller with two independent grips, offering unprecedented control over gameplay. Unconventional, challenging, and ultimately iconic.</p>
</div>
<div class="feature-card fade-in fade-in-delay-1">
<h4>Cartridge-Based Library</h4>
<p>A small but dedicated library of 22 games, each a unique experiment in 3D design. From sports to pinball, every title pushes the hardware's limits.</p>
</div>
<div class="feature-card fade-in fade-in-delay-2">
<h4>Portable, Yet Stationary</h4>
<p>Compact enough to move, but built for the living room tabletop. A hybrid form factor that confused consumers and delighted enthusiasts.</p>
</div>
<div class="feature-card fade-in">
<h4>Experimental 1990s VR</h4>
<p>One of the earliest attempts at consumer virtual reality, predating modern headsets by decades. A bold leap into immersive play.</p>
</div>
<div class="feature-card fade-in fade-in-delay-1">
<h4>Ultimate Collector Rarity</h4>
<p>With fewer than 1 million units sold, complete systems are highly sought after. A true grail item for retro gaming archivists.</p>
</div>
</div>
</div>
</section>
<section class="specs" id="specs">
<div class="container">
<h2 class="section-title fade-in">Technical Specifications</h2>
<table class="specs-table fade-in">
<tr><th>Display</th><td>256×224 pixels per eye; red monochrome LED; 60 Hz refresh</td></tr>
<tr><th>Processor</th><td>NEC V810 RISC microprocessor @ 20 MHz</td></tr>
<tr><th>Controller</th><td>Dual-grip with directional pad, A/B, Start/Select, two shoulder buttons</td></tr>
<tr><th>Game Format</th><td>16 MB ROM cartridges; proprietary form factor</td></tr>
<tr><th>Release Era</th><td>July 1995 (Japan); August 1995 (North America)</td></tr>
<tr><th>Visual Style</th><td>Wireframe polygons, parallax scrolling, stereoscopic depth layers</td></tr>
<tr><th>Power Source</th><td>AC adapter (included) or 6 × AA batteries (not recommended)</td></tr>
<tr><th>Player Mode</th><td>Single-player; link cable support for select titles</td></tr>
<tr><th>Collector Status</th><td>Rare; complete-in-box units command premium prices among enthusiasts</td></tr>
<tr><th>Units Sold</th><td>Approximately 770,000 worldwide</td></tr>
</table>
</div>
</section>
<section class="games" id="games">
<div class="container">
<h2 class="section-title fade-in">Games Library</h2>
<div class="games-grid">
<div class="game-card fade-in">
<div class="game-thumb">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect x="15" y="45" width="18" height="28" fill="none" stroke="#ff0000" stroke-width="2"/>
<rect x="67" y="45" width="18" height="28" fill="none" stroke="#ff0000" stroke-width="2"/>
<circle cx="50" cy="55" r="6" fill="none" stroke="#ff0000" stroke-width="2"/>
<line x1="33" y1="58" x2="67" y2="58" stroke="#ff0000" stroke-width="1"/>
</svg>
</div>
<div class="game-info">
<h4>Mario's Tennis</h4>
<span class="genre">Sports</span>
<p>A fast-paced tennis simulation featuring Mario and friends. Showcased the system's 3D depth with overhead court perspectives.</p>
<span class="rarity-badge">Common</span>
</div>
</div>
<div class="game-card fade-in fade-in-delay-1">
<div class="game-thumb">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="38" fill="none" stroke="#ff0000" stroke-width="2"/>
<line x1="50" y1="50" x2="50" y2="12" stroke="#ff0000" stroke-width="2"/>
<line x1="50" y1="50" x2="82" y2="35" stroke="#ff0000" stroke-width="1" opacity="0.6"/>
<circle cx="50" cy="50" r="3" fill="#ff0000"/>
</svg>
</div>
<div class="game-info">
<h4>Red Alarm</h4>
<span class="genre">Rail Shooter</span>
<p>A wireframe space shooter that used the 3D display to create a sense of breakneck speed and spatial awareness.</p>
<span class="rarity-badge">Uncommon</span>
</div>
</div>
<div class="game-card fade-in fade-in-delay-2">
<div class="game-thumb">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect x="30" y="30" width="40" height="40" fill="none" stroke="#ff0000" stroke-width="2" transform="rotate(45 50 50)"/>
<rect x="42" y="42" width="16" height="16" fill="#ff0000" transform="rotate(45 50 50)"/>
</svg>
</div>
<div class="game-info">
<h4>Wario Land</h4>
<span class="genre">Platformer</span>
<p>The mischievous Wario stars in a challenging platformer that uses 3D perspective for puzzles and exploration.</p>
<span class="rarity-badge">Rare</span>
</div>
</div>
<div class="game-card fade-in">
<div class="game-thumb">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="35" cy="55" r="14" fill="none" stroke="#ff0000" stroke-width="2"/>
<circle cx="65" cy="55" r="14" fill="none" stroke="#ff0000" stroke-width="2"/>
<line x1="22" y1="55" x2="78" y2="55" stroke="#ff0000" stroke-width="2"/>
<line x1="35" y1="41" x2="35" y2="25" stroke="#ff0000" stroke-width="1.5"/>
<line x1="65" y1="41" x2="65" y2="25" stroke="#ff0000" stroke-width="1.5"/>
</svg>
</div>
<div class="game-info">
<h4>Teleroboxer</h4>
<span class="genre">Fighting / Boxing</span>
<p>A futuristic boxing game requiring quick reflexes. The dual-grip controller became essential for landing combos.</p>
<span class="rarity-badge">Uncommon</span>
</div>
</div>
<div class="game-card fade-in fade-in-delay-1">
<div class="game-thumb">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="10" fill="none" stroke="#ff0000" stroke-width="2"/>
<line x1="20" y1="22" x2="32" y2="32" stroke="#ff0000" stroke-width="3" stroke-linecap="round"/>
<line x1="80" y1="22" x2="68" y2="32" stroke="#ff0000" stroke-width="3" stroke-linecap="round"/>
<line x1="50" y1="75" x2="50" y2="85" stroke="#ff0000" stroke-width="2"/>
</svg>
</div>
<div class="game-info">
<h4>Galactic Pinball</h4>
<span class="genre">Pinball Simulation</span>
<p>Space-themed pinball with multiple tables and physics-based gameplay. A cult favorite for its addictive simplicity.</p>
<span class="rarity-badge">Common</span>
</div>
</div>
<div class="game-card fade-in fade-in-delay-2">
<div class="game-thumb">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<polygon points="50,12 88,88 12,88" fill="none" stroke="#ff0000" stroke-width="2"/>
<line x1="50" y1="12" x2="50" y2="88" stroke="#ff0000" stroke-width="1"/>
<line x1="50" y1="50" x2="88" y2="88" stroke="#ff0000" stroke-width="1"/>
<line x1="50" y1="50" x2="12" y2="88" stroke="#ff0000" stroke-width="1"/>
</svg>
</div>
<div class="game-info">
<h4>Vertical Force</h4>
<span class="genre">Vertical Shooter</span>
<p>A vertical-scrolling shooter that placed players in the cockpit of a starfighter. Intense action in a minimalist red void.</p>
<span class="rarity-badge">Rare</span>
</div>
</div>
</div>
</div>
</section>
<section class="failed-matters" id="failed-matters">
<div class="container">
<h2 class="section-title fade-in">Why It Failed, Why It Matters</h2>
<div class="split-layout">
<div class="split-column fade-in">
<h3>The Commercial Collapse</h3>
<p>The Virtual Boy was plagued by discomfort, limited software, and a price point that placed it in a no-man's-land between handheld and home console. Its monochrome display, while technically impressive for its time, lacked the color and vibrancy that defined 16-bit gaming.</p>
<p>Players reported headaches and eye strain from prolonged sessions. The market simply wasn't ready for tabletop VR. Within months of its 1995 launch, it was discontinued, leaving behind a small library of fascinating, if flawed, games and a legacy of commercial disappointment.</p>
</div>
<div class="split-column fade-in fade-in-delay-1">
<h3>The Enduring Legacy</h3>
<p>Yet the Virtual Boy's legacy is not one of failure, but of <span class="highlight">fearless experimentation</span>. It was an early attempt at consumer virtual reality, a bold leap into stereoscopic 3D that wouldn't be meaningfully matched for decades.</p>
<p>Its industrial design—angular, menacing, and unmistakably futuristic—remains one of the most distinctive in gaming history. For collectors, it represents the holy grail of obscure hardware: a rare, misunderstood artifact that embodies the spirit of innovation, even when it doesn't succeed.</p>
</div>
</div>
</div>
</section>
<section class="timeline" id="timeline">
<div class="container">
<h2 class="section-title fade-in">System Timeline</h2>
<div class="timeline-container">
<div class="timeline-line"></div>
<div class="timeline-item fade-in">
<div class="timeline-year">1994</div>
<div class="timeline-content">
<h4>Concept Development</h4>
<p>Gunpei Yokoi's team at Nintendo R&D1 begins prototyping a stereoscopic gaming device. The goal: bring 3D graphics to the consumer market without glasses.</p>
</div>
</div>
<div class="timeline-item fade-in fade-in-delay-1">
<div class="timeline-year">1995</div>
<div class="timeline-content">
<h4>Global Launch</h4>
<p>Virtual Boy debuts in Japan and North America with a $179.95 price tag. Initial press coverage is intense, but consumer confusion sets in early.</p>
</div>
</div>
<div class="timeline-item fade-in">
<div class="timeline-year">1995</div>
<div class="timeline-content">
<h4>Market Retreat</h4>
<p>Reports of discomfort and limited software library lead to declining sales. Nintendo announces a steep price drop and halts production within the same year.</p>
</div>
</div>
<div class="timeline-item fade-in fade-in-delay-1">
<div class="timeline-year">1996</div>
<div class="timeline-content">
<h4>Discontinuation</h4>
<p>Official discontinuation after less than a year on the market. Fewer than 1 million units sold worldwide. A quiet end to a loud experiment.</p>
</div>
</div>
<div class="timeline-item fade-in">
<div class="timeline-year">2000s</div>
<div class="timeline-content">
<h4>Cult Following Emerges</h4>
<p>Retro gaming communities begin to re-evaluate the Virtual Boy. Enthusiasts celebrate its bold design, and game prices start to climb among collectors.</p>
</div>
</div>
<div class="timeline-item fade-in fade-in-delay-1">
<div class="timeline-year">2010s–Present</div>
<div class="timeline-content">
<h4>Rediscovered Artifact</h4>
<p>The Virtual Boy is recognized as a fascinating piece of gaming history—a failed ambition that remains more interesting than many successes. Prices soar; the legend grows.</p>
</div>
</div>
</div>
</div>
</section>
<section class="visual-experience" id="visual-experience">
<div class="container">
<h2 class="section-title fade-in">Live the Red Space</h2>
<p class="fade-in" style="color:#888; letter-spacing:2px; text-transform:uppercase; margin-bottom:2rem;">A simulation of the Virtual Boy display</p>
<div class="vb-screen-wrapper fade-in">
<div class="vb-screen">
<canvas id="vbCanvas" width="320" height="240"></canvas>
<div class="scanlines-overlay"></div>
</div>
</div>
<p class="screen-label fade-in">Monochrome Stereoscopic Simulation // Active</p>
</div>
</section>
<section class="collector-market" id="collector-market">
<div class="container">
<h2 class="section-title fade-in">Collector Market</h2>
<div class="market-grid">
<div class="market-card fade-in">
<span class="condition">Loose</span>
<h4>Console Only</h4>
<div class="price">$80 – $150</div>
<div class="rarity">Common</div>
<p>Headset unit without controller, stand, or accessories. Functional but incomplete. A starting point for restoration projects.</p>
</div>
<div class="market-card fade-in fade-in-delay-1">
<span class="condition">CIB</span>
<h4>Complete in Box</h4>
<div class="price">$300 – $600</div>
<div class="rarity">Uncommon</div>
<p>Includes headset, controller, stand, original box, and manual. The standard for serious collectors. Condition heavily influences value.</p>
</div>
<div class="market-card fade-in fade-in-delay-2">
<span class="condition">Sealed</span>
<h4>Factory Sealed Game</h4>
<div class="price">$200 – $400</div>
<div class="rarity">Rare</div>
<p>Unopened cartridge in original packaging. Varies significantly by title; Mario's Tennis and Wario Land command premium sealed prices.</p>
</div>
<div class="market-card fade-in">
<span class="condition">Parts</span>
<h4>Controller Only</h4>
<div class="price">$40 – $80</div>
<div class="rarity">Uncommon</div>
<p>Rarely sold separately; essential for a fully functional setup. Wear on grips and button membranes affects pricing.</p>
</div>
<div class="market-card fade-in fade-in-delay-1">
<span class="condition">Bundle</span>
<h4>Full Collector Bundle</h4>
<div class="price">$1,200 – $2,500</div>
<div class="rarity">Very Rare</div>
<p>CIB system, multiple games, original accessories, and often exceptional condition. The pinnacle of Virtual Boy preservation.</p>
</div>
</div>
</div>
</section>
<section class="comparison" id="comparison">
<div class="container">
<h2 class="section-title fade-in">Comparative Analysis</h2>
<div style="overflow-x:auto;">
<table class="comparison-table fade-in">
<tr>
<th>Category</th>
<th>Nintendo Virtual Boy</th>
<th>Nintendo Game Boy</th>
<th>Super Nintendo</th>
<th>Arcade Cabinet</th>
<th>Modern VR Headset</th>
</tr>
<tr>
<td>Era</td>
<td>1995</td>
<td>1989</td>
<td>1990</td>
<td>1980s–90s</td>
<td>2010s–Present</td>
</tr>
<tr>
<td>Display</td>
<td>Red monochrome stereoscopic LED</td>
<td>Grayscale LCD</td>
<td>RGB CRT</td>
<td>RGB CRT</td>
<td>RGB OLED</td>
</tr>
<tr>
<td>Portability</td>
<td>Semi-portable (tabletop)</td>
<td>Fully handheld</td>
<td>Home console</td>
<td>Fixed location</td>
<td>Standalone wireless</td>
</tr>
<tr>
<td>3D Support</td>
<td>Yes (stereoscopic, no glasses)</td>
<td>No</td>
<td>No</td>
<td>Limited (some games)</td>
<td>Yes (6DoF tracking)</td>
</tr>
<tr>
<td>Comfort</td>
<td>Moderate (reported strain)</td>
<td>High</td>
<td>High</td>
<td>Moderate</td>
<td>Moderate–High</td>
</tr>
<tr>
<td>Game Library</td>
<td>22 titles</td>
<td>1000+ titles</td>
<td>700+ titles</td>
<td>Thousands</td>
<td>Growing rapidly</td>
</tr>
<tr>
<td>Legacy</td>
<td>Cult classic, experimental</td>
<td>Iconic handheld</td>
<td>Golden age console</td>
<td>Foundation of gaming</td>
<td>Emerging platform</td>
</tr>
<tr>
<td>Collector Appeal</td>
<td>Very High</td>
<td>High</td>
<td>High</td>
<td>Medium</td>
<td>Low–Medium</td>
</tr>
</table>
</div>
</div>
</section>
<section class="quote">
<div class="container">
<blockquote class="fade-in">
"A machine that dreamed of the future but was trapped in the red haze of 1995. It wasn't a failure—it was a prototype for a world that wasn't ready."
</blockquote>
<cite class="fade-in fade-in-delay-1">— Red Space Archive Editorial</cite>
</div>
</section>
<footer>
<div class="footer-grid">
<div class="footer-col">
<h5>Archive</h5>
<ul>
<li><a href="#hero">Home</a></li>
<li><a href="#hardware-story">Hardware</a></li>
<li><a href="#games">Games</a></li>
<li><a href="#timeline">Timeline</a></li>
<li><a href="#specs">Specifications</a></li>
</ul>
</div>
<div class="footer-col">
<h5>Collector</h5>
<ul>
<li><a href="#collector-market">Market Guide</a></li>
<li><a href="#collector-market">Price Tracker</a></li>
<li><a href="#collector-market">Condition Grading</a></li>
<li><a href="#collector-market">Auction Listings</a></li>
</ul>
</div>
<div class="footer-col">
<h5>Connect</h5>
<ul>
<li><a href="#">Newsletter</a></li>
<li><a href="#">Retro Forums</a></li>
<li><a href="#">Discord Community</a></li>
<li><a href="#">Social Archive</a></li>
</ul>
</div>
<div class="footer-col">
<h5>Legal</h5>
<ul>
<li><a href="#">Privacy Policy</a></li>
<li><a href="#">Terms of Use</a></li>
<li><a href="#">Disclaimer</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>
</div>
<div class="footer-bottom">
© 2024 Red Space Archive. An independent collector resource. Not affiliated with Nintendo. All trademarks property of their respective owners.
</div>
</footer>
<script>
/* ─── Hero 3D Engine ─── */
const heroCanvas = document.getElementById('heroCanvas');
const heroCtx = heroCanvas.getContext('2d');
let W, H;
let mouseX = 0, mouseY = 0;
let smoothMouseX = 0, smoothMouseY = 0;
function resizeHero() {
W = heroCanvas.width = window.innerWidth;
H = heroCanvas.height = window.innerHeight;
}
window.addEventListener('resize', resizeHero);
resizeHero();
document.addEventListener('mousemove', e => {
mouseX = (e.clientX / W - 0.5) * 2;
mouseY = (e.clientY / H - 0.5) * 2;
});
function project(x, y, z) {
const fov = 600;
const scale = fov / (fov + z);
return { x: x * scale + W / 2, y: y * scale + H / 2, scale };
}
function rotateX(p, a) {
const c = Math.cos(a), s = Math.sin(a);
return { x: p.x, y: p.y * c - p.z * s, z: p.y * s + p.z * c };
}
function rotateY(p, a) {
const c = Math.cos(a), s = Math.sin(a);
return { x: p.x * c + p.z * s, y: p.y, z: -p.x * s + p.z * c };
}
// Wireframe headset model
const headset = {
body: [
{x:-80,y:-50,z:0},{x:80,y:-50,z:0},{x:80,y:50,z:0},{x:-80,y:50,z:0},
{x:-80,y:-50,z:100},{x:80,y:-50,z:100},{x:80,y:50,z:100},{x:-80,y:50,z:100}
],
edges: [[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]]
};
const visor = {
body: [
{x:-60,y:-28,z:-25},{x:60,y:-28,z:-25},{x:60,y:28,z:-25},{x:-60,y:28,z:-25},
{x:-60,y:-28,z:8},{x:60,y:-28,z:8},{x:60,y:28,z:8},{x:-60,y:28,z:8}
],
edges: [[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]]
};
const eyes = {
body: [
{x:-25,y:-10,z:-26},{x:25,y:-10,z:-26},{x:25,y:10,z:-26},{x:-25,y:10,z:-26},
{x:-25,y:-10,z:-24},{x:25,y:-10,z:-24},{x:25,y:10,z:-24},{x:-25,y:10,z:-24}
],
edges: [[0,1],[2,3],[4,5],[6,7],[0,4],[1,5],[2,6],[3,7]]
};
const stand = {
body: [
{x:-45,y:0,z:0},{x:45,y:0,z:0},{x:45,y:0,z:100},{x:-45,y:0,z:100}
],
edges: [[0,1],[1,2],[2,3],[3,0]]
};
const cartridges = [];
for(let i=0;i<6;i++){
cartridges.push({
x: (Math.random()-0.5)*500,
y: (Math.random()-0.5)*300,
z: -150 - Math.random()*400,
size: 15 + Math.random()*20
});
}
const particles = [];
for(let i=0;i<120;i++){
particles.push({
x: (Math.random()-0.5)*900,
y: (Math.random()-0.5)*700,
z: Math.random()*700,
size: Math.random()*2+0.5
});
}
const gridLines = [];
const gridSpacing = 50;
const gridExtent = 25;
for(let i=-gridExtent;i<=gridExtent;i++){
gridLines.push({x1:i*gridSpacing,z1:-gridExtent*gridSpacing,x2:i*gridSpacing,z2:gridExtent*gridSpacing});
gridLines.push({x1:-gridExtent*gridSpacing,z1:i*gridSpacing,x2:gridExtent*gridSpacing,z2:i*gridSpacing});
}
let time = 0;
function drawLine(p1, p2, color, w) {
heroCtx.strokeStyle = color;
heroCtx.lineWidth = w;
heroCtx.beginPath();
heroCtx.moveTo(p1.x, p1.y);
heroCtx.lineTo(p2.x, p2.y);
heroCtx.stroke();
}
function renderHero() {
time += 0.008;
smoothMouseX += (mouseX - smoothMouseX) * 0.04;
smoothMouseY += (mouseY - smoothMouseY) * 0.04;
heroCtx.clearRect(0, 0, W, H);
// Background
const grad = heroCtx.createRadialGradient(W/2, H/2, 0, W/2, H/2, W);
grad.addColorStop(0, '#150000');
grad.addColorStop(1, '#000000');
heroCtx.fillStyle = grad;
heroCtx.fillRect(0, 0, W, H);
const rotY = smoothMouseX * 0.6;
const rotX = smoothMouseY * 0.4;
// Grid
gridLines.forEach(line => {
let p1 = rotateY({x:line.x1,y:180,z:line.z1}, rotY);
let p2 = rotateY({x:line.x2,y:180,z:line.z2}, rotY);
p1 = rotateX(p1, rotX);
p2 = rotateX(p2, rotX);
const proj1 = project(p1.x, p1.y, p1.z);
const proj2 = project(p2.x, p2.y, p2.z);
if(proj1.scale>0 && proj2.scale>0){
const avgZ = (p1.z+p2.z)/2;
const alpha = Math.max(0.05, 0.3 - avgZ/800);
heroCtx.strokeStyle = `rgba(139,0,0,${alpha})`;
heroCtx.lineWidth = 0.8;
heroCtx.beginPath();
heroCtx.moveTo(proj1.x, proj1.y);
heroCtx.lineTo(proj2.x, proj2.y);
heroCtx.stroke();
}
});
function drawObj(obj, color, lineW) {
const projected = [];
obj.body.forEach(p => {
let rp = rotateY({x:p.x,y:p.y,z:p.z}, rotY + time*0.15);
rp = rotateX(rp, rotX + Math.sin(time)*0.08);
rp.y += Math.sin(time*1.8)*12;
rp.z += Math.cos(time*1.3)*25;
projected.push(project(rp.x, rp.y, rp.z));
});
obj.edges.forEach(edge => {
const p1 = projected[edge[0]];
const p2 = projected[edge[1]];
if(p1.scale>0 && p2.scale>0) drawLine(p1, p2, color, lineW);
});
}
drawObj(headset, '#ff0a0a', 1.8);
drawObj(visor, '#ff3333', 1.2);
drawObj(eyes, '#ff0000', 1);
drawObj(stand, '#8b0000', 1.5);
// Cartridges
cartridges.forEach(c => {
let rp = rotateY({x:c.x,y:c.y,z:c.z}, rotY);
rp = rotateX(rp, rotX);
const proj = project(rp.x, rp.y, rp.z);
if(proj.scale>0){
const s = c.size * proj.scale;
heroCtx.strokeStyle = '#ff0a0a';
heroCtx.lineWidth = 1;
heroCtx.strokeRect(proj.x-s, proj.y-s, s*2, s*2);
}
});
// Particles
particles.forEach(p => {
let rp = rotateY({x:p.x,y:p.y,z:p.z}, rotY);
rp = rotateX(rp, rotX);
const proj = project(rp.x, rp.y, rp.z);
if(proj.scale>0){
heroCtx.fillStyle = '#ff4444';
heroCtx.beginPath();
heroCtx.arc(proj.x, proj.y, p.size * proj.scale, 0, Math.PI*2);
heroCtx.fill();
}
});
// Glow behind visor
const vc = {x:0,y:0,z:-25};
let vp = rotateY({x:vc.x,y:vc.y,z:vc.z}, rotY+time*0.15);
vp = rotateX(vp, rotX+Math.sin(time)*0.08);
vp.y += Math.sin(time*1.8)*12;
vp.z += Math.cos(time*1.3)*25;
const projV = project(vp.x, vp.y, vp.z);
if(projV.scale>0){
const g = heroCtx.createRadialGradient(projV.x, projV.y, 0, projV.x, projV.y, 140*projV.scale);
g.addColorStop(0, 'rgba(255,0,0,0.25)');
g.addColorStop(1, 'rgba(255,0,0,0)');
heroCtx.fillStyle = g;
heroCtx.fillRect(0,0,W,H);
}
requestAnimationFrame(renderHero);
}
renderHero();
/* ─── VB Screen Simulation ─── */
const vbCanvas = document.getElementById('vbCanvas');
const vbCtx = vbCanvas.getContext('2d');
let vbTime = 0;
function renderVB() {
vbTime += 0.04;
vbCtx.fillStyle = '#000000';
vbCtx.fillRect(0, 0, 320, 240);
// Wireframe terrain
vbCtx.strokeStyle = '#ff0000';
vbCtx.lineWidth = 1;
for(let z=0; z<8; z++){
let offset = (vbTime * 25 + z * 35) % 280;
vbCtx.beginPath();
for(let x=0; x<=320; x+=8){
let y = 130 + Math.sin((x+offset)*0.025)*25*(z/8) - z*5;
if(x===0) vbCtx.moveTo(x,y); else vbCtx.lineTo(x,y);
}
vbCtx.stroke();
}
// Floating sprite
let sx = 160 + Math.sin(vbTime*0.8)*90;
let sy = 110 + Math.cos(vbTime*0.6)*50;
vbCtx.fillStyle = '#ff0000';
vbCtx.beginPath();
vbCtx.moveTo(sx, sy-12);
vbCtx.lineTo(sx+10, sy+10);
vbCtx.lineTo(sx-10, sy+10);
vbCtx.closePath();
vbCtx.fill();
// Pixel noise
for(let i=0;i<40;i++){
let px = Math.random()*320;
let py = Math.random()*240;
vbCtx.fillStyle = Math.random()>0.5 ? '#220000' : '#ff0000';
vbCtx.fillRect(px,py,2,2);
}
requestAnimationFrame(renderVB);
}
renderVB();
/* ─── Scroll Animations ─── */
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if(entry.isIntersecting) entry.target.classList.add('visible');
});
}, { threshold: 0.08 });
document.querySelectorAll('.fade-in').forEach(el => observer.observe(el));
/* ─── Parallax Title ─── */
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
const title = document.querySelector('.hero-overlay h1');
if(title && scrollY < window.innerHeight){
title.style.transform = `translateY(${scrollY * 0.4}px)`;
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment