Wunsch 27.08.2026: "soll nur noch hochwertiger und professioneller
aussehen." Kein neues Design, sondern die Details, die den Unterschied
zwischen "gemacht" und "gesetzt" ausmachen:
- Ueberschrift enger gesetzt (-.022em, Zeilenabstand 1.08, text-wrap:
balance). Bei 4rem wirkt normale Laufweite auseinandergefallen; die
drei Zeilen verteilen sich jetzt gleichmaessig statt mit kurzer
Restzeile.
- Jede Welt-Kachel traegt die Farbe IHRER Welt statt dreimal derselben:
Babyblau, Silber, das gedeckte Rot von Spicy Media. Die Werte sind
nicht erfunden, sondern die --accent-Toene der drei Themendateien.
- Plaketten ("WELT 1") klein, in Versalien, weit gesperrt -- liest sich
als Kapitelmarke statt als Beschriftung.
- Event-Karte: Datum als gesperrte Versalzeile (ordnet sich dem Titel
unter), "Mehr erfahren" als ruhiger Knopf statt nacktem Textlink,
Haarlinie am Bild, Text auf 5 Zeilen begrenzt -- damit nicht die
Textlaenge aus der Verwaltung das Aussehen der Startseite bestimmt und
bei zwei Events beide Kacheln gleich hoch sind (geprueft: 572/572px).
ZWEI FUNDE BEIM PRUEFEN, BEIDE WICHTIGER ALS DER FEINSCHLIFF:
1. INHALTSRICHTLINIE UND ZEILENENDEN. Der Browser rechnet die Pruefsumme
eines Inline-Skripts NICHT ueber die Bytes der Datei, sondern ueber
den Text im Dokument -- und der HTML-Parser ersetzt beim Einlesen
jedes CR LF durch LF (HTML-Spezifikation, "preprocessing the input
stream"). Eine Datei mit Windows-Zeilenenden ergibt serverseitig also
eine ANDERE Summe, und die Seite fuehrt ihr eigenes Skript nicht mehr
aus: kein Live-Status, keine Events, nichts. Live war es unauffaellig
(Linux-Auscheckung hat LF), auf dem Windows-Rechner sofort tot
(core.autocrlf=true). inhaltsrichtlinie.js vereinheitlicht jetzt vor
dem Rechnen auf LF -- das ist die Summe, die der Browser wirklich
bildet, und macht die Richtlinie unabhaengig davon, mit welchem
Werkzeug eine Datei zuletzt gespeichert wurde.
2. TESTS MIT FESTEM PORT KOENNEN LUEGEN. Drei Server aus frueheren
Laeufen liefen noch. Neue Testlaeufe konnten ihren Port nicht belegen,
starben still -- und massen weiter gegen den ALTEN Code. Ergebnis
waren Fehlermeldungen zu einem laengst behobenen Fehler. pruef-musik,
pruef-kasse und pruef-startseite suchen sich jetzt einen freien Port.
Neuer Test pruef-startseite.mjs (19 Pruefungen) mit FESTEN Event-Daten:
Beim Pruefen kam einmal nichts vom Server, der Abschnitt blieb leer und
der Test haette "kein Fehler" gemeldet, obwohl er nichts gesehen hat.
Geprueft werden Maske am Artwork, genau eine Kachel bei einem Event,
volle Breite, saubere Textkuerzung auf ganze Zeilen, eigene Weltfarben,
zwei gleich hohe Kacheln bei zwei Events, Handy ohne Ueberlauf.
Alles gruen: startseite 19, musik 17, kasse 15, inhaltsrichtlinie 22,
handy 56.
Co-Authored-By: Claude Opus 5 <[email protected]>
182 lines
9.3 KiB
HTML
182 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de" data-theme="dogfather">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Alle Links — DOGFATHER UNIVERSE</title>
|
|
<meta name="description" content="Alle Social-Media- und Musik-Links von DogFather an einem Ort — plus QR-Codes." />
|
|
<link rel="icon" type="image/png" href="assets/img/favicon.png" />
|
|
<link rel="manifest" href="/manifest.json" />
|
|
<meta name="theme-color" content="#0b0d10" />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:site_name" content="DOGFATHER UNIVERSE" />
|
|
<meta property="og:title" content="Alle Links — DOGFATHER UNIVERSE" />
|
|
<meta property="og:description" content="Alle Social-Media- und Musik-Links von DogFather an einem Ort — plus QR-Codes." />
|
|
<meta property="og:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
|
<meta property="og:url" content="https://dogfather-universe.com/links.html" />
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta name="twitter:title" content="Alle Links — DOGFATHER UNIVERSE" />
|
|
<meta name="twitter:description" content="Alle Social-Media- und Musik-Links von DogFather an einem Ort — plus QR-Codes." />
|
|
<meta name="twitter:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
|
|
|
<link rel="stylesheet" href="assets/css/main.css?v=20260828e" />
|
|
<link rel="stylesheet" href="assets/css/theme-dogfather.css?v=20260828e" />
|
|
<link rel="stylesheet" href="assets/css/theme-hasidog.css?v=20260828e" />
|
|
<link rel="stylesheet" href="assets/css/theme-spicymedia.css?v=20260828e" />
|
|
<style>
|
|
/* Rabattcodes: an das Supporter-Abo gekoppelt (Nutzer-Feedback
|
|
03.08.2026: "verbinde es mit dem Abo... wenn die Leute drauf drücken
|
|
wollen es nicht geht"). Eigener Knopf bleibt bestehen (führt weiter
|
|
eigenständig zu rabattcodes.html), wird aber nur für Supporter
|
|
tatsächlich anklickbar — sonst erscheint ein Hinweis mit Link zum Abo
|
|
statt der Navigation. Prüfung ist bewusst rein clientseitig (derselbe
|
|
zwischengespeicherte Login-Stand wie beim Nav-Abo-Knopf, siehe
|
|
renderAboButton() in main.js) — kein Aufruf-Zwang gegen den Worker bei
|
|
jedem Seitenaufruf, und da hier (noch) keine echten Rabattcodes
|
|
angezeigt werden, ist eine reine Client-Sperre für den jetzigen Stand
|
|
ausreichend statt eines vollen Server-Gates. */
|
|
.card-rabatt.gesperrt { cursor: not-allowed; }
|
|
.card-rabatt.gesperrt:hover { transform: none; }
|
|
.rabatt-gesperrt-hinweis {
|
|
display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
|
|
max-width: 1040px; margin: 1rem auto 0; padding: 1rem 1.4rem; border-radius: 12px;
|
|
border: 1.5px solid rgba(212,175,55,.4); background: rgba(212,175,55,.08); color: #ffe9a8;
|
|
}
|
|
.rabatt-gesperrt-hinweis[hidden] { display: none; }
|
|
.rabatt-gesperrt-hinweis p { color: #ffe9a8; margin: 0; flex: 1 1 260px; font-size: .95rem; }
|
|
</style>
|
|
</head>
|
|
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-links-seite.jpg');--page-bg-mobile:url('/assets/img/bg-links-seite-mobile.jpg');">
|
|
<div id="site-header"></div>
|
|
|
|
<main>
|
|
<section class="hero page-bg">
|
|
<div class="hero-banner"><img src="/assets/img/bg-links-seite.jpg" alt="" loading="eager" /></div>
|
|
<div class="container">
|
|
<span class="eyebrow" data-i18n="lk_eyebrow">🩵 Alle Links</span>
|
|
<h1 data-i18n="lk_h1">Alles an einem Ort</h1>
|
|
<p class="lead worlds" data-i18n="lk_lead">Ersatz für die Wonderlink-Seite — direkt Teil vom DOGFATHER UNIVERSE.</p>
|
|
<!-- Unsichtbare Gruppenüberschrift: Die folgenden Kacheln (Rabattcodes,
|
|
Kanäle, Shop …) sind <h3>. Ohne eine h2 dazwischen entstünde ein
|
|
Sprung h1 -> h3 in der Überschriftenordnung. Diese h2 ist nur für
|
|
Bildschirmleser da und ändert die Optik nicht (siehe .sr-only). -->
|
|
<h2 class="sr-only">Meine Kanäle und Angebote</h2>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section-tight" style="padding-bottom:0;">
|
|
<div class="container">
|
|
<div style="max-width:1040px;margin:0 auto;">
|
|
<a class="card card-brand card-feature card-feature-wide card-rabatt" href="rabattcodes.html" id="card-rabattcodes">
|
|
<span class="card-feature-ring" aria-hidden="true"></span>
|
|
<span class="card-feature-badge" id="rabatt-badge" data-i18n="lk_rabatt_badge">🔒 Nur für Supporter</span>
|
|
<span class="icon-badge">🏷️</span>
|
|
<span class="card-feature-text">
|
|
<h3 data-i18n="lk_rabatt_h3">Rabattcodes</h3>
|
|
<p class="card-feature-desc" data-i18n="lk_rabatt_desc">Codes von Dogis Partnern — exklusiv für Dogfather-Supporter.</p>
|
|
</span>
|
|
</a>
|
|
<div class="rabatt-gesperrt-hinweis" id="rabatt-gesperrt-hinweis" hidden>
|
|
<p data-i18n="lk_rabatt_gesperrt_hinweis">🔒 Rabattcodes sind nur für Dogfather-Supporter zugänglich. Werde jetzt Supporter, um sie freizuschalten.</p>
|
|
<a class="btn btn-primary" href="abonnieren.html" data-i18n="lk_rabatt_btn_abo">Jetzt Supporter werden 👑</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section-tight">
|
|
<div class="container">
|
|
<div class="grid grid-3" style="max-width:1040px;margin:0 auto;">
|
|
<a class="card card-brand card-tiktok text-center" href="https://www.tiktok.com/@dogfather0804" target="_blank" rel="noopener">
|
|
<span class="icon-badge">🎥</span>
|
|
<h3>TikTok</h3>
|
|
<p>@dogfather0804</p>
|
|
</a>
|
|
<a class="card card-brand card-instagram text-center" href="https://www.instagram.com/sf0118?igsh=MWo2eXFlcXFicXN5OQ==" target="_blank" rel="noopener">
|
|
<span class="icon-badge">📸</span>
|
|
<h3>Instagram</h3>
|
|
<p>@sf0118</p>
|
|
</a>
|
|
<a class="card card-brand card-snapchat text-center" href="https://www.snapchat.com/add/dogfather0804?share_id=m8mR6ylEtLo&locale=de-DE" target="_blank" rel="noopener">
|
|
<span class="icon-badge">👻</span>
|
|
<h3>Snapchat</h3>
|
|
<p>@dogfather0804</p>
|
|
</a>
|
|
<a class="card card-brand card-discord text-center" href="kontakt.html">
|
|
<span class="icon-badge">💬</span>
|
|
<h3>Discord</h3>
|
|
<p class="small muted" data-i18n="lk_discord_hint">Nur auf Anfrage</p>
|
|
</a>
|
|
<a class="card card-brand card-shop text-center" href="#" target="_blank" rel="noopener">
|
|
<span class="icon-badge">🛒</span>
|
|
<h3 data-i18n="lk_shop_h3">Merchandise / Shop</h3>
|
|
<p class="small muted" data-i18n="lk_shop_hint">Folgt in Kürze</p>
|
|
</a>
|
|
<a class="card card-brand card-bewerben text-center" href="bewerben.html">
|
|
<span class="icon-badge">📝</span>
|
|
<h3 data-i18n="lk_bewerben_h3">Bewerben</h3>
|
|
<p data-i18n="lk_bewerben_p">Modi, Scout, Creator oder Kooperation</p>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section>
|
|
<div class="container">
|
|
<h2 class="text-center" data-i18n="lk_qr_h2">QR-Codes</h2>
|
|
<div class="grid grid-3" style="max-width:800px;margin:0 auto;">
|
|
<div class="card qr-card">
|
|
<img src="assets/qr/qr-instagram.png" alt="QR-Code Instagram @sf0118" style="width:160px;height:160px;object-fit:contain;margin:0 auto 1rem;border-radius:10px;display:block;" />
|
|
<p class="small">Instagram</p>
|
|
</div>
|
|
<div class="card qr-card">
|
|
<img src="assets/qr/qr-snapchat.png" alt="QR-Code Snapchat dogfather0804" style="width:160px;height:160px;object-fit:contain;margin:0 auto 1rem;border-radius:10px;display:block;" />
|
|
<p class="small">Snapchat</p>
|
|
</div>
|
|
<div class="card qr-card">
|
|
<img src="assets/qr/qr-teilen-baustein.png" alt="QR-Code Dogis persönlicher Teilen-Baustein" style="width:160px;height:160px;object-fit:contain;margin:0 auto 1rem;border-radius:10px;display:block;" />
|
|
<p class="small" data-i18n="lk_qr_teilen">Dogis persönlicher Teilen-Baustein</p>
|
|
</div>
|
|
</div>
|
|
<!-- TODO: Shop noch mit echter URL befüllen, sobald vorhanden. Discord ist bewusst "nur auf Anfrage" (kein offener Link) und führt zur Kontaktseite. -->
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<div id="site-footer"></div>
|
|
<script src="assets/js/i18n-links.js?v=20260828e"></script>
|
|
<script src="assets/js/main.js?v=20260828e"></script>
|
|
<script>
|
|
(function () {
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
var karte = document.getElementById("card-rabattcodes");
|
|
var badge = document.getElementById("rabatt-badge");
|
|
var hinweis = document.getElementById("rabatt-gesperrt-hinweis");
|
|
if (!karte) return;
|
|
|
|
// Gleicher zwischengespeicherter Login-/Abo-Stand wie beim Nav-Abo-
|
|
// Knopf (renderAboButton() in main.js) — kein API-Aufruf bei jedem
|
|
// Seitenaufruf nötig.
|
|
var status = localStorage.getItem("supporterSubStatus");
|
|
var hatAbo = ["active", "pending", "suspended", "cancelled"].indexOf(status) !== -1;
|
|
|
|
if (hatAbo) {
|
|
karte.classList.remove("gesperrt");
|
|
if (badge && window.dogiUebersetzen) badge.textContent = window.dogiUebersetzen("lk_rabatt_badge_frei");
|
|
return;
|
|
}
|
|
|
|
karte.classList.add("gesperrt");
|
|
karte.addEventListener("click", function (e) {
|
|
e.preventDefault();
|
|
if (!hinweis) return;
|
|
hinweis.hidden = false;
|
|
hinweis.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|