Die Rabattcodeseite war ein Platzhalter -- "Codes folgen in Kuerze" und
darunter eine Vorschaukachel mit dem erfundenen Code "DOGFATHER". Jetzt
steht der erste echte drauf: DOGI10 fuer Van's DIY & Bastelbedarf,
verlinkt auf vans-diy-bastelbedarf.com.
DIE KONDITIONEN SIND ABGELESEN, NICHT GERATEN.
Aus "DOGI10" auf zehn Prozent zu schliessen, waere naheliegend gewesen,
haette zufaellig gestimmt und waere trotzdem falsch gewesen. Nachgesehen
im Shop selbst (src/content/partnercodes.json):
{ "code": "DOGI10", "prozent": 10, "bis": "2026-09-30",
"aktiv": true, "giltAufSale": false }
Zwei der drei Angaben stehen im Namen NICHT drin: dass der Code am
30.09.2026 auslaeuft und dass er auf bereits reduzierte Artikel nicht
gilt. Beides steht jetzt sichtbar auf der Karte. Eine falsche Zusage auf
einer Verkaufsseite kostet VanVan die Diskussion an der Kasse.
Gegengeprueft, dass die Datei auch wirklich gilt und kein Ueberbleibsel
ist: Sie wird an zwei Stellen ausgewertet, src/scripts/cart.ts fuer den
Warenkorb und server/lib/preis-berechnen.js fuer den Endpreis, beide mit
derselben Regel (aktiv !== false UND jetzt <= bis 23:59:59).
DAS ABLAUFDATUM IST EINE ZEITBOMBE, ALSO BEKOMMT ES EINEN ZUENDER.
Ein fest eingetippter Satz "gueltig bis 30.09.2026" stimmt, bis der
Kalender ihn ueberholt -- ab dem 01.10. verspraeche die Seite etwas, das
der Shop schon ablehnt. Genau dieselbe Falle hat am 06.09. den
Oeffnungstest im Shop umgeworfen. Das Datum steht deshalb nicht nur im
Text, sondern einmal als Zahl im Skript: Ist es vorbei, schaltet die
Karte selbsttaetig auf "abgelaufen", streicht den Code durch und sperrt
den Kopierknopf, statt weiter zu werben.
DAS LOGO: AUS EINEM SIEGEL WIRD EINE MUENZE.
Filipe hat das Logo als Bildschirmfoto aus TikTok geliefert, rundes
Siegel auf schwarzem Grund. Ungestellt waere daraus auf der dunklen
Karte ein sichtbarer schwarzer Kasten geworden -- derselbe Fehler wie
bei der Workspace-Marke, deren Zahlen damals tadellos aussahen.
Freigestellt wird per Flutfuellung vom Bildrand (tools/partner-siegel-
freistellen.mjs, 384 px WebP, 37 KB). Eine Kreismaske waere hier sogar
ausrechenbar gewesen -- Mitte 539,5/526,5, Radius 495 -- und haette
genau fuer dieses eine Bild funktioniert. Die Fuellung MISST die Form,
statt sie vorauszusetzen: Der naechste Partner ist ein Eintrag in
AUFTRAEGE und sonst nichts. Die Quelle liegt mit im Repo, sonst laesst
sich das Werkzeug genau einmal ausfuehren und ist danach Dekoration.
"Extrem speziell" fuehrt hier NICHT ueber mehr Farbe -- das Siegel ist
schwarz-weiss, jede Einfaerbung lackierte eine fremde Marke um. Es
fuehrt ueber mehr Material: sechs CSS-Lagen, kein zweites Bild.
Aura weicher Lichthof, atmet in 9 s
Raendel die geriffelte Muenzkante, 72 Zaehne. Sie steht STILL --
eine sich drehende Riffelung flimmert bei 148 px, und das
waere genau die grelle Optik, die die Hausregel ausschliesst
Glanz stattdessen wandert EIN Lichtpunkt in 22 s um die Kante.
Das ist die Bewegung, die eine Muenze im Licht macht
Schliff Praegekante nach innen, oben Licht, unten Schatten
Ablage elliptischer Schatten, damit die Muenze auf der Karte LIEGT
Bei prefers-reduced-motion steht alles davon still.
NEBENBEFUND, DER SONST NIEMANDEM AUFGEFALLEN WAERE: Der Text auf der
Sperrkachel endete auf "sobald die ersten Kooperationen live sind".
Seit heute IST die erste live -- der Satz haette jemanden dafuer zahlen
lassen, auf etwas zu warten, das schon hinter der Sperre liegt.
Ebenfalls nachgemessen statt vermutet: die Warengruppen im
Beschreibungssatz sind die echten Kategorien des Shops.
pruef-rabattcodes EXIT=0 (42 Pruefungen), darunter beide Richtungen der
Supporter-Sperre, die Bildpunkte des ausgelieferten Siegels (Ecken
durchsichtig, Mitte deckend, 69 % Flaeche), das Kopieren gegen die echte
Zwischenablage samt Gegenprobe davor, die Ablaufschaltung mit gestellter
Uhr an beiden Seiten des Stichtags und alle fuenf Sprachen.
Co-Authored-By: Claude Opus 5 <[email protected]>
537 lines
22 KiB
HTML
537 lines
22 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>Rabattcodes — DOGFATHER UNIVERSE</title>
|
||
<meta name="description" content="Rabattcodes von Dogis Partnern für Team Dogi — spar bares Geld bei ausgewählten Marken." />
|
||
<link rel="icon" type="image/png" href="/assets/img/app-symbole/universe-32.png" />
|
||
<link rel="apple-touch-icon" href="/assets/img/app-symbole/universe-180.png" />
|
||
<link rel="manifest" href="/manifest.json" />
|
||
<meta name="theme-color" content="#065f76" />
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:site_name" content="DOGFATHER UNIVERSE" />
|
||
<meta property="og:title" content="Rabattcodes — DOGFATHER UNIVERSE" />
|
||
<meta property="og:description" content="Rabattcodes von Dogis Partnern für Team Dogi — spar bares Geld bei ausgewählten Marken." />
|
||
<meta property="og:image" content="https://dogfather-universe.com/assets/img/og-cover.jpg" />
|
||
<meta property="og:url" content="https://dogfather-universe.com/rabattcodes.html" />
|
||
<meta name="twitter:card" content="summary_large_image" />
|
||
<meta name="twitter:title" content="Rabattcodes — DOGFATHER UNIVERSE" />
|
||
<meta name="twitter:description" content="Rabattcodes von Dogis Partnern für Team Dogi — spar bares Geld bei ausgewählten Marken." />
|
||
<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>
|
||
.code-platzhalter {
|
||
max-width: 620px;
|
||
margin: 0 auto;
|
||
text-align: center;
|
||
}
|
||
|
||
/* Gesperrt-Zustand: an das Supporter-Abo gekoppelt (Nutzer-Feedback
|
||
03.08.2026), gleiche Prüfung wie die Karte auf links.html. Direkter
|
||
Aufruf dieser Seite (Lesezeichen, geteilter Link) soll die Sperre
|
||
genauso zeigen wie der Knopf dort — nicht nur auf links.html blockiert
|
||
sein. */
|
||
.code-gesperrt-siegel {
|
||
width: 96px; height: 96px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
margin: 0 auto 1.4rem;
|
||
font-size: 2.6rem;
|
||
border-radius: 50%;
|
||
background: radial-gradient(circle at 32% 28%, rgba(212,175,55,.35), rgba(11,13,16,.9) 70%);
|
||
border: 1.5px solid rgba(212,175,55,.45);
|
||
box-shadow: 0 0 0 6px rgba(212,175,55,.06), 0 10px 30px rgba(0,0,0,.5);
|
||
}
|
||
|
||
/* =====================================================================
|
||
DER ERSTE ECHTE PARTNERCODE (08.09.2026)
|
||
|
||
Bis heute war das hier eine Platzhalterkachel ("Codes folgen in
|
||
Kürze") mit einem erfundenen Beispielcode. Jetzt steht der erste
|
||
echte drauf: DOGI10 für Van's DIY & Bastelbedarf.
|
||
|
||
⚠️ DIE KONDITIONEN SIND ABGELESEN, NICHT GERATEN.
|
||
|
||
Quelle der Wahrheit ist der Shop, nicht diese Seite:
|
||
/home/vandiy/vans-diy-bastelbedarf/src/content/partnercodes.json
|
||
{ "code": "DOGI10", "prozent": 10, "bis": "2026-09-30",
|
||
"aktiv": true, "giltAufSale": false }
|
||
Ausgewertet wird sie an zwei Stellen mit derselben Regel
|
||
(aktiv !== false UND jetzt <= bis 23:59:59): src/scripts/cart.ts für
|
||
den Warenkorb, server/lib/preis-berechnen.js für den Endpreis.
|
||
|
||
Der naheliegende Weg wäre gewesen, "–10 %" einfach aus dem Namen
|
||
"DOGI10" zu schließen. Das hätte hier zufällig gestimmt und wäre
|
||
trotzdem falsch gewesen: Dass der Code NICHT auf bereits reduzierte
|
||
Artikel gilt (giltAufSale: false) und dass er am 30.09.2026 ausläuft,
|
||
steht im Namen nicht drin. Eine falsche Zusage auf einer
|
||
Verkaufsseite kostet VanVan die Diskussion an der Kasse.
|
||
|
||
Abgeschrieben ist abgeschrieben: Wer die Konditionen ändert, ändert
|
||
sie im Shop UND hier — die Zeile unten rechnet nichts aus, sie sagt
|
||
nur an. Damit das nicht schleichend auseinanderläuft, kennt das
|
||
Skript am Seitenende das Ablaufdatum und schaltet die Karte von
|
||
selbst auf "abgelaufen", statt weiter etwas zu versprechen.
|
||
===================================================================== */
|
||
.rc-partner {
|
||
max-width: 620px;
|
||
margin: 0 auto;
|
||
text-align: center;
|
||
padding: 2.4rem 1.6rem 2rem;
|
||
border-color: rgba(94, 234, 167, .3);
|
||
}
|
||
|
||
/* Eckband wie bei den Feature-Kacheln auf links.html — hier aber ohne
|
||
Rotation und in Silber statt Bunt, damit es dem Siegel nicht die
|
||
Aufmerksamkeit wegnimmt. */
|
||
.rc-band {
|
||
position: absolute;
|
||
top: 1rem; right: 1rem;
|
||
font-size: .64rem;
|
||
font-weight: 800;
|
||
letter-spacing: .09em;
|
||
text-transform: uppercase;
|
||
padding: .36rem .72rem;
|
||
border-radius: 999px;
|
||
background: rgba(8, 10, 14, .6);
|
||
border: 1px solid rgba(255, 255, 255, .24);
|
||
color: #dfe6ef;
|
||
}
|
||
|
||
/* ---- Das Medaillon --------------------------------------------------
|
||
Warum für EIN Logo so viel Aufwand: Es ist das einzige Bild auf der
|
||
Seite und das Gesicht des Partners. Der Weg zu "besonders" führt hier
|
||
NICHT über mehr Farbe — das Siegel ist schwarz-weiß, jede Einfärbung
|
||
würde eine fremde Marke umlackieren. Er führt über mehr MATERIAL: aus
|
||
dem runden Siegel wird eine geprägte Münze, aus sechs Lagen:
|
||
|
||
1. Aura weicher Lichthof dahinter, atmet sehr langsam
|
||
2. Rändel die geriffelte Münzkante (repeating-conic-gradient),
|
||
72 Zähne. Sie steht STILL — eine sich drehende
|
||
Riffelung flimmert bei 148 px, und genau diese grelle
|
||
Optik soll hier nicht sein (Grundregel: augenschonend)
|
||
3. Glanz stattdessen wandert EIN Lichtpunkt in 22 s einmal um
|
||
die Kante. Das ist die Bewegung, die eine Münze im
|
||
Licht macht, und sie ist ruhig genug fürs Auge
|
||
4. Siegel das freigestellte Logo (partner-vandiy.webp)
|
||
5. Schliff Prägekante nach innen (oben Licht, unten Schatten) und
|
||
ein langsamer Lichtstreif über die Fläche
|
||
6. Ablage elliptischer Schatten darunter, damit die Münze auf der
|
||
Karte LIEGT statt zu schweben
|
||
|
||
Alles davon ist reines CSS: kein zweites Bild, kein Skript, keine
|
||
Abhängigkeit. Und alles davon steht still, sobald der Rechner
|
||
"weniger Bewegung" meldet (Block ganz unten). */
|
||
.rc-medaillon {
|
||
position: relative;
|
||
width: clamp(116px, 34vw, 148px);
|
||
aspect-ratio: 1 / 1;
|
||
margin: .2rem auto 1.5rem;
|
||
border-radius: 50%;
|
||
transition: transform .4s cubic-bezier(.22, .9, .3, 1);
|
||
}
|
||
.rc-medaillon > * {
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
/* 1 — Aura. Silber (die Farbe des Siegels) mit einem Hauch Mint (die
|
||
Farbe, in der diese Seite über Codes spricht). */
|
||
.rc-medaillon::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -28%;
|
||
z-index: 0;
|
||
border-radius: 50%;
|
||
background: radial-gradient(circle at 50% 45%,
|
||
rgba(226, 234, 244, .30), rgba(94, 234, 167, .11) 45%, transparent 70%);
|
||
filter: blur(12px);
|
||
animation: rc-aura-atmen 9s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 6 — Ablageschatten. Steht bewusst VOR der Aura im Quelltext, damit
|
||
die Reihenfolge im Kopf der Lage entspricht, nicht der Nummer. */
|
||
.rc-medaillon::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 14%; right: 14%;
|
||
bottom: -8%;
|
||
height: 13%;
|
||
z-index: 0;
|
||
border-radius: 50%;
|
||
background: radial-gradient(ellipse at center, rgba(0, 0, 0, .6), transparent 72%);
|
||
filter: blur(4px);
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 2 — Die geriffelte Münzkante. Der Ring entsteht aus zwei Teilen:
|
||
border-radius beschneidet den Kegelverlauf auf den Kreis, die Maske
|
||
stanzt die Mitte heraus. Das Siegel (Lage 4) deckt anschließend
|
||
alles bis zu seinem eigenen Rand ab — sichtbar bleibt genau der
|
||
Streifen, der außen übersteht. */
|
||
.rc-raendel {
|
||
inset: -10%;
|
||
z-index: 1;
|
||
background: repeating-conic-gradient(from 0deg,
|
||
rgba(228, 234, 243, .92) 0deg 2.5deg,
|
||
rgba(70, 80, 94, .8) 2.5deg 5deg);
|
||
-webkit-mask: radial-gradient(closest-side, transparent 0 82%, #000 86%);
|
||
mask: radial-gradient(closest-side, transparent 0 82%, #000 86%);
|
||
opacity: .45;
|
||
}
|
||
|
||
/* 3 — Der wandernde Lichtpunkt auf derselben Kante. */
|
||
.rc-glanz {
|
||
inset: -10%;
|
||
z-index: 2;
|
||
background: conic-gradient(from 0deg,
|
||
rgba(255, 255, 255, 0) 0deg,
|
||
rgba(255, 255, 255, 0) 248deg,
|
||
rgba(255, 255, 255, .72) 322deg,
|
||
rgba(255, 255, 255, 0) 360deg);
|
||
-webkit-mask: radial-gradient(closest-side, transparent 0 82%, #000 86%);
|
||
mask: radial-gradient(closest-side, transparent 0 82%, #000 86%);
|
||
animation: rc-glanz-dreht 22s linear infinite;
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 4 — Das Siegel selbst. */
|
||
.rc-medaillon img {
|
||
z-index: 3;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: contain;
|
||
filter: drop-shadow(0 10px 20px rgba(0, 0, 0, .55));
|
||
}
|
||
|
||
/* 5 — Prägekante und Lichtstreif. Der Streifen benutzt dieselbe
|
||
Bewegung wie die Marken-Kacheln auf links.html (nav-cta-shimmer aus
|
||
main.css), nur deutlich langsamer. */
|
||
.rc-schliff {
|
||
z-index: 4;
|
||
pointer-events: none;
|
||
background: linear-gradient(118deg, transparent 36%, rgba(255, 255, 255, .28) 49%, transparent 62%);
|
||
background-size: 260% 100%;
|
||
box-shadow:
|
||
inset 0 2px 4px rgba(255, 255, 255, .3),
|
||
inset 0 -8px 16px rgba(0, 0, 0, .4),
|
||
inset 0 0 0 1px rgba(255, 255, 255, .1);
|
||
animation: nav-cta-shimmer 6.5s linear infinite;
|
||
}
|
||
|
||
/* Beim Zeigen kippt die Münze leicht ins Licht. Ausgelöst wird das an
|
||
der ganzen KARTE, nicht am Medaillon: Es ist kein Knopf, und ein
|
||
Effekt, der erst kommt, wenn man ein Bild genau trifft, findet
|
||
niemand. */
|
||
.rc-partner:hover .rc-medaillon {
|
||
transform: perspective(680px) rotateX(9deg) rotateY(-7deg) scale(1.045);
|
||
}
|
||
|
||
@keyframes rc-aura-atmen {
|
||
0%, 100% { opacity: .75; transform: scale(1); }
|
||
50% { opacity: 1; transform: scale(1.05); }
|
||
}
|
||
@keyframes rc-glanz-dreht { to { transform: rotate(360deg); } }
|
||
|
||
/* ---- Name, Beschreibung ------------------------------------------- */
|
||
.rc-marke {
|
||
font-size: clamp(1.35rem, 5vw, 1.7rem);
|
||
line-height: 1.2;
|
||
margin: 0;
|
||
}
|
||
.rc-marke small {
|
||
display: block;
|
||
font-size: .58em;
|
||
font-weight: 700;
|
||
letter-spacing: .05em;
|
||
color: var(--text-muted);
|
||
margin-top: .25rem;
|
||
}
|
||
.rc-beschreibung {
|
||
margin: .7rem auto 0;
|
||
max-width: 40ch;
|
||
font-size: .97rem;
|
||
}
|
||
|
||
/* ---- Der Code selbst ----------------------------------------------
|
||
Ein Knopf, kein Textfeld: Die einzige Handlung hier ist "kopieren",
|
||
und die gehört auf etwas Drückbares — mit Tastatur erreichbar, ohne
|
||
dass jemand erst markieren muss. Der gestrichelte Rand ist der
|
||
Gutschein-Look, den diese Seite vorher schon in der Vorschaukachel
|
||
hatte; er bleibt, das Erfundene daran verschwindet. */
|
||
.rc-code {
|
||
position: relative;
|
||
display: block;
|
||
width: 100%;
|
||
max-width: 340px;
|
||
margin: 1.7rem auto 0;
|
||
padding: .9rem 1.1rem 1rem;
|
||
border: 1.5px dashed rgba(94, 234, 167, .45);
|
||
border-radius: 14px;
|
||
background: rgba(52, 211, 153, .06);
|
||
color: inherit;
|
||
font-family: inherit;
|
||
cursor: pointer;
|
||
text-align: center;
|
||
transition: border-color .2s ease, background-color .2s ease, transform .12s ease;
|
||
}
|
||
.rc-code:hover {
|
||
border-color: rgba(94, 234, 167, .8);
|
||
background: rgba(52, 211, 153, .1);
|
||
}
|
||
.rc-code:active { transform: scale(.99); }
|
||
.rc-code.ist-kopiert {
|
||
border-style: solid;
|
||
border-color: rgba(94, 234, 167, .9);
|
||
background: rgba(52, 211, 153, .16);
|
||
}
|
||
.rc-code-kopf {
|
||
display: block;
|
||
font-size: .7rem;
|
||
font-weight: 800;
|
||
letter-spacing: .16em;
|
||
text-transform: uppercase;
|
||
color: var(--text-muted);
|
||
}
|
||
.rc-code-wert {
|
||
display: block;
|
||
margin: .32rem 0 .4rem;
|
||
font-size: clamp(1.7rem, 7.5vw, 2.15rem);
|
||
font-weight: 900;
|
||
letter-spacing: .16em;
|
||
text-indent: .16em; /* gleicht den Sperrsatz hinter dem letzten Zeichen aus */
|
||
background: linear-gradient(100deg,
|
||
#7fe3b4 0%, #ffffff 26%, #d9fff1 44%, #86e9bd 62%, #ffffff 80%, #7fe3b4 100%);
|
||
background-size: 260% 100%;
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
animation: btn-silver-text-shine 5.5s linear infinite; /* aus main.css */
|
||
}
|
||
.rc-code-fuss {
|
||
display: block;
|
||
font-size: .8rem;
|
||
color: var(--text-muted);
|
||
}
|
||
/* Rückmeldung steht AUSSERHALB des Knopfes und wird nicht per Skript
|
||
beschriftet, sondern nur ein- und ausgeblendet. Sonst wäre der Text
|
||
nach einem Sprachwechsel deutsch geblieben — data-i18n greift nur an
|
||
Elementen, die im HTML stehen. Die feste Höhe verhindert, dass die
|
||
Karte beim Kopieren springt. */
|
||
.rc-code-echo {
|
||
min-height: 1.4em;
|
||
margin: .5rem 0 0;
|
||
font-size: .85rem;
|
||
font-weight: 700;
|
||
color: #8ff0c0;
|
||
}
|
||
.rc-code-echo .fehler { color: #ffc9a3; }
|
||
|
||
/* ---- Konditionen --------------------------------------------------- */
|
||
.rc-fakten {
|
||
list-style: none;
|
||
margin: 1.2rem 0 0;
|
||
padding: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: .4rem;
|
||
font-size: .9rem;
|
||
color: var(--text-muted);
|
||
}
|
||
.rc-fakten li { display: flex; gap: .5rem; align-items: baseline; }
|
||
.rc-fakten b { color: #8ff0c0; font-weight: 800; }
|
||
|
||
/* ---- Abgelaufen ---------------------------------------------------- */
|
||
.rc-abgelaufen {
|
||
max-width: 380px;
|
||
margin: 1.2rem auto 0;
|
||
padding: .7rem 1rem;
|
||
border-radius: 12px;
|
||
border: 1.5px solid rgba(212, 175, 55, .4);
|
||
background: rgba(212, 175, 55, .08);
|
||
color: #ffe9a8;
|
||
font-size: .88rem;
|
||
}
|
||
.rc-abgelaufen[hidden] { display: none; }
|
||
.rc-partner.ist-abgelaufen .rc-code-wert {
|
||
text-decoration: line-through;
|
||
opacity: .5;
|
||
animation: none;
|
||
}
|
||
.rc-partner.ist-abgelaufen .rc-code { cursor: not-allowed; opacity: .75; }
|
||
|
||
.rc-mehr {
|
||
max-width: 620px;
|
||
margin: 1.4rem auto 0;
|
||
text-align: center;
|
||
font-size: .9rem;
|
||
color: var(--text-muted);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.rc-medaillon,
|
||
.rc-medaillon::before,
|
||
.rc-glanz,
|
||
.rc-schliff,
|
||
.rc-code-wert { animation: none; transition: none; }
|
||
.rc-partner:hover .rc-medaillon { transform: none; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="mit-hintergrund" style="--page-bg:url('/assets/img/bg-links.jpg');--page-bg-mobile:url('/assets/img/bg-links-mobile.jpg');">
|
||
<div id="site-header"></div>
|
||
|
||
<main>
|
||
<section class="hero page-bg">
|
||
<div class="hero-banner"><img src="/assets/img/bg-links.jpg" alt="" loading="eager" /></div>
|
||
<div class="container">
|
||
<span class="eyebrow" data-i18n="rc_eyebrow">🏷️ Für Team Dogi</span>
|
||
<h1 data-i18n="rc_h1">Rabattcodes</h1>
|
||
<p class="lead worlds" data-i18n="rc_lead">Codes von Dogis Partnern — damit deine Community bares Geld spart.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="section-tight">
|
||
<div class="container">
|
||
<!-- Nur für Supporter sichtbar (siehe Skript unten) -->
|
||
<div id="rc-inhalt" hidden>
|
||
<article class="card rc-partner" id="rc-partner">
|
||
<span class="rc-band" data-i18n="rc_band">Partner Nr. 1</span>
|
||
|
||
<div class="rc-medaillon">
|
||
<span class="rc-raendel" aria-hidden="true"></span>
|
||
<span class="rc-glanz" aria-hidden="true"></span>
|
||
<img src="/assets/img/partner-vandiy.webp" width="384" height="384"
|
||
alt="Logo von Van’s DIY & Bastelbedarf"
|
||
data-i18n-attr="alt:rc_logo_alt" loading="lazy" decoding="async" />
|
||
<span class="rc-schliff" aria-hidden="true"></span>
|
||
</div>
|
||
|
||
<h2 class="rc-marke">VAN’S DIY<small>& Bastelbedarf</small></h2>
|
||
<p class="rc-beschreibung" data-i18n="rc_beschreibung">Häkelzubehör, Bastelbedarf, DIY-Plushies und Modeschmuck — VanVans eigener Shop.</p>
|
||
|
||
<button type="button" class="rc-code" id="rc-code" data-code="DOGI10">
|
||
<span class="rc-code-kopf" data-i18n="rc_code_kopf">Dein Code</span>
|
||
<span class="rc-code-wert">DOGI10</span>
|
||
<span class="rc-code-fuss" data-i18n="rc_code_fuss">Tippen zum Kopieren</span>
|
||
</button>
|
||
<p class="rc-code-echo" role="status" aria-live="polite">
|
||
<span id="rc-echo-ok" data-i18n="rc_code_kopiert" hidden>Code kopiert ✓</span>
|
||
<span class="fehler" id="rc-echo-fehler" data-i18n="rc_code_fehler" hidden>Kopieren ging nicht — bitte von Hand abtippen.</span>
|
||
</p>
|
||
|
||
<ul class="rc-fakten">
|
||
<li><span aria-hidden="true">💸</span><span data-i18n="rc_fakt_rabatt"><b>10 %</b> Rabatt auf deinen Einkauf</span></li>
|
||
<li><span aria-hidden="true">📅</span><span data-i18n="rc_fakt_bis">Gültig bis 30.09.2026</span></li>
|
||
<li><span aria-hidden="true">ℹ️</span><span data-i18n="rc_fakt_sale">Nicht auf bereits reduzierte Artikel</span></li>
|
||
</ul>
|
||
|
||
<p class="rc-abgelaufen" id="rc-abgelaufen" hidden data-i18n="rc_abgelaufen">Dieser Code ist ausgelaufen. Dogi klärt gerade die Verlängerung — schau bald wieder rein.</p>
|
||
|
||
<div class="btn-row" style="justify-content:center;margin-top:1.6rem;">
|
||
<a class="btn btn-primary" href="https://vans-diy-bastelbedarf.com/" target="_blank" rel="noopener" data-i18n="rc_btn_shop">Zum Shop von Van’s DIY ↗</a>
|
||
<a class="btn btn-outline" href="links.html" data-i18n="rc_btn_zurueck">← Zurück zu allen Links</a>
|
||
</div>
|
||
</article>
|
||
|
||
<p class="rc-mehr" data-i18n="rc_mehr">Weitere Codes folgen, sobald die nächsten Kooperationen stehen.</p>
|
||
</div>
|
||
|
||
<!-- Nur für Nicht-Supporter sichtbar (siehe Skript unten) -->
|
||
<div class="card code-platzhalter" id="rc-gesperrt" hidden>
|
||
<div class="code-gesperrt-siegel" aria-hidden="true">🔒</div>
|
||
<h2 data-i18n="rc_gesperrt_titel">Nur für Dogfather-Supporter</h2>
|
||
<p data-i18n="rc_gesperrt_text">Rabattcodes sind ein exklusiver Vorteil der DogiCrew 🩵. Der erste Partnercode ist schon drin — werde jetzt Teil davon, um ihn freizuschalten.</p>
|
||
<div class="btn-row" style="justify-content:center;margin-top:1.8rem;">
|
||
<a class="btn btn-primary" href="abonnieren.html" data-i18n="rc_btn_abo">Jetzt Supporter werden 👑</a>
|
||
<a class="btn btn-outline" href="links.html" data-i18n="rc_btn_zurueck">← Zurück zu allen Links</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<div id="site-footer"></div>
|
||
<script src="assets/js/i18n-rabattcodes.js?v=20260908a"></script>
|
||
<script src="assets/js/main.js?v=20260828e"></script>
|
||
<script>
|
||
(function () {
|
||
/* Ablaufdatum von DOGI10 — dieselbe Angabe wie "bis" in
|
||
src/content/partnercodes.json im Shop, und dieselbe Auslegung:
|
||
einschließlich dieses Tages bis 23:59:59 (server/lib/preis-
|
||
berechnen.js, istRabattAktiv).
|
||
|
||
WARUM DAS HIER ÜBERHAUPT STEHT: Ein fest eingetipptes Datum in einem
|
||
Satz ist eine Zeitbombe — es stimmt, bis der Kalender es überholt,
|
||
und ab dann verspricht die Seite etwas, das der Shop schon ablehnt.
|
||
Deshalb steht das Datum genau EINMAL als Zahl da und nicht nur als
|
||
Text, damit die Seite selbst merken kann, wann sie stillhalten muss.
|
||
|
||
Gerechnet wird in der Zeitzone des Besuchers, der Shop rechnet in
|
||
seiner. In den wenigen Stunden Unterschied kann die Seite den Code
|
||
bereits als abgelaufen zeigen, während er noch gilt — das ist die
|
||
harmlose Richtung des Fehlers. Andersherum wäre sie es nicht. */
|
||
var ABLAUF = "2026-09-30";
|
||
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
var status = localStorage.getItem("supporterSubStatus");
|
||
var hatAbo = ["active", "pending", "suspended", "cancelled"].indexOf(status) !== -1;
|
||
var inhalt = document.getElementById("rc-inhalt");
|
||
var gesperrt = document.getElementById("rc-gesperrt");
|
||
if (inhalt) inhalt.hidden = !hatAbo;
|
||
if (gesperrt) gesperrt.hidden = hatAbo;
|
||
|
||
var karte = document.getElementById("rc-partner");
|
||
var knopf = document.getElementById("rc-code");
|
||
var ok = document.getElementById("rc-echo-ok");
|
||
var fehler = document.getElementById("rc-echo-fehler");
|
||
var abgelaufen = new Date() > new Date(ABLAUF + "T23:59:59");
|
||
|
||
if (abgelaufen) {
|
||
if (karte) karte.classList.add("ist-abgelaufen");
|
||
var hinweis = document.getElementById("rc-abgelaufen");
|
||
if (hinweis) hinweis.hidden = false;
|
||
if (knopf) knopf.disabled = true;
|
||
}
|
||
|
||
if (!knopf) return;
|
||
var uhr = null;
|
||
knopf.addEventListener("click", function () {
|
||
if (abgelaufen) return;
|
||
var zeigen = function (welches) {
|
||
if (ok) ok.hidden = welches !== "ok";
|
||
if (fehler) fehler.hidden = welches !== "fehler";
|
||
knopf.classList.toggle("ist-kopiert", welches === "ok");
|
||
clearTimeout(uhr);
|
||
uhr = setTimeout(function () {
|
||
if (ok) ok.hidden = true;
|
||
if (fehler) fehler.hidden = true;
|
||
knopf.classList.remove("ist-kopiert");
|
||
}, 2600);
|
||
};
|
||
/* Ohne HTTPS gibt es navigator.clipboard nicht, und auch mit kann
|
||
das Versprechen abgelehnt werden. Beide Fälle bekommen dieselbe
|
||
ehrliche Antwort statt einer stillen Nicht-Reaktion — der Code
|
||
steht ja sichtbar da und lässt sich abtippen. */
|
||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||
navigator.clipboard.writeText(knopf.getAttribute("data-code") || "").then(
|
||
function () { zeigen("ok"); },
|
||
function () { zeigen("fehler"); }
|
||
);
|
||
} else {
|
||
zeigen("fehler");
|
||
}
|
||
});
|
||
});
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|