PageSourceSearch

https://aeternolife.ai/

html aeternolife.ai collected 2026-10-01 01:48:10 UTC 22,544 bytes, 516 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width, initial-scale=1.0">
6<title>AETERNO — Beyond Human Sight</title>
7<meta name="description" content="AETERNO Life — sovereign AI health monitoring. Enter the universe of prevention. Educational CDS — not a diagnosis. Zug, Switzerland.">
8<meta name="robots" content="index, follow">
9<meta name="theme-color" content="#020208">
10<meta name="mobile-web-app-capable" content="yes">
11<meta name="apple-mobile-web-app-capable" content="yes">
12<meta name="apple-mobile-web-app-title" content="AETERNO">
13<link rel="canonical" href="https://aeternolife.ai/">
14<link rel="manifest" href="/manifest.webmanifest">
15<link rel="apple-touch-icon" href="/icon-192.png">
16<meta property="og:title" content="AETERNO — Beyond Human Sight">
17<meta property="og:description" content="Sovereign AI health monitoring. Enter the platform.">
18<meta property="og:url" content="https://aeternolife.ai/">
19<meta property="og:image" content="https://storage.googleapis.com/aeterno-official/og-index.jpg">
20<meta property="og:type" content="website">
21<meta name="twitter:card" content="summary_large_image">
22<meta name="twitter:title" content="AETERNO — Beyond Human Sight">
23<meta name="twitter:image" content="https://storage.googleapis.com/aeterno-official/og-index.jpg">
24<link rel="sitemap" type="application/xml" href="https://aeternolife.ai/sitemap.xml">
25<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;1,300;1,400&family=Montserrat:wght@200;300;400&display=swap" rel="stylesheet">
26<style>
27*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
28html,body{width:100%;height:100%;overflow:hidden;
28background:#020208;color:#f0ede6;font-family:'Montserrat',sans-serif;font-weight:300}
29
30.skip-link{
31  position:absolute;left:12px;top:-44px;z-index:40;
32  background:#c9a84c;color:#04040A;padding:10px 12px;text-decoration:none;
33  font-size:11px;letter-spacing:1px;
34}
35.skip-link:focus{top:12px}
36.skip-btn:focus-visible,.skip-link:focus-visible{outline:2px solid #00d4be;outline-offset:2px}
37
38#space-canvas{position:fixed;inset:0;z-index:0}
39#warp-glow{
40  position:fixed;inset:0;z-index:1;pointer-events:none;
41  background:radial-gradient(circle at 50% 50%,
42    rgba(255,255,255,0) 0%,
43    rgba(0,212,230,0) 18%,
44    transparent 55%);
45  opacity:0;
46  animation:warp-glow-build 9s ease-in forwards;
47}
48@keyframes warp-glow-build{
49  0%,25%{opacity:0}
50  55%{opacity:0.35}
51  100%{opacity:0.85}
52}
53
54.nebula{
55  position:fixed;inset:0;z-index:2;pointer-events:none;
56  background:
57    radial-gradient(ellipse 80% 60% at 20% 80%, rgba(0,212,190,0.07) 0%, transparent 55%),
58    radial-gradient(ellipse 60% 50% at 85% 15%, rgba(167,139,250,0.06) 0%, transparent 50%),
59    radial-gradient(ellipse 50% 40% at 50% 50%, rgba(0,212,230,0.08) 0%, transparent 60%);
60  animation:nebula-warp 9s ease-in forwards;
61}
62@keyframes nebula-warp{
63  0%{opacity:0.5;transform:scale(1)}
64  50%{opacity:0.75;transform:scale(1.05)}
65  100%{opacity:1;transform:scale(1.35)}
66}
67
68.vignette{
69  position:fixed;inset:0;z-index:3;pointer-events:none;
70  background:radial-gradient(ellipse at center, transparent 35%, rgba(2,2,8,0.88) 100%);
71  animation:vignette-tunnel 9s ease-in forwards;
72}
73@keyframes vignette-tunnel{
74  0%{opacity:1}
75  100%{opacity:0.65}
76}
77
78.intro{
79  position:fixed;inset:0;z-index:10;
80  display:flex;flex-direction:column;align-items:center;justify-content:center;
81  padding:40px 32px;text-align:center;
82  animation:intro-into-eternity 9s ease-in forwards;
83}
84@keyframes intro-into-eternity{
85  0%,40%{transform:scale(1);filter:blur(0)}
86  75%{transform:scale(1.04);filter:blur(0)}
87  100%{transform:scale(1.14);filter:blur(1px)}
88}
89
90.qe-orbit-1 { animation: qe-spin 12s linear infinite; transform-origin: 50% 50%; }
91.qe-orbit-2 { animation: qe-spin 18s linear infinite reverse; transform-origin: 50% 50%; }
92.qe-orbit-3 { animation: qe-spin 8s linear infinite; transform-origin: 50% 50%; }
93.qe-pulse   { animation: qe-glow 3s ease-in-out infinite; }
94.qe-scan    { animation: qe-scanline 4s ease-in-out infinite; }
95@keyframes qe-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
96@keyframes qe-glow { 0%,100% { opacity:0.7; } 50% { opacity:1; } }
97@keyframes qe-scanline { 0%,100% { opacity:0.15; } 50% { opacity:0.5; } }
98
99.eye-wrap{
100  position:relative;width:120px;height:120px;margin-bottom:48px;
101  animation:eye-appear 1.8s ease both;
102}
103@keyframes eye-appear{ from{opacity:0;transform:scale(0.6)} to{opacity:1;transform:scale(1)} }
104.eye-ring{
105  position:absolute;border-radius:50%;border:1px solid rgba(201,168,76,0.2);
106  animation:ring-pulse 3s ease-in-out infinite;
107}
108.eye-ring-1{inset:-20px}
109.eye-ring-2{inset:-36px;border-color:rgba(201,168,76,0.12);animation-delay:0.5s}
110.eye-ring-3{inset:-54px;border-color:rgba(201,168,76,0.06);animation-delay:1s}
111@keyframes ring-pulse{ 0%,100%{opacity:0.5;transform:scale(1)} 50%{opacity:1;transform:scale(1.03)} }
112.eye-core{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
113.eye-core svg{width:96px;height:96px}
114
115.wordmark{
116  font-family:'Cormorant Garamond',serif;
117  font-size:clamp(28px,5vw,42px);
118  letter-spacing:clamp(12px,3vw,22px);
119  color:#c9a84c;
120  text-shadow:0 0 40px rgba(201,168,76,0.5),0 0 80px rgba(201,168,76,0.2);
121  margin-bottom:8px;
122  animation:wordmark-glow 2s ease 0.4s both;
123}
124@keyframes wordmark-glow{ from{opacity:0;letter-spacing:30px} to{opacity:1} }
125.tagline{
126  font-size:8px;letter-spacing:5px;text-transform:uppercase;
127  color:rgba(201,168,76,0.45);margin-bottom:56px;
128  animation:fade-up 1.2s ease 0.8s both;
129}
130
131.vision{
132  max-width:640px;min-height:120px;
133  display:flex;flex-direction:column;gap:16px;align-items:center;
134}
135.vision-line{
136  font-family:'Cormorant Garamond',serif;
137  font-size:clamp(18px,3.5vw,28px);
138  font-weight:300;line-height:1.5;
139  color:rgba(240,237,230,0);
140  transform:translateY(12px);
141  transition:opacity 1s ease, transform 1s ease, color 1s ease;
142}
143.vision-line.visible{ opacity:1;transform:translateY(0);color:rgba(240,237,230,0.88); }
144.vision-line em{font-style:italic;color:#00d4be}
145.vision-line.gold{color:#c9a84c;opacity:0!important}
146.vision-line.gold.visible{opacity:1!important;font-size:clamp(22px,4vw,34px);letter-spacing:4px}
147
148.countdown-wrap{
149  position:fixed;bottom:48px;left:50%;transform:translateX(-50%);
150  z-index:20;display:flex;flex-direction:column;align-items:center;gap:12px;
151  animation:fade-up 1s ease 1.2s both;
152}
153@keyframes fade-up{
154  from{opacity:0;transform:translateX(-50%) translateY(16px)}
155  to{opacity:1;transform:translateX(-50%) translateY(0)}
156}
157.countdown-ring{position:relative;width:48px;height:48px}
158.countdown-ring svg{transform:rotate(-90deg)}
159.countdown-ring circle{fill:none;stroke-width:2}
160.countdown-track{stroke:rgba(201,168,76,0.15)}
161.countdown-progress{
162  stroke:#c9a84c;stroke-linecap:round;
163  stroke-dasharray:113;stroke-dashoffset:0;
164  animation:countdown 9s linear forwards;
165  filter:drop-shadow(0 0 6px rgba(201,168,76,0.6));
166}
167@keyframes countdown{ from{stroke-dashoffset:0} to{stroke-dashoffset:113} }
168.countdown-label{
169  font-size:8px;letter-spacing:4px;text-transform:uppercase;
170  color:rgba(240,237,230,0.35);
171}
172.skip-btn{
173  position:fixed;top:28px;right:32px;z-index:30;
174  background:transparent;border:1px solid rgba(201,168,76,0.2);
175  color:rgba(201,168,76,0.6);font-family:'Montserrat',sans-serif;
176  font-size:8px;letter-spacing:3px;text-transform:uppercase;
177  padding:10px 18px;cursor:pointer;transition:all 0.3s;
178}
179.skip-btn:hover{border-color:#c9a84c;color:#c9a84c;background:rgba(201,168,76,0.06)}
180
181.audio-hint{
182  position:fixed;bottom:110px;left:50%;transform:translateX(-50%);
183  font-size:8px;letter-spacing:3px;text-transform:uppercase;
184  color:rgba(240,237,230,0.25);z-index:20;
185  opacity:0;transition:opacity 0.5s;pointer-events:none;
186}
187.audio-hint.show{opacity:1}
188
189.intro.warp-out{ animation:warp-out 0.7s ease-in forwards !important; }
190@keyframes warp-out{ to{opacity:0;transform:scale(2.2);filter:blur(14px)} }
191body.warp-out #space-canvas,
192body.warp-out #warp-glow{ animation:warp-burst 0.7s ease-in forwards; }
193body.warp-out .nebula{ animation:warp-burst 0.7s ease-in forwards; }
194@keyframes warp-burst{ to{transform:scale(2.8);opacity:0} }
195
196@media (prefers-reduced-motion: reduce){
197  *,*::before,*::after{
198    animation:none !important;
199    transition:none !important;
200    scroll-behavior:auto !important;
201  }
202}
203</style>
204<link rel="stylesheet" href="aeterno-access.css">
205</head>
206<body>
207<a class="skip-link" href="/platform.html">Skip intro and open platform</a>
208
209<canvas id="space-canvas" aria-hidden="true"></canvas>
210<div id="warp-glow" aria-hidden="true"></div>
211<div class="nebula" aria-hidden="true"></div>
212<div class="vignette" aria-hidden="true"></div>
213
214<button class="skip-btn" id="skip-btn" type="button">Skip to Platform →</button>
215
216<div class="intro" id="intro">
217  <div class="eye-wrap" aria-hidden="true">
218    <div class="eye-ring eye-ring-1"></div>
219    <div class="eye-ring eye-ring-2"></div>
220    <div class="eye-ring eye-ring-3"></div>
221    <div class="eye-core">
222      <svg viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
223        <circle cx="60" cy="60" r="56" stroke="#C9A84C" stroke-width="0.8" opacity="0.5"/>
224        <circle cx="60" cy="60" r="44" stroke="#C9A84C" stroke-width="0.4" opacity="0.25"/>
225        <g class="qe-orbit-1"><ellipse cx="60" cy="60" rx="48" ry="18" stroke="#C9A84C" stroke-width="0.7" opacity="0.55"/></g>
226        <g class="qe-orbit-2"><ellipse cx="60" cy="60" rx="48" ry="18" stroke="#C9A84C" stroke-width="0.5" opacity="0.35" transform="rotate(60 60 60)"/></g>
227        <g class="qe-orbit-3"><ellipse cx="60" cy="60" rx="48" ry="18" stroke="#C9A84C" stroke-width="0.4" opacity="0.25" transform="rotate(120 60 60)"/></g>
228        <line x1="4" y1="60" x2="116" y2="60" stroke="#C9A84C" stroke-width="0.4" opacity="0.2" class="qe-scan"/>
229        <line x1="60" y1="4" x2="60" y2="116" stroke="#C9A84C" stroke-width="0.4" opacity="0.15"/>
230        <circle cx="60" cy="60" r="10" stroke="#C9A84C" stroke-width="0.6" opacity="0.5"/>
231        <circle cx="60" cy="60" r="4" fill="#C9A84C" class="qe-pulse"/>
232      </svg>
233    </div>
234  </div>
235
236  <div class="wordmark">AETERNO</div>
237  <div class="tagline">Sovereign AI Health · Zug, Switzerland</div>
238
239  <div class="vision" id="vision" aria-live="polite">
240    <p class="vision-line" data-delay="800">In the silence between heartbeats,<br>the body speaks.</p>
241    <p class="vision-line" data-delay="2200">AETERNO listens — <em>before symptoms arise.</em></p>
242    <p class="vision-line" data-delay="3800">Your health. Your data. Your sovereignty.</p>
243    <p class="vision-line gold" data-delay="5400">Beyond human sight. For life.</p>
244  </div>
245</div>
246
247<div class="countdown-wrap">
248  <div class="countdown-ring" aria-hidden="true">
249    <svg width="48" height="48" viewBox="0 0 48 48">
250      <circle class="countdown-track" cx="24" cy="24" r="18"/>
251      <circle class="countdown-progress" cx="24" cy="24" r="18"/>
252    </svg>
253  </div>
254  <span class="countdown-label">Entering AETERNO</span>
255</div>
256
257<p class="audio-hint" id="audio-hint">Tap anywhere for sound</p>
258
259<script>
260(function () {
261  'use strict';
262
263  const INTRO_MS = 9000;
264  const INTRO_REDUCED_MS = 5000;
265  const INTRO_DONE_KEY = 'aeterno_intro_v1';
266  const INTRO_ATTEMPTS_KEY = 'aeterno_intro_attempts';
267  let redirected = false;
268  const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
269  const params = new URLSearchParams(window.location.search);
270  const forceIntro = params.get('intro') === '1' || params.get('replay') === '1';
271
272  /** Works on Google static hosting (platform.html) and FastAPI (/platform). */
273  function getNextUrl() {
274    if (params.get('next') === 'console') return '/console.html';
275    return '/platform.html?from=intro';
276  }
277
278  function clearIntroFlags() {
279    try {
280      sessionStorage.removeItem(INTRO_DONE_KEY);
281      sessionStorage.removeItem(INTRO_ATTEMPTS_KEY);
282    } catch (_) { /* ignore */ }
283  }
284
285  if (forceIntro) clearIntroFlags();
286
287  function showLoopHelp() {
288    document.body.innerHTML =
289      '<div style="min-height:100vh;display:flex;align-items:center;justify-content:center;padding:32px;
289background:#020208;color:#f0ede6;font-family:Montserrat,sans-serif;text-align:center">' +
290      '<div style="max-width:520px">' +
291      '<p style="font-size:11px;letter-spacing:0.2em;text-transform:uppercase;color:#00d4be;margin-bottom:16px">AETERNO</p>' +
292      '<h1 style="font-family:Cormorant Garamond,serif;font-size:28px;color:#c9a84c;font-weight:300;margin-bottom:16px">Opening platform…</h1>' +
293      '<p style="font-size:14px;line-height:1.7;color:rgba(240,237,230,0.75);margin-bottom:24px">' +
294      'If this stays stuck, open the platform directly or clear this site’s session and retry. ' +
295      'Make sure <code style="color:#c9a84c">platform.html</code> is uploaded to the <strong>aeternolife.ai</strong> bucket root (same place as index.html).</p>' +
296      '<p style="font-size:13px;display:flex;flex-direction:column;gap:12px;align-items:center">' +
297      '<a href="/platform.html?from=intro" style="color:#00d4be">Open /platform.html</a>' +
298      '<a href="/?intro=1" style="color:#c9a84c">Replay space intro</a>' +
299      '<button type="button" id="aeterno-clear-intro" style="background:#c9a84c;color:#020208;border:0;padding:12px 22px;letter-spacing:2px;text-transform:uppercase;font-size:10px;cursor:pointer">Clear &amp; retry intro</button>' +
300      '</p>' +
301      '</div></div>';
302    var btn = document.getElementById('aeterno-clear-intro');
303    if (btn) {
304      btn.addEventListener('click', function () {
305        clearIntroFlags();
306        window.location.replace('/?intro=1');
307      });
308    }
309  }
310
311  async function probePlatformThenHelp() {
312    try {
313      const res = await fetch('/platform.html?probe=' + Date.now(), { cache: 'no-store', redirect: 'follow' });
314      const text = await res.text();
315      const looksLikePlatform = /id=["']modules["']|id=["']ecosystem["']|hero-h1|Live Health Console/i.test(text);
316      const looksLikeIntro = /aeterno_intro_v1|space-canvas|Skip intro/i.test(text);
317      if (res.ok && looksLikePlatform && !looksLikeIntro) {
318        clearIntroFlags();
319        window.location.replace(getNextUrl());
320        return;
321      }
322    } catch (_) { /* fall through */ }
323    showLoopHelp();
324  }
325
326  (function guardIntroLoop() {
327    // After a completed intro in this tab session, skip straight to platform —
328    // unless user explicitly asked to replay (?intro=1).
329    if (forceIntro) return;
330    const attempts = parseInt(sessionStorage.getItem(INTRO_ATTEMPTS_KEY) || '0', 10) + 1;
331    sessionStorage.setItem(INTRO_ATTEMPTS_KEY, String(attempts));
332    if (sessionStorage.getItem(INTRO_DONE_KEY) === '1') {
333      if (attempts > 3) {
334        probePlatformThenHelp();
335        return;
336      }
337      window.location.replace(getNextUrl());
338      throw new Error('redirecting');
339    }
340  })();
341
342  function goToPlatform() {
343    if (redirected) return;
344    redirected = true;
345    sessionStorage.setItem(INTRO_DONE_KEY, '1');
346    var introEl = document.getElementById('intro');
347    if (introEl) introEl.classList.add('warp-out');
348    document.body.classList.add('warp-out');
349    stopAmbient();
350    setTimeout(function () { window.location.replace(getNextUrl()); }, 550);
351  }
352
353  var skipBtn = document.getElementById('skip-btn');
354  if (skipBtn) skipBtn.addEventListener('click', goToPlatform);
355  // Never use ~80ms — "reduce motion" OS setting was skipping the whole universe intro.
356  setTimeout(goToPlatform, reducedMotion ? INTRO_REDUCED_MS : INTRO_MS);
357
358  document.querySelectorAll('.vision-line').forEach((line) => {
359    const delay = parseInt(line.dataset.delay, 10) || 0;
360    setTimeout(() => line.classList.add('visible'), delay);
361  });
362
363  const canvas = document.getElementById('space-canvas');
364  const ctx = canvas.getContext('2d');
365  let particles = [], w, h, cx, cy, maxR, animId;
366  const introStart = performance.now();
367  const introDuration = reducedMotion ? INTRO_REDUCED_MS : INTRO_MS;
368
369  function warpProgress() {
370    return Math.min(1, (performance.now() - introStart) / introDuration);
371  }
372
373  function resize() {
374    w = canvas.width = window.innerWidth;
375    h = canvas.height = window.innerHeight;
376    cx = w / 2; cy = h / 2;
377    maxR = Math.hypot(cx, cy) * 1.15;
378    const count = Math.floor((w * h) / 900);
379    particles = Array.from({ length: count }, () =>
379 spawnParticle(true));
380  }
381
382  function spawnParticle(scattered) {
383    const angle = Math.random() * Math.PI * 2;
384    const radius = scattered ? Math.random() * maxR : Math.random() * maxR * 0.08;
385    const depth = Math.random();
386    return { angle, radius, depth, speed: 0.6 + depth * 1.4, size: 0.4 + depth * 1.8, cyan: Math.random() < 0.55 + depth * 0.25 };
387  }
388
389  function drawWarp() {
390    const progress = warpProgress();
391    const warp = 1 + progress * progress * 28;
392    const streak = 4 + progress * 22;
393    ctx.fillStyle = `rgba(2,2,8,${0.22 + progress * 0.35})`;
394    ctx.fillRect(0, 0, w, h);
395    const glowR = maxR * (0.12 + progress * 0.55);
396    const glow = ctx.createRadialGradient(cx, cy, 0, cx, cy, glowR);
397    glow.addColorStop(0, `rgba(255,255,255,${0.35 + progress * 0.55})`);
398    glow.addColorStop(0.12, `rgba(120,240,255,${0.25 + progress * 0.45})`);
399    glow.addColorStop(0.35, `rgba(0,180,220,${0.08 + progress * 0.2})`);
400    glow.addColorStop(1, 'rgba(2,2,8,0)');
401    ctx.fillStyle = glow;
402    ctx.fillRect(0, 0, w, h);
403    particles.forEach((p) => {
404      const spd = p.speed * warp * (0.35 + p.depth * 0.9);
405      const prevR = p.radius;
406      p.radius += spd;
407      if (p.radius > maxR) Object.assign(p, spawnParticle(false));
408      const x = cx + Math.cos(p.angle) * p.radius;
409      const y = cy + Math.sin(p.angle) * p.radius;
410      const px = cx + Math.cos(p.angle) * Math.max(0, prevR - streak * spd * 0.08);
411      const py = cy + Math.sin(p.angle) * Math.max(0, prevR - streak * spd * 0.08);
412      const alpha = (0.15 + p.depth * 0.75) * (1 - p.radius / maxR * 0.35);
413      if (progress > 0.2 && p.radius > 20) {
414        const grad = ctx.createLinearGradient(px, py, x, y);
415        grad.addColorStop(0, p.cyan ? 'rgba(0,212,230,0)' : 'rgba(255,255,255,0)');
416        grad.addColorStop(1, p.cyan ? `rgba(80,240,255,${alpha})` : `rgba(240,237,230,${alpha * 0.9})`);
417        ctx.strokeStyle = grad;
418        ctx.lineWidth = p.size * (0.8 + progress * 2.2);
419        ctx.lineCap = 'round';
420        ctx.beginPath();
421        ctx.moveTo(px, py);
422        ctx.lineTo(x, y);
423        ctx.stroke();
424      } else {
425        ctx.fillStyle = p.cyan ? `rgba(0,212,230,${alpha})` : `rgba(240,237,230,${alpha * 0.85})`;
426        ctx.beginPath();
427        ctx.arc(x, y, p.size * (0.5 + progress), 0, Math.PI * 2);
428        ctx.fill();
429      }
430    });
431    animId = requestAnimationFrame(drawWarp);
432  }
433
434  window.addEventListener('resize', resize);
435  resize();
436  drawWarp();
437
438  let audioCtx = null;
439  let ambientNodes = [];
440
441  function startAmbient() {
442    if (audioCtx) {
443      if (audioCtx.state === 'suspended') audioCtx.resume();
444      return;
445    }
446    try {
447      const AC = window.AudioContext || window.webkitAudioContext;
448      if (!AC) return;
449      audioCtx = new AC();
450      const master = audioCtx.createGain();
451      master.gain.setValueAtTime(0, audioCtx.currentTime);
452      master.gain.linearRampToValueAtTime(0.22, audioCtx.currentTime + 2);
453      master.connect(audioCtx.destination);
454      [55, 82.5, 110, 165].forEach((freq, i) => {
455        const osc = audioCtx.createOscillator();
456        const gain = audioCtx.createGain();
457        const lfo = audioCtx.createOscillator();
458        const lfoGain = audioCtx.createGain();
459        osc.type = i === 0 ? 'sine' : 'triangle';
460        osc.frequency.value = freq;
461        gain.gain.value = 0.08 / (i + 1);
462        lfo.frequency.value = 0.05 + i * 0.02;
463        lfoGain.gain.value = 0.03;
464        lfo.connect(lfoGain);
465        lfoGain.connect(gain.gain);
466        osc.connect(gain);
467        gain.connect(master);
468        osc.start();
469        lfo.start();
470        ambientNodes.push(osc, lfo);
471      });
472      const bufferSize = audioCtx.sampleRate * 2;
473      const noiseBuffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
474      const data = noiseBuffer.getChannelData(0);
475      for (let i = 0; i < bufferSize; i++) data[i] = (Math.random() * 2 - 1) * 0.3;
476      const noise = audioCtx.createBufferSource();
477      noise.buffer = noiseBuffer;
478      noise.loop = true;
479      const noiseFilter = audioCtx.createBiquadFilter();
480      noiseFilter.type = 'lowpass';
481      noiseFilter.frequency.value = 400;
482      const noiseGain = audioCtx.createGain();
483      noiseGain.gain.value = 0.04;
484      noise.connect(noiseFilter);
485      noiseFilter.connect(noiseGain);
486      noiseGain.connect(master);
487      noise.start();
488      ambientNodes.push(noise);
489      document.getElementById('audio-hint').classList.remove('show');
490    } catch (_) {}
491  }
492
493  function stopAmbient() {
494    ambientNodes.forEach((n) => { try { n.stop(); } catch (_) {} });
495    if (audioCtx) { audioCtx.close(); audioCtx = null; }
496  }
497
498  if (!reducedMotion) startAmbient();
499  document.addEventListener('pointerdown', startAmbient, { once: true });
500  setTimeout(() => {
501    if (!audioCtx || audioCtx.state === 'suspended') {
502      document.getElementById('audio-hint').classList.add('show');
503    }
504  }, 800);
505
506  window.addEventListener('beforeunload', () => {
507    cancelAnimationFrame(animId);
508    stopAmbient();
509  });
510})();
511</script>
vendor: 2 bytes, line 511
511
512<script src="aeterno-access.js"></script>
vendor: 2 bytes, line 512
512
513<script src="aeterno-pwa.js"></script>
vendor: 2 bytes, line 513
513
514<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"cddfe76281444a859168b3c4031e0968","r":1,"spa":2}' crossorigin="anonymous"></script>
514
515</body>
516</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.