+
+
+
+ RECOVERY · ARCHIVE_404
-
-
> FILE
{pad(count)}/20
- {count > 0 &&
{TITLES[count - 1]}}
+
+ RECOVERING FILES.
- {done && (
+
- > 20/20 FILES INTACT
+ > RECOVERING ARCHIVE_404
- )}
-
+
+ > FILE {pad(count)}/20
+ {count > 0 && {TITLES[count - 1]}}
+
+ {done && (
+
+ > 20/20 FILES INTACT
+
+ )}
+
+
+
+
+
+ 20 FILES
+ {pad(count)}/20
+
Recovering ARCHIVE_404: 20 of 20 files intact.
{/* visually hidden; appears only when focused, e.g. by a screen reader (tap / any key also skips) */}
diff --git a/src/styles/overrides.css b/src/styles/overrides.css
index 2741bef..2d71720 100644
--- a/src/styles/overrides.css
+++ b/src/styles/overrides.css
@@ -2904,53 +2904,160 @@ body {
}
/* ===== intro M3: terminal readout over the tracklist rain (BootSequence) ===== */
-.e-bterm {
+/* intro readout card (site intro + vault unlock): the vault gate's viewfinder card. No box, four
+ corner ticks, the rain fading to dark behind the text; a tag, a small title, the readout lines and
+ a gradient bar that fills with the 00 → 20 count. */
+.e-icard {
position: absolute;
left: 50%;
top: 50%;
z-index: 3;
transform: translate(-50%, -50%);
- padding: 18px 22px;
- min-width: min(440px, calc(100vw - 48px));
- background: rgba(3, 4, 9, 0.78);
- border: 1px solid rgba(244, 244, 248, 0.12);
+ width: min(330px, calc(100vw - 40px));
+ padding: 18px 18px 14px;
+ background: radial-gradient(closest-side, rgba(3, 4, 9, 0.92), rgba(3, 4, 9, 0.75) 70%, transparent);
font-family:
Space Mono,
monospace;
- font-size: clamp(11px, 1.3vw, 15px);
+ color: #f4f4f8;
+ transition: opacity 0.4s;
+}
+@media (min-width: 768px) {
+ .e-icard {
+ width: 380px;
+ padding: 22px 22px 16px;
+ }
+}
+.e-icard.out {
+ opacity: 0;
+}
+.e-icard::before,
+.e-icard::after,
+.e-icard-vf::before,
+.e-icard-vf::after {
+ content: "";
+ position: absolute;
+ width: 14px;
+ height: 14px;
+ border: 1px solid #ff00e5;
+ pointer-events: none;
+}
+.e-icard::before {
+ top: -1px;
+ left: -1px;
+ border-right: 0;
+ border-bottom: 0;
+}
+.e-icard::after {
+ bottom: -1px;
+ right: -1px;
+ border-left: 0;
+ border-top: 0;
+ border-color: #00efff;
+}
+.e-icard-vf {
+ position: absolute;
+ inset: -1px;
+ pointer-events: none;
+}
+.e-icard-vf::before {
+ top: 0;
+ right: 0;
+ border-left: 0;
+ border-bottom: 0;
+ border-color: #00efff;
+}
+.e-icard-vf::after {
+ bottom: 0;
+ left: 0;
+ border-right: 0;
+ border-top: 0;
+}
+.e-icard-tg {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ margin-bottom: 10px;
+ font-size: 8px;
+ letter-spacing: 0.32em;
+ color: #ff00e5;
+ white-space: nowrap;
+}
+.e-icard-tg i {
+ width: 6px;
+ height: 6px;
+ flex: none;
+ background: #4ade80;
+ box-shadow: 0 0 8px #4ade80;
+ animation: e4-blink 1.2s steps(1) infinite;
+}
+.e-icard-h {
+ font-family: "Bebas Neue", sans-serif;
+ font-weight: 400;
+ font-size: 1.7rem;
+ line-height: 0.86;
+ margin-bottom: 10px;
+}
+.e-icard-l {
+ min-height: 66px;
+ font-size: 11px;
letter-spacing: 0.08em;
line-height: 2;
- color: #f4f4f8;
white-space: nowrap;
text-shadow: 0 0 10px rgba(255, 0, 229, 0.5);
- transition: opacity 0.4s;
}
-.e-bterm.out {
- opacity: 0;
+@media (min-width: 768px) {
+ .e-icard-h {
+ font-size: 2rem;
+ }
+ .e-icard-l {
+ font-size: 12px;
+ min-height: 72px;
+ }
}
-.e-bterm b {
+.e-icard-l b {
font-weight: 400;
color: #ff00e5;
}
-.e-bterm i {
+.e-icard-l i {
font-style: normal;
color: #00efff;
}
-.e-bterm-t {
+.e-icard-l .ok {
+ color: #4ade80;
+}
+.e-icard-t {
+ display: block;
margin-left: 1.4em;
+ overflow: hidden;
+ text-overflow: ellipsis;
color: rgba(244, 244, 248, 0.6);
}
-.e-bterm-cur {
- display: inline-block;
- width: 0.6em;
- height: 1.1em;
- margin-top: 4px;
+.e-icard-bar {
+ position: relative;
+ height: 2px;
+ margin-top: 12px;
+ background: rgba(244, 244, 248, 0.1);
+}
+.e-icard-bar b {
+ position: absolute;
+ left: 0;
+ top: 0;
+ bottom: 0;
background: linear-gradient(90deg, #ff00e5, #00efff);
- vertical-align: -0.2em;
- animation: e4-blink 1s steps(1) infinite;
+ box-shadow: 0 0 8px rgba(255, 0, 229, 0.7);
+ transition: width 0.15s;
+}
+.e-icard-tk {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 6px;
+ font-size: 8px;
+ letter-spacing: 0.2em;
+ color: rgba(244, 244, 248, 0.28);
}
@media (prefers-reduced-motion: reduce) {
- .e-bterm-cur {
+ .e-icard-tg i {
animation: none;
}
}
diff --git a/src/vault/main.js b/src/vault/main.js
index eb7006d..ba3cc20 100644
--- a/src/vault/main.js
+++ b/src/vault/main.js
@@ -15,6 +15,10 @@ const mb = (b) => (b >= 1e9 ? (b / 1e9).toFixed(2) + " GB" : Math.round(b / 1e6)
const esc = (s) =>
s.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
const REDUCE = matchMedia("(prefers-reduced-motion: reduce)").matches;
+// The vault always opens at the top: typing the key on a phone scrolls the page behind the gate
+// (the keyboard pushes the field into view), and the browser may restore an old position on return.
+if ("scrollRestoration" in history) history.scrollRestoration = "manual";
+const toTop = () => scrollTo({ top: 0, left: 0, behavior: "instant" });
const toast = (t) => {
const el = $("#toast");
el.textContent = t;
@@ -187,6 +191,7 @@ let revealed = false;
function reveal() {
if (revealed) return;
revealed = true;
+ toTop();
$("#gate").classList.add("out");
stopGateRain();
document.body.classList.remove("locked");
@@ -338,20 +343,25 @@ function unlockSequence() {
term = $("#viTerm");
ov.hidden = false;
ov.classList.remove("out");
+ toTop();
$("#gate").classList.add("out");
stopGateRain();
const rain = vaultRain($("canvas", ov), stems.concat(titles));
const T = [];
const at = (ms, f) => T.push(setTimeout(f, ms));
- const line = (i, extra = "") =>
- `
> KEY ACCEPTED · ACCESS Nº004
> DECRYPTING ${pad(i)}/20${i ? `${titles[i - 1]}_STEMS.ZIP` : ""}
${extra}
`;
+ const line = (i, extra = "") => {
+ $("#viBar").style.width = (i / 20) * 100 + "%";
+ $("#viCount").textContent = `${pad(i)}/20`;
+ return `
> KEY ACCEPTED · ACCESS Nº004
> DECRYPTING ${pad(i)}/20${i ? `${titles[i - 1]}_STEMS.ZIP` : ""}
${extra}`;
+ };
+ const lines = $("#viLines");
term.classList.remove("out");
- term.innerHTML = line(0);
- for (let i = 1; i <= 20; i++) at(250 + (i - 1) * 150, () => (term.innerHTML = line(i)));
+ lines.innerHTML = line(0);
+ for (let i = 1; i <= 20; i++) at(250 + (i - 1) * 150, () => (lines.innerHTML = line(i)));
at(
250 + 20 * 150,
() =>
- (term.innerHTML = line(
+ (lines.innerHTML = line(
20,
'
> VAULT OPEN · 20 FILES · WAV + MIDI
',
)),
diff --git a/src/vault/vault.css b/src/vault/vault.css
index b9f5380..3d81c2b 100644
--- a/src/vault/vault.css
+++ b/src/vault/vault.css
@@ -399,57 +399,6 @@ a {
pointer-events: none;
background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.3) 0 1px, transparent 1px 3px);
}
-.vi-term {
- position: absolute;
- left: 50%;
- top: 50%;
- z-index: 3;
- transform: translate(-50%, -50%);
- padding: 18px 22px;
- min-width: min(460px, calc(100vw - 48px));
- background: rgba(3, 4, 9, 0.78);
- border: 1px solid rgba(244, 244, 248, 0.12);
- font-family: var(--mono);
- font-size: clamp(11px, 1.3vw, 15px);
- letter-spacing: 0.08em;
- line-height: 2;
- color: var(--ghost);
- white-space: nowrap;
- text-shadow: 0 0 10px rgba(255, 0, 229, 0.5);
- transition: opacity 0.4s;
-}
-.vi-term.out {
- opacity: 0;
-}
-.vi-term b {
- font-weight: 400;
- color: var(--mag);
-}
-.vi-term i {
- font-style: normal;
- color: var(--cyan);
-}
-.vi-term .ok {
- color: var(--led);
-}
-.vi-term .t {
- margin-left: 1.2em;
- color: rgba(244, 244, 248, 0.6);
-}
-@media (max-width: 520px) {
- .vi-term .t {
- display: block;
- margin-left: 1.4em;
- }
-}
-.vi-term .cur {
- display: inline-block;
- width: 0.6em;
- height: 1.1em;
- background: var(--grad);
- vertical-align: -0.2em;
- animation: blink 1s steps(2) infinite;
-}
.sr-only {
position: absolute;
width: 1px;
@@ -1089,8 +1038,15 @@ details.fold[open] summary::after {
.toolbar {
flex-wrap: wrap;
}
+ /* chapter buttons wrap onto a second row instead of scrolling off the edge */
.chips-scroll {
flex: 1 1 100%;
+ flex-wrap: wrap;
+ overflow: visible;
+ }
+ .chips-scroll .gbtn {
+ flex: 1 1 auto;
+ justify-content: center;
}
.search {
flex: 1;
diff --git a/vault/index.html b/vault/index.html
index 72b77f8..091c190 100644
--- a/vault/index.html
+++ b/vault/index.html
@@ -52,7 +52,14 @@
ACCESS REQUIRED.
-
+
+
+
KEY ACCEPTED · SOURCE VAULT
+
DECRYPTING VAULT.
+
+
+
20 STEM ZIPS00/20
+