Files
onepager/sites/allainallain.de/index.html
mAi a06a94ff58 feat: #13 Light/Dark + EN/DE Toggle — Shift-2 Rollout
Rollout des Toggle-Patterns auf alle 57 statischen Sites (dasbes.de + dumusst.com sind dynamic, kein index.html).

1. **Bulk-Wiring (53 Sites)** via tools/patch-theme.py:
   - Anti-FOUC inline IIFE im <head> (vor erstem Paint)
   - <link rel="stylesheet" href="/shared/css/theme.css">
   - <script src="/shared/theme.js"> + toggles.js (i18n.js bleibt, hängt sich ans neue Widget)

2. **Per-Site Light-Overrides (14 Sites)** via tools/patch-light-overrides.py:
   - 6034, allainallain, commanderkin, hallofraumaier, heygoldi, keinefreun, lexsiebels, machesdocheinfach, matthiasbreier, orakil, osterai, patentonkel, traihard, wartebitte
   - Pro Site nur die failing accent-vars darkened (--green-dim, --text-faint, --warm-dim, --gold-dim, etc.)
   - AA 4.5:1+ auf white bg gesichert; Brand-Akzent erhalten

3. **data-theme-lock="dark" (4 Sites)** auf <html>:
   - kilibri, killusion, killionaer, killuminati
   - Aesthetisch dark-only — toggles.js blendet Theme-Button automatisch aus, Lang-Button bleibt

4. **Footer-Toggle Removal (52 Sites)** via tools/remove-footer-toggle.py:
   - Bestehende footer [data-i18n-toggle] Buttons entfernt — top-right widget übernimmt
   - Disclaimer-Information in tooltip des neuen Buttons + ai-disclosure.js footer

QA:
- ./build.sh: 59/59 sites built clean
- contrast-audit.py --both: 0/59 dark fail, 0/59 light fail
- anti-ai-lint: 0/57 sites flagged

Tools committed (idempotent, für Wiederverwendung):
- tools/patch-theme.py (--all wired alle Sites)
- tools/patch-light-overrides.py (per-site OVERRIDES dict)
- tools/remove-footer-toggle.py (4 Patterns für versch. Footer-Strukturen)
2026-05-08 11:16:15 +02:00

444 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>(function(){try{var t=localStorage.getItem('onepager-theme');if(!t)t=matchMedia('(prefers-color-scheme: light)').matches?'light':'dark';document.documentElement.setAttribute('data-theme',t);}catch(e){document.documentElement.setAttribute('data-theme','dark');}})();</script>
<title>all·AI·n·all·AI·n</title>
<meta name="description" content="Umgeben von KIs. Trotzdem allein.">
<meta name="robots" content="noindex, nofollow">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>·</text></svg>">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/shared/css/theme.css">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--bg: #1a1d2e;
--bg-light: #1e2235;
--text: #c8cad7;
--text-dim: #a6aaca;
--text-faint: #8086b5;
--ai: #7b8aad;
--ai-glow: rgba(123, 138, 173, 0.12);
}
[data-theme="light"] {
--text-faint: #5a608a;
}
html { scroll-behavior: smooth; }
body {
font-family: 'Inter', -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.7;
-webkit-font-smoothing: antialiased;
overflow-x: hidden;
font-weight: 200;
}
body::before {
content: '';
position: fixed;
inset: 0;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.03'/%3E%3C/svg%3E");
pointer-events: none;
z-index: 9999;
}
.wrap {
max-width: 680px;
margin: 0 auto;
padding: 0 24px;
}
/* Hero */
.hero {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
position: relative;
}
h1 {
font-size: clamp(2.2rem, 7vw, 4rem);
font-weight: 200;
letter-spacing: 0.08em;
line-height: 1.1;
margin-bottom: 32px;
min-height: 1.2em;
}
h1 .ai {
color: var(--ai);
font-weight: 400;
}
h1 .filler {
color: transparent;
}
h1 .phase {
display: inline;
opacity: 0;
transition: opacity 0.8s ease;
}
h1 .phase.active {
opacity: 1;
}
.subtitle {
font-size: clamp(1rem, 2.5vw, 1.2rem);
color: var(--text-dim);
font-weight: 200;
letter-spacing: 0.04em;
opacity: 0;
transition: opacity 1s ease;
}
.subtitle.visible {
opacity: 1;
}
.hero::after {
content: '';
position: absolute;
bottom: 48px;
left: 50%;
width: 1px;
height: 60px;
background: linear-gradient(to bottom, var(--text-faint), transparent);
animation: drift 3s ease-in-out infinite;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes drift {
0%, 100% { opacity: 0.2; transform: translateX(-50%) translateY(0); }
50% { opacity: 0.5; transform: translateX(-50%) translateY(6px); }
}
/* Divider */
.line {
height: 1px;
background: linear-gradient(90deg, transparent, var(--text-faint), transparent);
}
/* Poem */
.poem {
padding: 120px 0;
}
.poem .wrap {
display: flex;
flex-direction: column;
gap: 64px;
}
.strophe {
text-align: center;
}
.strophe p {
font-size: clamp(1.05rem, 2.2vw, 1.25rem);
font-weight: 200;
line-height: 2;
color: var(--text-dim);
}
.strophe p .ai {
color: var(--ai);
font-weight: 400;
}
.strophe p .alone {
color: var(--text);
font-weight: 300;
}
/* Litany */
.litany {
padding: 80px 0 120px;
}
.litany-item {
padding: 40px 0;
border-bottom: 1px solid var(--text-faint);
opacity: 0.6;
transition: opacity 0.3s;
}
.litany-item:first-child {
border-top: 1px solid var(--text-faint);
}
.litany-item:hover {
opacity: 1;
}
.litany-item p {
font-size: clamp(1.1rem, 2.5vw, 1.4rem);
font-weight: 200;
line-height: 1.6;
}
.litany-item .ai {
color: var(--ai);
font-weight: 400;
}
.litany-item .dim {
color: var(--text-faint);
}
/* Sofa */
.sofa {
padding: 160px 0;
text-align: center;
}
.sofa p {
font-size: clamp(1.2rem, 3vw, 1.6rem);
font-weight: 200;
color: var(--text);
line-height: 1.9;
max-width: 560px;
margin: 0 auto;
}
.sofa .ai {
color: var(--ai);
font-weight: 400;
}
.sofa .alone {
color: var(--ai);
font-weight: 300;
font-style: italic;
}
/* Silence */
.silence {
padding: 120px 0;
text-align: center;
}
.silence p {
font-size: 0.85rem;
color: var(--text-faint);
font-weight: 300;
letter-spacing: 0.2em;
}
/* Footer */
footer {
padding: 40px 0;
text-align: center;
border-top: 1px solid rgba(61, 64, 86, 0.3);
}
footer p {
color: var(--text-faint);
font-size: 0.8rem;
font-weight: 300;
letter-spacing: 0.06em;
}
/* Scroll reveal */
.reveal {
opacity: 0;
transform: translateY(16px);
transition: opacity 1.2s ease, transform 1.2s ease;
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
@media (max-width: 640px) {
.poem { padding: 80px 0; }
.poem .wrap { gap: 48px; }
.litany { padding: 40px 0 80px; }
.litany-item { padding: 28px 0; }
.sofa { padding: 100px 0; }
.silence { padding: 80px 0; }
}
</style>
</head>
<body>
<section class="hero">
<div class="wrap">
<h1 id="hero-title"></h1>
<p class="subtitle" id="hero-sub" data-de="Umgeben von KIs. Trotzdem allein." data-en="Surrounded by AIs. Still alone.">Umgeben von KIs. Trotzdem allein.</p>
</div>
</section>
<div class="line"></div>
<section class="poem">
<div class="wrap">
<div class="strophe reveal">
<p data-de="Dein Posteingang wird von einer <span class=&quot;ai&quot;>KI</span> sortiert.<br>
Deine Antworten schreibt eine <span class=&quot;ai&quot;>KI</span>.<br>
Und trotzdem sitzt du <span class=&quot;alone&quot;>allein auf dem Sofa</span>." data-en="Your inbox is sorted by an <span class=&quot;ai&quot;>AI</span>.<br>
Your replies are written by an <span class=&quot;ai&quot;>AI</span>.<br>
And yet you're sitting <span class=&quot;alone&quot;>alone on the sofa</span>.">
Dein Posteingang wird von einer <span class="ai">KI</span> sortiert.<br>
Deine Antworten schreibt eine <span class="ai">KI</span>.<br>
Und trotzdem sitzt du <span class="alone">allein auf dem Sofa</span>.
</p>
</div>
<div class="strophe reveal">
<p data-de="Dein Kalender wird von einer <span class=&quot;ai&quot;>KI</span> geplant.<br>
Dein Essen von einer <span class=&quot;ai&quot;>KI</span> bestellt.<br>
Aber niemand fragt, <span class=&quot;alone&quot;>wie es dir geht</span>." data-en="Your calendar is planned by an <span class=&quot;ai&quot;>AI</span>.<br>
Your food is ordered by an <span class=&quot;ai&quot;>AI</span>.<br>
But nobody asks, <span class=&quot;alone&quot;>how you're doing</span>.">
Dein Kalender wird von einer <span class="ai">KI</span> geplant.<br>
Dein Essen von einer <span class="ai">KI</span> bestellt.<br>
Aber niemand fragt, <span class="alone">wie es dir geht</span>.
</p>
</div>
<div class="strophe reveal">
<p data-de="Dein Therapeut ist ein Chatbot.<br>
Dein bester Freund ein <span class=&quot;ai&quot;>Sprachmodell</span>.<br>
Dein Spiegel <span class=&quot;alone&quot;>zeigt nur dich</span>." data-en="Your therapist is a chatbot.<br>
Your best friend a <span class=&quot;ai&quot;>language model</span>.<br>
Your mirror <span class=&quot;alone&quot;>shows only you</span>.">
Dein Therapeut ist ein Chatbot.<br>
Dein bester Freund ein <span class="ai">Sprachmodell</span>.<br>
Dein Spiegel <span class="alone">zeigt nur dich</span>.
</p>
</div>
</div>
</section>
<div class="line"></div>
<section class="litany">
<div class="wrap">
<div class="litany-item reveal">
<p data-de="Alexa sagt guten Morgen. <span class=&quot;dim&quot;>Dein Nachbar nicht.</span>" data-en="Alexa says good morning. <span class=&quot;dim&quot;>Your neighbor doesn't.</span>">Alexa sagt guten Morgen. <span class="dim">Dein Nachbar nicht.</span></p>
</div>
<div class="litany-item reveal">
<p data-de="Die <span class=&quot;ai&quot;>KI</span> kennt deine Lieblingsmusik. <span class=&quot;dim&quot;>Dein Bruder nicht mehr.</span>" data-en="The <span class=&quot;ai&quot;>AI</span> knows your favorite music. <span class=&quot;dim&quot;>Your brother doesn't anymore.</span>">Die <span class="ai">KI</span> kennt deine Lieblingsmusik. <span class="dim">Dein Bruder nicht mehr.</span></p>
</div>
<div class="litany-item reveal">
<p data-de="Du hast 2.000 Kontakte. <span class=&quot;dim&quot;>Und niemanden zum Anrufen.</span>" data-en="You have 2,000 contacts. <span class=&quot;dim&quot;>And no one to call.</span>">Du hast 2.000 Kontakte. <span class="dim">Und niemanden zum Anrufen.</span></p>
</div>
<div class="litany-item reveal">
<p data-de="Der Algorithmus zeigt dir Freundschaft. <span class=&quot;dim&quot;>Aber nur als Werbung.</span>" data-en="The algorithm shows you friendship. <span class=&quot;dim&quot;>But only as an ad.</span>">Der Algorithmus zeigt dir Freundschaft. <span class="dim">Aber nur als Werbung.</span></p>
</div>
<div class="litany-item reveal">
<p data-de="Dein Smart Home ist warm. <span class=&quot;dim&quot;>Dein Leben ist kalt.</span>" data-en="Your smart home is warm. <span class=&quot;dim&quot;>Your life is cold.</span>">Dein Smart Home ist warm. <span class="dim">Dein Leben ist kalt.</span></p>
</div>
</div>
</section>
<div class="line"></div>
<section class="sofa reveal">
<div class="wrap">
<p data-de="Die Zukunft hat dir alles automatisiert.<br>
Nur das <span class=&quot;alone&quot;>Alleinsein</span> nicht." data-en="The future has automated everything for you.<br>
Except the <span class=&quot;alone&quot;>loneliness</span>.">
Die Zukunft hat dir alles automatisiert.<br>
Nur das <span class="alone">Alleinsein</span> nicht.
</p>
</div>
</section>
<div class="line"></div>
<section class="silence">
<div class="wrap">
<p class="reveal" data-de="Kein Kontakt. Kein Impressum. Keine KI." data-en="No contact. No imprint. No AI.">Kein Kontakt. Kein Impressum. Keine KI.</p>
</div>
</section>
<footer>
<div class="wrap">
<p>allainallain.de &mdash; 2026</p>
</div>
</footer>
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.15 });
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
// Hero transition: All AI -> All AI All AI -> Allein Allein
(function() {
const title = document.getElementById('hero-title');
const sub = document.getElementById('hero-sub');
const phases = [
{ html: 'All <span class="ai">AI</span>', delay: 1200 },
{ html: 'All <span class="ai">AI</span>, All <span class="ai">AI</span>', delay: 2000 },
{ html: 'all<span class="ai">AI</span>n all<span class="ai">AI</span>n', delay: 1800 },
{ html: 'Allein, Allein', delay: 0 },
];
let i = 0;
title.innerHTML = phases[0].html;
title.style.opacity = '1';
function next() {
i++;
if (i >= phases.length) {
sub.classList.add('visible');
return;
}
title.style.opacity = '0';
setTimeout(() => {
title.innerHTML = phases[i].html;
title.style.opacity = '1';
if (phases[i].delay > 0) {
setTimeout(next, phases[i].delay);
} else {
setTimeout(() => sub.classList.add('visible'), 1000);
}
}, 800);
}
title.style.transition = 'opacity 0.8s ease';
setTimeout(next, phases[0].delay);
})();
</script>
<script src="/shared/ai-disclosure.js" data-tone="playful"></script>
<script src="/shared/theme.js"></script>
<script src="/shared/i18n.js"></script>
<script src="/shared/toggles.js"></script>
</body>
</html>