now the ascii animation is at the top
This commit is contained in:
@@ -4,33 +4,36 @@
|
|||||||
The mountain background is JS-driven: tools/mountain.py renders 60
|
The mountain background is JS-driven: tools/mountain.py renders 60
|
||||||
procedural 3D mountain-flyover PNG frames; chafa converts each to 80x24
|
procedural 3D mountain-flyover PNG frames; chafa converts each to 80x24
|
||||||
ASCII; tools/build_mountain_js.py bundles them into static/js/mountain.js.
|
ASCII; tools/build_mountain_js.py bundles them into static/js/mountain.js.
|
||||||
static/js/mountain-bg.js cycles the frames at 12 fps into a single
|
static/js/mountain-bg.js cycles the frames at 12 fps into the
|
||||||
<pre class="tp-mountain-frame"> element mounted at the bottom of <body>.
|
<pre id="tp-mountain-bg" class="tp-mountain-bg"> placeholder in index.html.
|
||||||
|
|
||||||
This CSS file:
|
This CSS file:
|
||||||
- positions the frame as a full-bleed fixed background
|
- positions the frame as a full-screen top layer
|
||||||
- tints the dense characters rust-orange with text-shadow + glow
|
- tints the dense characters rust-orange with text-shadow + glow
|
||||||
- adds a CRT scanline overlay
|
- adds a CRT scanline overlay
|
||||||
- disables the animation under prefers-reduced-motion
|
- disables the animation under prefers-reduced-motion
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
/* Full-bleed ASCII mountain background ---------------------------------- */
|
/* Full-screen ASCII mountain top layer ----------------------------------- */
|
||||||
.tp-mountain-frame {
|
.tp-mountain-bg {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
inset: 0;
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
height: 100svh;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||||
font-size: clamp(8px, 1.2vw, 14px);
|
font-size: max(2.1vw, 4.17vh);
|
||||||
|
font-size: max(2.1vw, 4.17svh);
|
||||||
line-height: 1.0;
|
line-height: 1.0;
|
||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
color: #f4a26b; /* warm rust-orange tint, picks up the brand */
|
color: #f4a26b;
|
||||||
text-shadow: 0 0 8px rgba(183, 65, 14, 0.35); /* phosphor glow */
|
text-shadow: 0 0 8px rgba(183, 65, 14, 0.35);
|
||||||
opacity: 0.45;
|
opacity: 0.45;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -40,7 +43,7 @@
|
|||||||
|
|
||||||
/* CRT scanlines overlay - a thin moving line every 2px. Faint so it doesn't
|
/* CRT scanlines overlay - a thin moving line every 2px. Faint so it doesn't
|
||||||
fight the page content. */
|
fight the page content. */
|
||||||
.tp-mountain-frame::after {
|
.tp-mountain-bg::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
@@ -62,14 +65,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Light theme: dim the background, drop the glow, switch to dark text. */
|
/* Light theme: dim the background, drop the glow, switch to dark text. */
|
||||||
:root[data-theme="winter"] .tp-mountain-frame {
|
:root[data-theme="winter"] .tp-mountain-bg {
|
||||||
opacity: 0.20;
|
opacity: 0.20;
|
||||||
color: #2a1810;
|
color: #2a1810;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
mix-blend-mode: multiply;
|
mix-blend-mode: multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme="winter"] .tp-mountain-frame::after {
|
:root[data-theme="winter"] .tp-mountain-bg::after {
|
||||||
background: repeating-linear-gradient(
|
background: repeating-linear-gradient(
|
||||||
to bottom,
|
to bottom,
|
||||||
transparent 0,
|
transparent 0,
|
||||||
@@ -82,7 +85,7 @@
|
|||||||
|
|
||||||
/* Reduced motion: keep the first frame static, no scanline drift. */
|
/* Reduced motion: keep the first frame static, no scanline drift. */
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
.tp-mountain-frame::after {
|
.tp-mountain-bg::after {
|
||||||
animation: none !important;
|
animation: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,12 @@
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
if (typeof window.TP_MOUNTAIN_FRAMES === "undefined") return;
|
if (typeof window.TP_MOUNTAIN_FRAMES === "undefined") return;
|
||||||
if (document.querySelector("[data-tp-mountain]")) return;
|
|
||||||
|
|
||||||
var pre = document.createElement("pre");
|
var pre = document.querySelector("#tp-mountain-bg");
|
||||||
pre.className = "tp-mountain-frame";
|
if (!pre) return;
|
||||||
pre.setAttribute("data-tp-mountain", "");
|
pre.setAttribute("data-tp-mountain", "");
|
||||||
pre.setAttribute("aria-hidden", "true");
|
pre.setAttribute("aria-hidden", "true");
|
||||||
pre.textContent = window.TP_MOUNTAIN_FRAMES[0];
|
pre.textContent = window.TP_MOUNTAIN_FRAMES[0];
|
||||||
document.body.appendChild(pre);
|
|
||||||
|
|
||||||
var n = window.TP_MOUNTAIN_N_FRAMES;
|
var n = window.TP_MOUNTAIN_N_FRAMES;
|
||||||
var fps = window.TP_MOUNTAIN_FPS;
|
var fps = window.TP_MOUNTAIN_FPS;
|
||||||
|
|||||||
Reference in New Issue
Block a user