2026-04-02 23:33:37 +01:00

264 lines
11 KiB
Plaintext

@model CatherineLynwood.Models.TitlePageViewModel
@{
ViewData["Title"] = "The Alpha Flame: Reckoning";
}
<div class="reckoning-page-shell">
<!-- Detective desk / case file section -->
<section class="reckoning-desk-section">
<div class="reckoning-desk-surface">
<div class="reckoning-desk-props">
<div class="reckoning-desk-photos">
<div class="reckoning-desk-photo reckoning-desk-photo-1">
<responsive-image src="flyover-at-night.png" class="img-fluid" alt="The Rubery flyover at night time" display-width-percentage="50"></responsive-image>
</div>
<div class="reckoning-desk-photo reckoning-desk-photo-2">
<responsive-image src="sophie-jones-nightclub.png" class="img-fluid" alt="Sophie Jones" display-width-percentage="50"></responsive-image>
</div>
<div class="reckoning-desk-photo reckoning-desk-photo-3">
<responsive-image src="the-alpha-flame-reckoning-cover.png" class="img-fluid" alt="Maggie Grant" display-width-percentage="50"></responsive-image>
</div>
</div>
<div class="reckoning-desk-postit">
<span>Fashion show<br />Scandals,<br />tonight!</span>
</div>
</div>
<div class="reckoning-casefile-page">
<div class="casefile-stage">
<div class="casefile" id="caseFile">
<div class="casefile-rear">
<img src="/images/webp/folder-rear.webp" alt="Case file interior" class="casefile-rear-img" />
<div class="casefile-flap-shadow"></div>
<div class="casefile-inner">
<div class="casefile-paper-stack">
<div class="casefile-paper-stack-layer casefile-paper-stack-layer-1"></div>
<div class="casefile-paper-stack-layer casefile-paper-stack-layer-2"></div>
<div class="casefile-content">
<div class="casefile-panel active" data-tab="summary">
<partial name="_ReckoningSummary" model="Model"></partial>
</div>
<div class="casefile-panel" data-tab="subjects">
<partial name="_ReckoningSubjects" model="Model"></partial>
</div>
<div class="casefile-panel" data-tab="evidence">
<partial name="_ReckoningEvidence" model="Model"></partial>
</div>
<div class="casefile-panel" data-tab="notes">
<partial name="_ReckoningReview" model="Model"></partial>
</div>
<div class="casefile-panel" data-tab="buy">
<partial name="_ReckoningBuy" model="Model"></partial>
</div>
<div class="casefile-panel restricted-panel" data-tab="restricted">
<partial name="_ReckoningRestricted" model="Model"></partial>
</div>
</div>
</div>
<div class="casefile-tabs">
<button type="button" class="casefile-tab active" data-tab="summary">Summary</button>
<button type="button" class="casefile-tab" data-tab="subjects">Subjects</button>
<button type="button" class="casefile-tab" data-tab="evidence">Evidence</button>
<button type="button" class="casefile-tab" data-tab="notes">Review</button>
<button type="button" class="casefile-tab" data-tab="buy">Purchase</button>
<button type="button" class="casefile-tab restricted" data-tab="restricted">Restricted</button>
</div>
</div>
</div>
<div class="casefile-front" id="caseFileFront" role="button" tabindex="0" aria-label="Open case file">
<div class="casefile-front-face casefile-front-face-front">
<img src="/images/webp/folder-front.webp" alt="Case file cover" class="casefile-front-img" />
<div class="casefile-front-overlay">
<div class="casefile-stamp">
RESTRICTED
</div>
<div class="casefile-cover-text">
<div class="casefile-cover-kicker">WEST MIDLANDS POLICE</div>
<h1>ALPHA FLAME: RECKONING</h1>
<p>Case Ref: AFR-1983-06</p>
<p>Status: Active Investigation</p>
</div>
<div class="casefile-open-hint">Click to open file</div>
</div>
</div>
<div class="casefile-front-face casefile-front-face-back">
<img src="/images/webp/folder-front-inside.webp" alt="" class="casefile-front-img casefile-front-img-back" />
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
@section BackgroundVideo {
<div></div>
}
@section CSS {
<link href="~/css/reckoning.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Permanent+Marker&family=Shadows+Into+Light&display=swap" rel="stylesheet">
}
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", function () {
const trigger = document.querySelector(".casefile-audio-trigger");
const audio = document.getElementById("evidenceTapeAudio");
if (!trigger || !audio) return;
trigger.addEventListener("click", function () {
if (audio.paused) {
audio.play().then(function () {
trigger.classList.add("is-playing");
}).catch(function () {
});
} else {
audio.pause();
trigger.classList.remove("is-playing");
}
});
audio.addEventListener("pause", function () {
if (!audio.ended) {
trigger.classList.remove("is-playing");
}
});
audio.addEventListener("ended", function () {
trigger.classList.remove("is-playing");
audio.currentTime = 0;
});
});
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
const caseFile = document.getElementById("caseFile");
const frontCover = document.getElementById("caseFileFront");
const tabs = caseFile.querySelectorAll(".casefile-tab");
const panels = caseFile.querySelectorAll(".casefile-panel");
const images = caseFile.querySelectorAll("img");
let loadedCount = 0;
let assetsReady = false;
let openTimer = null;
let isOpening = false;
let hasEnteredView = false;
function openCaseFile() {
if (!assetsReady || isOpening || caseFile.classList.contains("open")) {
return;
}
isOpening = true;
caseFile.classList.add("revealed");
caseFile.classList.add("open");
if (openTimer) {
clearTimeout(openTimer);
openTimer = null;
}
}
function startAutoOpenTimer() {
if (!assetsReady || hasEnteredView === false || openTimer || caseFile.classList.contains("open")) {
return;
}
openTimer = setTimeout(() => {
openCaseFile();
}, 3000);
}
function onAssetLoaded() {
loadedCount++;
if (loadedCount === images.length) {
assetsReady = true;
caseFile.classList.add("assets-ready");
setTimeout(() => {
caseFile.classList.add("ready");
}, 250);
startAutoOpenTimer();
}
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && !hasEnteredView) {
hasEnteredView = true;
startAutoOpenTimer();
observer.disconnect();
}
});
}, {
threshold: 0.35
});
observer.observe(caseFile);
images.forEach(img => {
if (img.complete) {
onAssetLoaded();
} else {
img.addEventListener("load", onAssetLoaded, { once: true });
img.addEventListener("error", onAssetLoaded, { once: true });
}
});
frontCover.addEventListener("click", function () {
openCaseFile();
});
frontCover.addEventListener("keydown", function (e) {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
openCaseFile();
}
});
tabs.forEach(tab => {
tab.addEventListener("click", function () {
const tabName = this.dataset.tab;
tabs.forEach(t => t.classList.remove("active"));
panels.forEach(p => p.classList.remove("active"));
this.classList.add("active");
const targetPanel = caseFile.querySelector(`.casefile-panel[data-tab="${tabName}"]`);
if (targetPanel) {
targetPanel.classList.add("active");
}
});
});
});
</script>
}