feat: brutalist placeholder site for 0012.de root

Replace ops beacon with sarcastic standalone landing page, centered
layout, no leaked data; update SITE.md that monitoring lives elsewhere.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Frank Schwenk
2026-06-11 23:39:23 +02:00
parent 01de7ed4fb
commit 3558739e07
2 changed files with 225 additions and 96 deletions
+212 -53
View File
@@ -2,79 +2,238 @@
declare(strict_types=1);
require_once dirname(__DIR__) . '/private/config/bootstrap.php';
$domain = env('DOMAIN', '0012.de');
$bokaIp = env('BOKA_IP', '89.163.231.180');
$checksFile = privateDataDir() . '/last-checks.json';
$checks = is_readable($checksFile)
? json_decode((string) file_get_contents($checksFile), true)
: null;
$lastRun = is_array($checks) && isset($checks['updated_at'])
? $checks['updated_at']
: null;
header('Content-Type: text/html; charset=utf-8');
header('X-Robots-Tag: noindex');
$jahr = (int) date('Y');
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($domain, ENT_QUOTES, 'UTF-8') ?> · external observer</title>
<title>0012</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #0d1117;
--text: #c9d1d9;
--muted: #8b949e;
--accent: #58a6ff;
--warn: #d29922;
--ok: #3fb950;
--bg: #0a0a0a;
--fg: #e8e8e8;
--dim: #666;
--line: #333;
--acid: #c8ff00;
--blood: #ff2a2a;
}
* { box-sizing: border-box; }
html { font-size: 16px; }
body {
margin: 0;
min-height: 100vh;
background: var(--bg);
color: var(--text);
font-family: ui-monospace, "Cascadia Code", "JetBrains Mono", monospace;
line-height: 1.5;
padding: 2rem 1.25rem 3rem;
color: var(--fg);
font-family: "IBM Plex Mono", "Courier New", monospace;
line-height: 1.45;
padding: 0 clamp(1rem, 4vw, 3rem);
}
main { max-width: 42rem; margin: 0 auto; }
h1 { font-size: 1.25rem; font-weight: 600; margin: 0 0 0.25rem; letter-spacing: 0.04em; }
.tagline { color: var(--muted); margin: 0 0 2rem; font-size: 0.9rem; }
.panel {
border: 1px solid #30363d;
border-radius: 8px;
padding: 1.25rem 1.5rem;
background: #161b22;
.wrap {
width: 100%;
max-width: 42rem;
margin: 0 auto;
min-height: 100vh;
border-left: 4px solid var(--acid);
border-right: 1px solid var(--line);
}
header {
border-bottom: 1px solid var(--line);
padding: 2rem 1.5rem 1.5rem;
}
.logo {
font-size: clamp(4rem, 18vw, 9rem);
font-weight: 700;
letter-spacing: -0.06em;
line-height: 0.85;
color: var(--fg);
}
.logo span { color: var(--acid); }
.claim {
margin-top: 1rem;
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.2em;
color: var(--dim);
}
section {
border-bottom: 1px solid var(--line);
padding: 1.5rem;
}
h2 {
font-size: 0.7rem;
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.25em;
color: var(--dim);
margin-bottom: 1rem;
}
p { margin-bottom: 0.75rem; }
p:last-child { margin-bottom: 0; }
.blink {
animation: blink 1.2s step-end infinite;
color: var(--blood);
}
@keyframes blink { 50% { opacity: 0; } }
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
border: 1px solid var(--line);
}
@media (max-width: 520px) {
.grid { grid-template-columns: 1fr; }
.cell { border-right: none; }
}
.cell {
padding: 1rem 1.25rem;
border-right: 1px solid var(--line);
border-bottom: 1px solid var(--line);
font-size: 0.8rem;
}
.cell:nth-child(2n) { border-right: none; }
.cell strong {
display: block;
font-size: 0.65rem;
letter-spacing: 0.15em;
text-transform: uppercase;
color: var(--dim);
margin-bottom: 0.4rem;
}
.cell em { color: var(--acid); font-style: normal; }
.cell s { color: var(--dim); }
blockquote {
border-left: 3px solid var(--blood);
padding: 0 0 0 1rem;
color: var(--dim);
font-size: 0.9rem;
}
.meter {
display: flex;
align-items: stretch;
height: 12px;
border: 1px solid var(--line);
margin-top: 0.5rem;
}
.meter-fill {
width: 3%;
background: var(--acid);
}
.meter-rest {
flex: 1;
background: repeating-linear-gradient(
90deg,
var(--line) 0,
var(--line) 2px,
transparent 2px,
transparent 6px
);
}
footer {
padding: 1.5rem;
font-size: 0.7rem;
color: var(--dim);
letter-spacing: 0.05em;
}
footer a { color: var(--dim); }
.cursor {
display: inline-block;
width: 0.55em;
height: 1em;
background: var(--fg);
vertical-align: text-bottom;
margin-left: 2px;
animation: blink 0.9s step-end infinite;
}
.warn {
background: var(--blood);
color: var(--bg);
padding: 0.35rem 0.6rem;
font-size: 0.65rem;
text-transform: uppercase;
letter-spacing: 0.12em;
display: inline-block;
margin-bottom: 1rem;
}
.status { color: var(--warn); margin: 0 0 0.75rem; }
.status.ok { color: var(--ok); }
.meta { color: var(--muted); font-size: 0.85rem; margin: 1.5rem 0 0; }
code { color: var(--accent); }
</style>
</head>
<body>
<main>
<h1>0012</h1>
<p class="tagline">external observer node · watching from outside</p>
<div class="wrap">
<header>
<div class="logo">00<span>12</span></div>
<p class="claim">Eine Website · kein Inhalt · keine Entschuldigung</p>
</header>
<div class="panel">
<?php if ($lastRun): ?>
<p class="status ok">Monitoring active — last check <?= htmlspecialchars($lastRun, ENT_QUOTES, 'UTF-8') ?></p>
<?php else: ?>
<p class="status">Monitoring not initialized — awaiting first cron run</p>
<?php endif; ?>
<p class="meta">
Node <code><?= htmlspecialchars($domain, ENT_QUOTES, 'UTF-8') ?></code>
· independent of boka (<code><?= htmlspecialchars($bokaIp, ENT_QUOTES, 'UTF-8') ?></code>)
<section>
<div class="warn">Status: unbelegt</div>
<p>
Willkommen auf 0012.de. Hier entsteht irgendwann etwas.
Was genau, ist noch nicht entschieden — und das ist halb Strategie, halb Bequemlichkeit.
</p>
</div>
</main>
</section>
<section>
<h2>Was wir anbieten</h2>
<div class="grid">
<div class="cell">
<strong>Produkt</strong>
<s>Alles</s> Noch nichts.<br>
Aber mit Überzeugung.
</div>
<div class="cell">
<strong>Support</strong>
Schreiben Sie an die Leere.<br>
Antwortzeit: <em>∞</em>
</div>
<div class="cell">
<strong>Preise</strong>
Kostenlos.<br>
Der Preis ist Ihre Zeit, die Sie gerade verschwenden.
</div>
<div class="cell">
<strong>Datenschutz</strong>
Wir sammeln nichts.<br>
Nicht aus Tugend — aus Inkompetenz.
</div>
</div>
</section>
<section>
<h2>Roadmap <?= $jahr ?>–<?= $jahr + 3 ?></h2>
<p>Q1 — Idee haben<br>Q2 — Idee vergessen<br>Q3 — Diese Seite<br>Q4 — Sie lesen das</p>
<p>Fortschritt zur „finalen Vision“:</p>
<div class="meter"><div class="meter-fill"></div><div class="meter-rest"></div></div>
<p style="margin-top:0.5rem;font-size:0.75rem;color:var(--dim);">3 % · gerundet von 0 %</p>
</section>
<section>
<h2>Pressestimmen (intern)</h2>
<blockquote>
„Sieht aus wie eine Website.“ — Entwickler, bezahlt<br><br>
„0012 — eine Zahl vor dem Fehler.“ — Logfile, 03:14 Uhr<br><br>
„Wenigstens keine Comic Sans.“ — Besucher mit Standards
</blockquote>
</section>
<section>
<h2>Live</h2>
<p>
<span class="blink">■</span>
System operational · Inhalt pending · Bedeutung not found
<span class="cursor"></span>
</p>
<p style="font-size:0.8rem;color:var(--dim);margin-top:1rem;">
Keine IPs. Keine Tokens. Nichts auf dem Server, der Ihnen zulächelt.
Nur diese Seite — und Ihr schlechtes Gewissen, noch nicht weiterzuklicken.
</p>
</section>
<footer>
© <?= $jahr ?> 0012.de · Impressum folgt, wenn jemand klagt
</footer>
</div>
</body>
</html>