Files

192 lines
8.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1" />
<title>Newbury Nights — AR Ghost Hunt</title>
<link rel="stylesheet" href="/css/app.css" />
<link rel="stylesheet" href="/css/game.css" />
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js"
}
}
</script>
</head>
<body>
<!-- ============ TITLE SCREEN ============ -->
<section id="screen-title" class="screen">
<div class="title-wrap">
<div class="eyebrow">Newbury · After Dark</div>
<h1 class="game-title">Newbury<span>Nights</span></h1>
<p class="tagline">The town is glooming over. Raise your detector, find the cold spots, and clear them before your battery dies.</p>
<div class="title-actions">
<button class="primary" id="btn-scan-set">Scan a Set</button>
<button id="btn-freehunt">Free Hunt</button>
<button id="btn-roster">Ghost Index</button>
<button id="btn-about">About This Tribute</button>
</div>
<div class="battery-hint mono">DETECTOR ONLINE · v0.1</div>
</div>
<div class="disclaimer">
Fan-made tribute. Not affiliated with, sponsored by, or endorsed by the LEGO Group.
LEGO® and Hidden Side™ are trademarks of the LEGO Group.
</div>
</section>
<!-- ============ SCAN SCREEN ============ -->
<section id="screen-scan" class="screen hidden">
<button class="back" data-back>← Back</button>
<div class="scan-wrap">
<h2>Scan a Set</h2>
<p class="muted">Point your camera at the set's code, or type it in.</p>
<div id="scan-video-wrap" class="scan-video">
<video id="scan-video" playsinline muted></video>
<div class="scan-reticle"></div>
<div id="scan-status" class="scan-status mono">Starting camera…</div>
</div>
<div class="manual-entry">
<label for="manual-code">Set code</label>
<div class="row">
<input id="manual-code" placeholder="e.g. NN-70419" autocomplete="off" />
<button class="primary" id="btn-manual-go">Go</button>
</div>
<div id="scan-error" class="scan-error hidden"></div>
</div>
</div>
</section>
<!-- ============ HUNT (AR) SCREEN ============ -->
<section id="screen-hunt" class="screen hidden">
<video id="ar-video" playsinline muted></video>
<canvas id="ar-canvas"></canvas>
<!-- HUD overlay -->
<div class="hud">
<div class="hud-top">
<button class="back small" data-back></button>
<div class="battery">
<div class="battery-label mono">BATTERY</div>
<div class="battery-bar"><div id="battery-fill" class="battery-fill"></div></div>
<div id="battery-pct" class="mono">100%</div>
</div>
<div class="gloom-count mono"><span class="dot" style="background:var(--gloom);box-shadow:0 0 8px var(--gloom)"></span> <span id="gloom-count">0</span></div>
</div>
<!-- color wheel scanner -->
<div class="wheel" id="color-wheel" aria-label="Gloom detector color wheel">
<button class="wheel-seg seg-red" data-type="red" aria-label="Scan red gloom"></button>
<button class="wheel-seg seg-yellow" data-type="yellow" aria-label="Scan yellow gloom"></button>
<button class="wheel-seg seg-blue" data-type="blue" aria-label="Scan blue gloom"></button>
<div class="wheel-core mono" id="wheel-core">SCAN</div>
</div>
<!-- lock-on label -->
<div id="lockon" class="lockon hidden">
<div class="lockon-name display" id="lockon-name"></div>
<div class="lockon-sub mono"><span id="lockon-type"></span> · <span id="lockon-rarity"></span> · <span id="lockon-ability"></span></div>
<div class="ghost-hp"><div id="ghost-hp-fill" class="ghost-hp-fill"></div></div>
</div>
<!-- blaster -->
<div class="hud-bottom">
<div class="overheat" id="overheat-wrap"><div id="overheat-fill" class="overheat-fill"></div></div>
<button id="btn-blast" class="blaster">HOLD TO BLAST</button>
</div>
<!-- jumpscare / toast -->
<div id="toast" class="toast hidden"></div>
<!-- iOS motion permission gate -->
<div id="motion-gate" class="motion-gate hidden">
<div class="motion-card">
<div class="motion-title display">Enable Motion</div>
<p class="motion-body">Newbury Nights uses your phone's motion sensor to look around. Tap below and allow access when prompted.</p>
<button class="primary" id="motion-enable">Enable Motion</button>
</div>
</div>
<div id="result" class="result hidden">
<div class="result-card">
<div id="result-title" class="display">Set Cleared</div>
<div id="result-body" class="muted"></div>
<button class="primary" data-back>Return to Newbury</button>
</div>
</div>
</div>
</section>
<!-- ============ ABOUT / TRIBUTE ============ -->
<section id="screen-about" class="screen hidden">
<button class="back" data-back>← Back</button>
<div class="about-wrap">
<h2>About This Tribute</h2>
<p class="about-lead">Newbury Nights is a fan-made, non-commercial homage to the
augmented-reality ghost-hunting mechanics of the LEGO® Hidden Side™ app, which the
LEGO Group discontinued. It exists because some of us loved how that game worked and
didn't want the idea to disappear.</p>
<h3>What this is</h3>
<p>An independent reimplementation of the <em>way the game played</em> — raising your
phone as a detector, uncovering coloured gloom, locking on, and clearing ghosts. The
ghost names, types, and stats are referenced from community documentation of the
original so the tribute feels true to what fans remember.</p>
<h3>What this is not</h3>
<p>This project is not made by, affiliated with, sponsored by, or endorsed by the
LEGO Group. It uses none of the LEGO Group's logos, brand artwork, minifigure designs,
or other protected imagery. Where the original game's name appears, it is only to
describe what this project pays tribute to.</p>
<h3>Names &amp; trademarks</h3>
<p>"LEGO" and "Hidden Side" are trademarks of the LEGO Group. They are referenced here
solely to identify the original work being honoured. If you're looking for the official
product, visit the LEGO Group's own website rather than this fan project.</p>
<h3>Credit &amp; takedown</h3>
<p>All credit for the original concept belongs to the LEGO Group and the team behind
Hidden Side. This is a labour of love, offered freely. If a rights holder would prefer
any element changed or removed, that request will be respected.</p>
</div>
<div class="disclaimer">
Fan-made tribute. Not affiliated with, sponsored by, or endorsed by the LEGO Group.
LEGO® and Hidden Side™ are trademarks of the LEGO Group.
</div>
</section>
<!-- ============ ROSTER / INDEX ============ -->
<section id="screen-roster" class="screen hidden">
<button class="back" data-back>← Back</button>
<div class="roster-wrap">
<h2>Ghost Index</h2>
<div class="roster-filters">
<select id="filter-type">
<option value="">All types</option>
<option value="red">Red</option>
<option value="yellow">Yellow</option>
<option value="blue">Blue</option>
</select>
<select id="filter-rarity">
<option value="">All rarities</option>
<option value="1"></option>
<option value="2">★★</option>
<option value="3">★★★</option>
<option value="4">★★★★</option>
</select>
<label class="boss-toggle"><input type="checkbox" id="filter-boss" /> Bosses only</label>
</div>
<div id="roster-grid" class="roster-grid"></div>
</div>
<div class="disclaimer">
Fan-made tribute. Not affiliated with, sponsored by, or endorsed by the LEGO Group.
LEGO® and Hidden Side™ are trademarks of the LEGO Group.
</div>
</section>
<script type="module" src="/js/game.js"></script>
</body>
</html>