Files

1356 lines
53 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>Wraneck — IT aus Magdeburg · Im Aufbau</title>
<meta name="description" content="Wraneck baut Webseiten, hostet sie, hilft bei IT-Problemen vor Ort und druckt Bauteile. Kleingewerbe aus Magdeburg. Aktuell im Aufbau — Anfragen jederzeit moeglich." />
<meta name="robots" content="noindex, nofollow" />
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='10' y='10' width='12' height='12' fill='%23d97a4a' transform='rotate(45 16 16)'/%3E%3C/svg%3E" />
<style>
/* ---------------------------------------------------------------------------
Wraneck.de — Blueprint Scroll Story
Single-file prototype. In the Astro build:
- Move <style> into src/styles/global.css and configure Tailwind tokens
- Move <script> into src/scripts/scroll-story.js
- Replace fonts with @font-face in public/fonts/
- Replace inline SVG groups with src/assets/blueprint/*.svg components
--------------------------------------------------------------------------- */
:root {
/* Blueprint palette ----------------------------------------------------- */
--bp-ink: #e8f0f7; /* primary line + body text */
--bp-ink-dim: rgba(232, 240, 247, 0.55);
--bp-ink-faint: rgba(232, 240, 247, 0.18);
--bp-paper: #0a1929; /* base canvas, deep navy */
--bp-paper-2: #0d2236; /* slightly raised band */
--bp-grid: rgba(120, 170, 220, 0.07);
--bp-grid-bold: rgba(120, 170, 220, 0.13);
--bp-cyan: #7fb3d5; /* secondary lines, labels */
--bp-warm: #d97a4a; /* terracotta accent — CTAs */
--bp-warm-glow: rgba(217, 122, 74, 0.45);
/* System-Fonts fuer DSGVO-konformen Sofort-Deploy.
Vor Launch: self-hosted "Source Serif 4" + "Space Grotesk" + "JetBrains Mono" in /fonts/ */
--font-serif: ui-serif, Georgia, "Times New Roman", serif;
--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
--measure: 36rem;
}
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
html, body { margin: 0; padding: 0; }
body {
background: var(--bp-paper);
color: var(--bp-ink);
font-family: var(--font-sans);
font-size: 17px;
line-height: 1.55;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
overflow-x: hidden;
}
/* Blueprint grid background — fixed, very subtle ------------------------ */
body::before {
content: "";
position: fixed;
inset: 0;
background-image:
linear-gradient(var(--bp-grid) 1px, transparent 1px),
linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px),
linear-gradient(var(--bp-grid-bold) 1px, transparent 1px),
linear-gradient(90deg, var(--bp-grid-bold) 1px, transparent 1px);
background-size: 24px 24px, 24px 24px, 120px 120px, 120px 120px;
pointer-events: none;
z-index: 0;
}
body::after {
/* paper grain — extremely subtle noise via radial gradients */
content: "";
position: fixed;
inset: 0;
background:
radial-gradient(ellipse at 20% 10%, rgba(127, 179, 213, 0.06), transparent 50%),
radial-gradient(ellipse at 80% 90%, rgba(127, 179, 213, 0.04), transparent 55%);
pointer-events: none;
z-index: 0;
}
main, header, footer { position: relative; z-index: 1; }
a { color: inherit; }
/* ---------- HEADER ----------------------------------------------------- */
.site-header {
position: sticky;
top: 0;
z-index: 50;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
background: linear-gradient(to bottom, rgba(10, 25, 41, 0.85), rgba(10, 25, 41, 0.65));
border-bottom: 1px solid var(--bp-ink-faint);
}
.site-header__inner {
max-width: 1280px;
margin: 0 auto;
padding: 14px 28px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 24px;
}
.wordmark {
font-family: var(--font-mono);
font-size: 15px;
letter-spacing: 0.32em;
text-transform: uppercase;
display: inline-flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--bp-ink);
}
.wordmark__dot {
width: 9px;
height: 9px;
border: 1.5px solid var(--bp-warm);
background: var(--bp-warm);
transform: rotate(45deg);
}
.site-header__meta {
font-family: var(--font-mono);
font-size: 12.5px;
letter-spacing: 0.08em;
color: var(--bp-ink-dim);
display: flex;
align-items: center;
gap: 18px;
}
.site-header__meta a {
color: var(--bp-ink);
text-decoration: none;
border-bottom: 1px solid var(--bp-ink-faint);
padding-bottom: 2px;
transition: border-color 0.18s;
}
.site-header__meta a:hover { border-color: var(--bp-warm); }
@media (max-width: 640px) {
.site-header__meta .label { display: none; }
.site-header__inner { padding: 12px 18px; }
}
/* ---------- LAYOUT: story container ------------------------------------ */
.story {
position: relative;
max-width: 1280px;
margin: 0 auto;
padding: 0 28px;
}
/* Hero — full bleed, sets tone before scroll-stations */
.hero {
min-height: 92vh;
padding: 14vh 0 9vh;
display: grid;
grid-template-columns: 1fr;
gap: 48px;
align-items: end;
}
.hero__caption {
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.18em;
color: var(--bp-cyan);
text-transform: uppercase;
display: flex;
align-items: center;
gap: 14px;
}
.hero__caption::before {
content: "";
display: inline-block;
width: 42px;
height: 1px;
background: var(--bp-cyan);
}
.hero__title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(40px, 6.5vw, 78px);
line-height: 1.05;
letter-spacing: -0.01em;
margin: 24px 0 0;
max-width: 14ch;
text-wrap: balance;
}
.hero__title em {
font-style: italic;
color: var(--bp-warm);
}
.hero__sub {
margin-top: 28px;
max-width: 48ch;
color: var(--bp-ink-dim);
font-size: 17px;
}
.hero__meta {
margin-top: 56px;
display: flex;
gap: 32px;
font-family: var(--font-mono);
font-size: 11.5px;
letter-spacing: 0.14em;
color: var(--bp-ink-dim);
text-transform: uppercase;
border-top: 1px solid var(--bp-ink-faint);
padding-top: 18px;
max-width: 720px;
flex-wrap: wrap;
}
.hero__meta span b { color: var(--bp-ink); font-weight: 500; }
.hero__scrollhint {
margin-top: 64px;
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.22em;
color: var(--bp-ink-dim);
text-transform: uppercase;
display: flex;
align-items: center;
gap: 12px;
}
.hero__scrollhint::after {
content: "";
width: 1px;
height: 48px;
background: linear-gradient(to bottom, var(--bp-ink-dim), transparent);
animation: hint-bob 2.4s ease-in-out infinite;
}
@keyframes hint-bob { 0%, 100% { transform: translateY(0); opacity: 1; } 50% { transform: translateY(8px); opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .hero__scrollhint::after { animation: none; } }
/* ---------- STORY: split layout ---------------------------------------- */
.split {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
gap: 64px;
align-items: flex-start;
position: relative;
}
@media (max-width: 960px) {
.split { grid-template-columns: 1fr; gap: 0; }
}
/* Left rail — stations stack */
.stations {
padding: 8vh 0 12vh;
display: flex;
flex-direction: column;
gap: 14vh;
}
/* Right rail — sticky build */
.build {
position: sticky;
top: 96px;
height: calc(100vh - 120px);
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
@media (max-width: 960px) {
.build {
position: sticky;
top: 64px;
height: 48vh;
background: linear-gradient(to bottom, var(--bp-paper) 78%, rgba(10, 25, 41, 0.7));
margin: 0 -28px;
padding: 12px 28px 0;
border-bottom: 1px solid var(--bp-ink-faint);
backdrop-filter: blur(2px);
}
.stations { padding-top: 4vh; gap: 8vh; }
}
/* ---------- STATION CARDS --------------------------------------------- */
.station {
min-height: 64vh;
display: flex;
flex-direction: column;
justify-content: center;
padding: 4vh 0;
}
.station__no {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.3em;
color: var(--bp-cyan);
text-transform: uppercase;
display: flex;
align-items: center;
gap: 14px;
}
.station__no::before {
content: "";
width: 28px; height: 1px;
background: var(--bp-cyan);
}
.station__tag {
margin-left: 14px;
color: var(--bp-ink-dim);
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.2em;
}
.station__title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(28px, 3.4vw, 44px);
line-height: 1.12;
letter-spacing: -0.005em;
margin: 18px 0 22px;
max-width: 18ch;
text-wrap: balance;
}
.station__body {
max-width: var(--measure);
color: var(--bp-ink);
font-size: 17.5px;
line-height: 1.6;
}
.station__body p { margin: 0 0 14px; }
.station__body p:last-child { margin-bottom: 0; }
.station__body .muted { color: var(--bp-ink-dim); }
.station__body strong { color: var(--bp-warm); font-weight: 500; }
/* Coming-soon chip (replaces price chip during build phase) */
.soonchip {
display: inline-flex;
align-items: center;
gap: 10px;
margin-top: 22px;
padding: 8px 14px;
border: 1px dashed var(--bp-warm);
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.14em;
text-transform: uppercase;
background: rgba(217, 122, 74, 0.06);
color: var(--bp-warm);
}
.soonchip::before {
content: "";
width: 7px; height: 7px;
background: var(--bp-warm);
transform: rotate(45deg);
}
/* Soft top banner — Coming soon */
.topbanner {
background: rgba(217, 122, 74, 0.10);
border-bottom: 1px solid rgba(217, 122, 74, 0.3);
color: var(--bp-warm);
text-align: center;
padding: 9px 16px;
font-family: var(--font-mono);
font-size: 11.5px;
letter-spacing: 0.18em;
text-transform: uppercase;
position: relative;
z-index: 60;
}
/* Soft fade in when station enters viewport */
.station__title, .station__body, .soonchip, .station__no {
opacity: 0;
transform: translateY(14px);
transition: opacity 0.7s ease, transform 0.7s ease;
}
.station.is-in .station__no { opacity: 1; transform: none; transition-delay: 0s; }
.station.is-in .station__title { opacity: 1; transform: none; transition-delay: 0.05s; }
.station.is-in .station__body { opacity: 1; transform: none; transition-delay: 0.12s; }
.station.is-in .soonchip { opacity: 1; transform: none; transition-delay: 0.2s; }
@media (prefers-reduced-motion: reduce) {
.station__title, .station__body, .soonchip, .station__no {
opacity: 1; transform: none; transition: none;
}
}
/* ---------- NOTEBOOK SVG ---------------------------------------------- */
.notebook-wrap {
width: 100%;
max-width: 620px;
aspect-ratio: 620 / 740;
position: relative;
}
@media (max-width: 960px) {
.notebook-wrap { max-width: 420px; aspect-ratio: 620 / 740; }
}
.notebook {
width: 100%;
height: 100%;
overflow: visible;
color: var(--bp-ink);
}
/* Default stroke + text styles for SVG parts */
.notebook [data-part] {
opacity: 0;
transform-box: fill-box;
transition: opacity 0.55s ease;
}
.notebook [data-part].is-on { opacity: 1; }
.notebook .label {
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: 0.18em;
fill: var(--bp-cyan);
text-transform: uppercase;
}
.notebook .label-faint {
fill: var(--bp-ink-dim);
}
.notebook .dim {
fill: var(--bp-ink-dim);
}
.notebook .warm { stroke: var(--bp-warm); }
.notebook .warm-fill { fill: var(--bp-warm); }
/* Drawn-line entry: stroke-dasharray animation */
.notebook .draw {
stroke-dasharray: 1200;
stroke-dashoffset: 1200;
transition: stroke-dashoffset 1.1s ease;
}
.notebook [data-part].is-on .draw { stroke-dashoffset: 0; }
@media (prefers-reduced-motion: reduce) {
.notebook [data-part] { transition: none; }
.notebook .draw { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
}
/* Display glow — Station 8 */
.display-glow {
opacity: 0;
transition: opacity 1.2s ease;
}
.notebook.is-final .display-glow { opacity: 1; }
/* Notebook crosshair / corner ticks (always visible, schematic chrome) */
.schematic-chrome { color: var(--bp-cyan); opacity: 0.7; }
/* Big rotating BETA stamp on CPU when station 5 active */
.cpu-stamp {
transform-origin: 310px 470px;
transform: rotate(-14deg) scale(0.7);
opacity: 0;
transition: opacity 0.5s ease 0.35s, transform 0.7s cubic-bezier(.2,.9,.3,1.4) 0.35s;
}
[data-part="cpu"].is-on .cpu-stamp { opacity: 1; transform: rotate(-14deg) scale(1); }
/* ---------- FINAL CTA SECTION (Station 8) ----------------------------- */
.final {
padding: 14vh 0 8vh;
position: relative;
border-top: 1px dashed var(--bp-ink-faint);
margin-top: 8vh;
}
.final__inner {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 64px;
max-width: 920px;
margin: 0 auto;
text-align: center;
}
.final__caption {
font-family: var(--font-mono);
font-size: 11px;
letter-spacing: 0.3em;
color: var(--bp-cyan);
text-transform: uppercase;
}
.final__title {
font-family: var(--font-serif);
font-weight: 400;
font-size: clamp(36px, 5vw, 60px);
line-height: 1.08;
margin: 18px 0 14px;
text-wrap: balance;
}
.final__title em { font-style: italic; color: var(--bp-warm); }
.final__sub {
color: var(--bp-ink-dim);
max-width: 48ch;
margin: 0 auto;
font-size: 17px;
}
/* "Display" CTA panel — warm-lit screen on dark blueprint */
.display-cta {
margin: 56px auto 0;
max-width: 720px;
background: radial-gradient(ellipse at center, rgba(217, 122, 74, 0.12), rgba(217, 122, 74, 0.03) 60%, transparent 80%), linear-gradient(180deg, #142b40, #0d2236);
border: 1px solid rgba(217, 122, 74, 0.35);
box-shadow:
0 0 0 1px rgba(127, 179, 213, 0.05) inset,
0 0 80px rgba(217, 122, 74, 0.12),
0 30px 60px rgba(0, 0, 0, 0.4);
padding: 56px 40px 48px;
position: relative;
}
.display-cta::before, .display-cta::after {
content: "";
position: absolute;
width: 14px; height: 14px;
border: 1px solid var(--bp-cyan);
}
.display-cta::before { top: -1px; left: -1px; border-right: none; border-bottom: none; }
.display-cta::after { bottom: -1px; right: -1px; border-left: none; border-top: none; }
.display-cta__greeting {
font-family: var(--font-serif);
font-style: italic;
font-size: 22px;
color: var(--bp-ink);
margin: 0 0 32px;
}
.cta-list {
display: flex;
flex-direction: column;
gap: 14px;
margin: 0;
padding: 0;
list-style: none;
}
.cta-list a {
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 18px 22px;
border: 1px solid var(--bp-ink-faint);
text-decoration: none;
color: var(--bp-ink);
font-family: var(--font-mono);
font-size: 14px;
letter-spacing: 0.04em;
background: rgba(10, 25, 41, 0.45);
transition: border-color 0.2s, background 0.2s, transform 0.2s;
}
.cta-list a:hover {
border-color: var(--bp-warm);
background: rgba(217, 122, 74, 0.08);
transform: translateY(-1px);
}
.cta-list a .arrow {
color: var(--bp-warm);
font-family: var(--font-mono);
font-size: 16px;
}
.cta-list a .kind {
color: var(--bp-cyan);
margin-right: 12px;
font-size: 10.5px;
letter-spacing: 0.22em;
text-transform: uppercase;
}
.cta-list a .val {
font-family: var(--font-mono);
font-size: 15px;
letter-spacing: 0;
}
/* Soft hint panel below CTA list (coming soon) */
.cal-embed {
margin-top: 28px;
border: 1px dashed var(--bp-ink-faint);
padding: 22px;
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.1em;
color: var(--bp-ink-dim);
text-transform: uppercase;
text-align: center;
}
.cal-embed b { color: var(--bp-ink); font-weight: 500; }
/* ---------- FOOTER ----------------------------------------------------- */
footer {
border-top: 1px solid var(--bp-ink-faint);
margin-top: 12vh;
padding: 40px 0 60px;
font-family: var(--font-mono);
font-size: 12px;
letter-spacing: 0.06em;
color: var(--bp-ink-dim);
}
.footer__inner {
max-width: 1280px;
margin: 0 auto;
padding: 0 28px;
display: grid;
grid-template-columns: 1.4fr 1fr 1fr;
gap: 40px;
}
@media (max-width: 720px) {
.footer__inner { grid-template-columns: 1fr; gap: 24px; }
}
footer h4 {
font-family: var(--font-mono);
font-size: 10.5px;
letter-spacing: 0.28em;
text-transform: uppercase;
color: var(--bp-cyan);
margin: 0 0 12px;
font-weight: 500;
}
footer p { margin: 4px 0; line-height: 1.7; color: var(--bp-ink); }
footer a { color: var(--bp-ink); text-decoration: none; border-bottom: 1px solid var(--bp-ink-faint); }
footer a:hover { border-color: var(--bp-warm); }
.footer__legal {
margin-top: 36px;
padding: 24px 28px 0;
max-width: 1280px;
margin-left: auto; margin-right: auto;
border-top: 1px dashed var(--bp-ink-faint);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 14px;
font-size: 11px;
color: var(--bp-ink-dim);
}
.footer__legal a { color: var(--bp-ink-dim); border: none; }
.footer__legal a:hover { color: var(--bp-warm); }
/* Mobile floating phone button — bottom nav per brief ("Hamburger unten") */
.mobile-cta {
position: fixed;
bottom: 18px;
left: 50%;
transform: translateX(-50%);
z-index: 40;
background: var(--bp-warm);
color: #1a0d05;
font-family: var(--font-mono);
font-size: 13px;
letter-spacing: 0.06em;
padding: 12px 22px;
border: none;
text-decoration: none;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(217, 122, 74, 0.5);
display: none;
}
@media (max-width: 720px) {
.mobile-cta { display: inline-flex; align-items: center; gap: 8px; }
}
.mobile-cta::before {
content: "";
width: 8px; height: 8px;
background: #1a0d05;
transform: rotate(45deg);
}
/* Selection */
::selection { background: var(--bp-warm); color: #1a0d05; }
</style>
</head>
<body>
<!-- ============================== TOP BANNER ============================ -->
<div class="topbanner" role="status">Im Aufbau · Anfragen jederzeit moeglich</div>
<!-- ============================== HEADER ================================ -->
<header class="site-header">
<div class="site-header__inner">
<a class="wordmark" href="/" aria-label="Wraneck — Startseite">
<span class="wordmark__dot" aria-hidden="true"></span>
Wraneck
</a>
<div class="site-header__meta">
<span class="label">Magdeburg</span>
<a href="mailto:info@wraneck.de">info@wraneck.de</a>
</div>
</div>
</header>
<main>
<!-- ============================ HERO ================================== -->
<section class="story hero" aria-labelledby="hero-title">
<div>
<div class="hero__caption">Bauplan&nbsp;Nr.&nbsp;01 &nbsp;·&nbsp; Magdeburg, 2026</div>
<h1 class="hero__title" id="hero-title">
Ich&nbsp;baue&nbsp;dir was, das <em>läuft</em>.
</h1>
<p class="hero__sub">
Webseiten, Hosting, IT-Hilfe vor Ort, 3D-Druck. Kein Konzern. Kein Vertrieb.
Ich bin Krys, ich mach das in meiner Werkstatt nebenher.
Die Seite ist gerade im Aufbau — Preise und Pakete folgen bald.
Wenn du jetzt schon was brauchst, schreib mir einfach.
</p>
<div class="hero__meta">
<span><b>Inhaber</b> &nbsp;Krys Baumgarten</span>
<span><b>Rechtsform</b> &nbsp;Kleingewerbeanmeldung in Arbeit</span>
<span><b>Standort</b> &nbsp;Magdeburg + Umkreis</span>
</div>
<div class="hero__scrollhint">Scroll · Bauteil 01 von 07</div>
</div>
</section>
<!-- ======================= STORY (split) ============================== -->
<div class="story split">
<!-- ----- LEFT: stations stack ----- -->
<div class="stations">
<!-- Station 1 -->
<section class="station" id="st-1" data-station="1">
<div class="station__no">01 / 07 <span class="station__tag">Gehäuse</span></div>
<h2 class="station__title">Hallo. Schön, dass&nbsp;du hier&nbsp;bist.</h2>
<div class="station__body">
<p>Das hier ist meine Werkstatt — virtuell. Rechts liegt das Gehäuse. Noch leer.</p>
<p class="muted">Scroll einfach weiter. Ich zeig dir Stück für Stück, was ich baue. Sieben Bauteile. Sieben Sachen, mit denen ich dir helfen kann.</p>
</div>
</section>
<!-- Station 2 -->
<section class="station" id="st-2" data-station="2">
<div class="station__no">02 / 07 <span class="station__tag">Mainboard · Über mich</span></div>
<h2 class="station__title">Ich bin Krys.<br/>IT-Administrator aus Magdeburg.</h2>
<div class="station__body">
<p>Wraneck ist mein Nebenberuf. Kein Konzern, kein Vertrieb, keine Mitarbeiter. Nur ich.</p>
<p class="muted">Wenn du anfragst, schreibe ich dir. Wenn du anrufst, höre ich zu. Wenn ich was nicht weiß, sag ich's dir — und nicht das Gegenteil.</p>
</div>
</section>
<!-- Station 3 -->
<section class="station" id="st-3" data-station="3">
<div class="station__no">03 / 07 <span class="station__tag">Display · Wraneck&nbsp;Web</span></div>
<h2 class="station__title">Brauchst du eine Webseite?</h2>
<div class="station__body">
<p>Ich baue sie für dich. Sauber, schnell, DSGVO-konform. Ohne Cookie-Wand, ohne Tracker, ohne unnötigen Schnickschnack.</p>
<p class="muted">Du kriegst den Code, du kriegst die Texte, du kriegst die Hoheit. Wenn du irgendwann woanders hin willst — alles deins.</p>
<span class="soonchip">Festpreis-Pakete in Vorbereitung · Anfrage schon jetzt moeglich</span>
</div>
</section>
<!-- Station 4 -->
<section class="station" id="st-4" data-station="4">
<div class="station__no">04 / 07 <span class="station__tag">SSD · Wraneck&nbsp;Host</span></div>
<h2 class="station__title">Soll deine Webseite irgendwo&nbsp;liegen?</h2>
<div class="station__body">
<p>Auf deutschen Servern. Ohne US-Tracking, ohne Daten-Roundtrip nach Übersee.</p>
<p class="muted">Was ich <em>nicht</em> mache: ich verspreche dir kein Mail-Hosting. Mailbetrieb ist eine eigene Welt, und ich bau nichts, was ich nicht zu 100% halten kann.</p>
<span class="soonchip">Hosting-Tarife in Vorbereitung · monatlich kuendbar geplant</span>
</div>
</section>
<!-- Station 5 -->
<section class="station" id="st-5" data-station="5">
<div class="station__no">05 / 07 <span class="station__tag">CPU · Wraneck&nbsp;Bots <strong style="color:var(--bp-warm)">· bald</strong></span></div>
<h2 class="station__title">Demnächst: kleine&nbsp;Assistenten.</h2>
<div class="station__body">
<p>Bots, die Termine annehmen oder einfache Fragen beantworten. Auf deiner Webseite. Mit deiner Stimme.</p>
<p class="muted">Steht noch in der Werkstatt. Wenn's so weit ist, sag ich Bescheid — bis dahin lasse ich's lieber unfertig, statt überteuert.</p>
</div>
</section>
<!-- Station 6 -->
<section class="station" id="st-6" data-station="6">
<div class="station__no">06 / 07 <span class="station__tag">Akku + Tastatur · IT-Hilfe</span></div>
<h2 class="station__title">WLAN streikt? Drucker spinnt?<br/>Alexa versteht dich nicht?</h2>
<div class="station__body">
<p>Ich komm vorbei. Im Raum Magdeburg, an deinem Esstisch, mit ruhiger Stimme.</p>
<p class="muted">Egal ob 78 oder 28, egal ob ein Klick zu viel oder das halbe Heimnetz. Wir kriegen das hin.</p>
<span class="soonchip">Stundensaetze folgen · Termin per Mail vereinbaren</span>
</div>
</section>
<!-- Station 7 -->
<section class="station" id="st-7" data-station="7">
<div class="station__no">07 / 07 <span class="station__tag">Druckteil · 3D-Druck</span></div>
<h2 class="station__title">Du brauchst ein Bauteil,<br/>das es nicht mehr gibt?</h2>
<div class="station__body">
<p>Schick mir die Datei. Oder beschreib's mir. Oder bring den kaputten Rest vorbei, ich vermesse.</p>
<p class="muted">Ich drucke es. PLA, PETG, ASA — je nachdem, was du brauchst. Kleinteile, Adapter, Halterungen, Ersatz für die Spülmaschine.</p>
</div>
</section>
</div>
<!-- ----- RIGHT: sticky notebook ----- -->
<aside class="build" aria-hidden="true">
<div class="notebook-wrap">
<svg class="notebook" viewBox="0 0 620 740" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<!-- ===========================================================
Generic notebook — top-down "open and lying flat" patent view.
Original schematic. Deliberately NOT modeled on any brand.
============================================================= -->
<!-- Schematic chrome: corner ticks + crosshair (always visible) -->
<g class="schematic-chrome" stroke="currentColor" stroke-width="1" fill="none" stroke-linecap="square">
<!-- corner ticks -->
<path d="M 8 8 L 8 28 M 8 8 L 28 8" />
<path d="M 612 8 L 612 28 M 612 8 L 592 8" />
<path d="M 8 732 L 8 712 M 8 732 L 28 732" />
<path d="M 612 732 L 612 712 M 612 732 L 592 732" />
<!-- center crosshair (very faint) -->
<g opacity="0.35">
<path d="M 310 24 L 310 36 M 310 706 L 310 718" />
<path d="M 22 370 L 34 370 M 586 370 L 598 370" />
</g>
<!-- title block, lower-right -->
<g transform="translate(424, 686)" font-family="JetBrains Mono, monospace" font-size="8.5" letter-spacing="1.8" fill="#7fb3d5">
<rect x="0" y="0" width="178" height="38" stroke="#7fb3d5" stroke-width="0.7" fill="none" opacity="0.6"/>
<line x1="0" y1="14" x2="178" y2="14" stroke="#7fb3d5" stroke-width="0.4" opacity="0.6"/>
<line x1="120" y1="0" x2="120" y2="38" stroke="#7fb3d5" stroke-width="0.4" opacity="0.6"/>
<text x="6" y="10" fill="#7fb3d5" opacity="0.75">DWG · WRANECK / NB-01</text>
<text x="6" y="26" fill="#e8f0f7" opacity="0.9">SHEET</text>
<text x="126" y="26" fill="#d97a4a">01/01</text>
</g>
<!-- Top label -->
<g font-family="JetBrains Mono, monospace" font-size="9" letter-spacing="3" fill="#7fb3d5" opacity="0.85">
<text x="20" y="20">NOTEBOOK · TOP VIEW · OPEN · SCALE 1:3</text>
</g>
</g>
<!-- ============== PART 1: CHASSIS (always on after st1) ============== -->
<g data-part="chassis">
<!-- Outer chassis: a rounded rectangle.
Top half (y: 60-330) = display lid (lying flat behind hinge)
Bottom half (y: 360-680) = keyboard base -->
<!-- Hinge band -->
<g stroke="var(--bp-ink-faint)" stroke-width="0.7" fill="none" stroke-dasharray="3 4">
<line x1="80" y1="345" x2="540" y2="345" />
</g>
<!-- BASE (bottom half) — chassis interior visible -->
<g stroke="var(--bp-ink)" stroke-width="1.4" fill="none" stroke-linejoin="round">
<path class="draw" d="M 80 360
L 540 360
Q 552 360 552 372
L 552 668
Q 552 680 540 680
L 80 680
Q 68 680 68 668
L 68 372
Q 68 360 80 360 Z" />
</g>
<!-- Inner edge — interior cavity outline -->
<g stroke="var(--bp-cyan)" stroke-width="0.6" fill="none" opacity="0.55">
<path d="M 95 376
L 525 376
Q 537 376 537 388
L 537 652
Q 537 664 525 664
L 95 664
Q 83 664 83 652
L 83 388
Q 83 376 95 376 Z" />
</g>
<!-- Screw markers (corners) -->
<g stroke="var(--bp-cyan)" stroke-width="0.7" fill="none">
<g transform="translate(96, 392)"><circle r="4.5"/><line x1="-3.2" y1="-3.2" x2="3.2" y2="3.2"/></g>
<g transform="translate(524, 392)"><circle r="4.5"/><line x1="-3.2" y1="-3.2" x2="3.2" y2="3.2"/></g>
<g transform="translate(96, 648)"><circle r="4.5"/><line x1="-3.2" y1="-3.2" x2="3.2" y2="3.2"/></g>
<g transform="translate(524, 648)"><circle r="4.5"/><line x1="-3.2" y1="-3.2" x2="3.2" y2="3.2"/></g>
<g transform="translate(310, 392)"><circle r="3.5"/></g>
<g transform="translate(310, 648)"><circle r="3.5"/></g>
</g>
<!-- Hinge cylinders -->
<g stroke="var(--bp-ink)" stroke-width="1" fill="var(--bp-paper-2)">
<rect x="100" y="340" width="80" height="14" rx="3"/>
<rect x="440" y="340" width="80" height="14" rx="3"/>
</g>
<g stroke="var(--bp-cyan)" stroke-width="0.5" fill="none">
<line x1="110" y1="347" x2="170" y2="347"/>
<line x1="450" y1="347" x2="510" y2="347"/>
</g>
<!-- Dimension lines on base (width) -->
<g stroke="var(--bp-cyan)" stroke-width="0.5" opacity="0.85" fill="none">
<line x1="68" y1="700" x2="552" y2="700"/>
<line x1="68" y1="696" x2="68" y2="704"/>
<line x1="552" y1="696" x2="552" y2="704"/>
<text x="310" y="694" text-anchor="middle" class="label">340&nbsp;MM</text>
</g>
<!-- Port cutouts (left + right edges) -->
<g stroke="var(--bp-ink-dim)" stroke-width="0.8" fill="none">
<rect x="60" y="430" width="10" height="22" />
<rect x="60" y="468" width="10" height="14" />
<rect x="60" y="498" width="10" height="14" />
<rect x="550" y="430" width="10" height="14" />
<rect x="550" y="450" width="10" height="22" />
<rect x="550" y="488" width="10" height="14" />
</g>
<!-- Ventilation slots (top of base) -->
<g stroke="var(--bp-cyan)" stroke-width="0.5" opacity="0.6">
<line x1="120" y1="370" x2="220" y2="370"/>
<line x1="230" y1="370" x2="330" y2="370"/>
<line x1="340" y1="370" x2="440" y2="370"/>
</g>
<!-- ==== DISPLAY LID (top half) — visible from the start as outline only, off-state ==== -->
<g stroke="var(--bp-ink)" stroke-width="1.4" fill="none">
<path class="draw" d="M 80 60
L 540 60
Q 552 60 552 72
L 552 330
L 68 330
L 68 72
Q 68 60 80 60 Z" />
</g>
<!-- bezel inner edge -->
<g stroke="var(--bp-cyan)" stroke-width="0.5" opacity="0.55">
<rect x="92" y="80" width="436" height="232" />
</g>
<!-- camera dot -->
<g stroke="var(--bp-cyan)" stroke-width="0.7" fill="var(--bp-paper-2)">
<circle cx="310" cy="72" r="2.4"/>
</g>
<!-- "DISPLAY" tag -->
<g>
<line x1="40" y1="196" x2="65" y2="196" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="14" y="200" class="label" transform="rotate(-90 14 200)">DISPLAY · OFF</text>
</g>
<!-- "BASE" tag -->
<g>
<line x1="40" y1="520" x2="65" y2="520" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="14" y="524" class="label" transform="rotate(-90 14 524)">BASE · CAVITY</text>
</g>
</g>
<!-- ============== PART 2: MAINBOARD ============== -->
<g data-part="mainboard">
<!-- PCB rectangle inside base cavity -->
<g stroke="var(--bp-ink)" stroke-width="1" fill="rgba(127,179,213,0.04)">
<rect x="112" y="408" width="396" height="172" rx="3"/>
</g>
<!-- Traces -->
<g stroke="var(--bp-cyan)" stroke-width="0.5" fill="none" opacity="0.85">
<path d="M 120 420 L 200 420 L 200 480 L 240 480"/>
<path d="M 280 416 L 280 470 L 360 470"/>
<path d="M 380 420 L 480 420"/>
<path d="M 130 560 L 130 510 L 230 510 L 230 540 L 410 540"/>
<path d="M 450 560 L 450 500 L 490 500"/>
<path d="M 200 580 L 260 580"/>
</g>
<!-- Solder pads -->
<g fill="var(--bp-cyan)" opacity="0.85">
<circle cx="200" cy="420" r="1.4"/>
<circle cx="280" cy="416" r="1.4"/>
<circle cx="380" cy="420" r="1.4"/>
<circle cx="480" cy="420" r="1.4"/>
<circle cx="130" cy="510" r="1.4"/>
<circle cx="410" cy="540" r="1.4"/>
<circle cx="490" cy="500" r="1.4"/>
<circle cx="200" cy="580" r="1.4"/>
<circle cx="260" cy="580" r="1.4"/>
</g>
<!-- Tiny SMD components (capacitors / resistors) -->
<g stroke="var(--bp-cyan)" stroke-width="0.5" fill="none">
<rect x="148" y="426" width="14" height="6"/>
<rect x="168" y="426" width="6" height="6"/>
<rect x="320" y="554" width="14" height="6"/>
<rect x="345" y="552" width="6" height="10"/>
<rect x="440" y="450" width="10" height="6"/>
</g>
<!-- Screw markers for mainboard mount -->
<g stroke="var(--bp-cyan)" stroke-width="0.7" fill="none">
<g transform="translate(124, 420)"><circle r="3.2"/><line x1="-2.2" y1="0" x2="2.2" y2="0"/><line x1="0" y1="-2.2" x2="0" y2="2.2"/></g>
<g transform="translate(496, 420)"><circle r="3.2"/><line x1="-2.2" y1="0" x2="2.2" y2="0"/><line x1="0" y1="-2.2" x2="0" y2="2.2"/></g>
<g transform="translate(124, 568)"><circle r="3.2"/><line x1="-2.2" y1="0" x2="2.2" y2="0"/><line x1="0" y1="-2.2" x2="0" y2="2.2"/></g>
<g transform="translate(496, 568)"><circle r="3.2"/><line x1="-2.2" y1="0" x2="2.2" y2="0"/><line x1="0" y1="-2.2" x2="0" y2="2.2"/></g>
</g>
<!-- Label -->
<g>
<line x1="112" y1="404" x2="112" y2="396" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<line x1="112" y1="396" x2="172" y2="396" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="118" y="392" class="label">A · MAINBOARD</text>
</g>
</g>
<!-- ============== PART 3: DISPLAY (ON) ============== -->
<!-- Display gets a subtle "powered" treatment: dim cyan fill + scan lines + tiny status dot -->
<g data-part="display">
<g fill="rgba(127,179,213,0.05)">
<rect x="92" y="80" width="436" height="232" />
</g>
<!-- Scan lines -->
<g stroke="var(--bp-cyan)" stroke-width="0.3" opacity="0.4">
<line x1="92" y1="120" x2="528" y2="120"/>
<line x1="92" y1="160" x2="528" y2="160"/>
<line x1="92" y1="200" x2="528" y2="200"/>
<line x1="92" y1="240" x2="528" y2="240"/>
<line x1="92" y1="280" x2="528" y2="280"/>
</g>
<!-- Glyph: a tiny abstract page mark in upper-left of screen -->
<g stroke="var(--bp-cyan)" stroke-width="0.8" fill="none">
<rect x="116" y="104" width="60" height="78"/>
<line x1="124" y1="120" x2="168" y2="120"/>
<line x1="124" y1="132" x2="158" y2="132"/>
<line x1="124" y1="144" x2="168" y2="144"/>
<line x1="124" y1="156" x2="148" y2="156"/>
</g>
<text x="200" y="118" class="label">WRANECK.DE / INDEX</text>
<text x="200" y="132" class="label label-faint">200&nbsp;OK · 14&nbsp;KB · 0.18&nbsp;S</text>
<!-- Status dot -->
<g fill="var(--bp-warm)">
<circle cx="510" cy="92" r="2.4"/>
</g>
<!-- Label tag -->
<g>
<line x1="540" y1="196" x2="568" y2="196" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="574" y="200" class="label" transform="rotate(90 574 200)">B · DISPLAY · ON</text>
</g>
</g>
<!-- ============== PART 4: SSD ============== -->
<g data-part="ssd">
<!-- SSD module — sits top-right of mainboard area -->
<g stroke="var(--bp-ink)" stroke-width="1" fill="rgba(127,179,213,0.05)">
<rect x="412" y="430" width="90" height="34" rx="2"/>
</g>
<!-- Chip outlines on SSD -->
<g stroke="var(--bp-cyan)" stroke-width="0.6" fill="none">
<rect x="420" y="438" width="34" height="18"/>
<rect x="458" y="438" width="34" height="18"/>
</g>
<g stroke="var(--bp-cyan)" stroke-width="0.4" opacity="0.6">
<line x1="424" y1="444" x2="450" y2="444"/>
<line x1="424" y1="450" x2="450" y2="450"/>
<line x1="462" y1="444" x2="488" y2="444"/>
<line x1="462" y1="450" x2="488" y2="450"/>
</g>
<!-- Edge connector pins -->
<g stroke="var(--bp-cyan)" stroke-width="0.5">
<line x1="414" y1="466" x2="414" y2="470"/>
<line x1="418" y1="466" x2="418" y2="470"/>
<line x1="422" y1="466" x2="422" y2="470"/>
<line x1="426" y1="466" x2="426" y2="470"/>
<line x1="430" y1="466" x2="430" y2="470"/>
<line x1="434" y1="466" x2="434" y2="470"/>
</g>
<!-- Insertion arrow from outside chassis -->
<g stroke="var(--bp-warm)" stroke-width="0.8" fill="none">
<line x1="540" y1="447" x2="510" y2="447"/>
<path d="M 514 442 L 506 447 L 514 452" fill="none"/>
</g>
<!-- Label -->
<g>
<line x1="502" y1="430" x2="502" y2="420" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<line x1="502" y1="420" x2="546" y2="420" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="466" y="416" class="label">C · SSD</text>
</g>
</g>
<!-- ============== PART 5: CPU ============== -->
<g data-part="cpu">
<!-- CPU package — squared chip with pins -->
<g stroke="var(--bp-ink)" stroke-width="1" fill="rgba(127,179,213,0.05)">
<rect x="280" y="440" width="60" height="60" rx="1"/>
</g>
<!-- inner die -->
<g stroke="var(--bp-cyan)" stroke-width="0.6" fill="none">
<rect x="294" y="454" width="32" height="32"/>
<line x1="294" y1="454" x2="326" y2="486"/>
<line x1="326" y1="454" x2="294" y2="486"/>
</g>
<!-- pin grid (dots) -->
<g fill="var(--bp-cyan)" opacity="0.7">
<circle cx="286" cy="446" r="0.8"/><circle cx="292" cy="446" r="0.8"/><circle cx="298" cy="446" r="0.8"/>
<circle cx="322" cy="446" r="0.8"/><circle cx="328" cy="446" r="0.8"/><circle cx="334" cy="446" r="0.8"/>
<circle cx="286" cy="494" r="0.8"/><circle cx="292" cy="494" r="0.8"/><circle cx="298" cy="494" r="0.8"/>
<circle cx="322" cy="494" r="0.8"/><circle cx="328" cy="494" r="0.8"/><circle cx="334" cy="494" r="0.8"/>
</g>
<!-- BETA stamp -->
<g class="cpu-stamp">
<g stroke="var(--bp-warm)" stroke-width="1.2" fill="none">
<rect x="270" y="455" width="80" height="30" rx="2"/>
</g>
<text x="310" y="476" text-anchor="middle"
font-family="JetBrains Mono, monospace" font-size="14" letter-spacing="4"
fill="var(--bp-warm)" font-weight="600">SOON</text>
</g>
<!-- Label -->
<g>
<line x1="340" y1="500" x2="360" y2="510" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="366" y="514" class="label">D · CPU / BOTS</text>
</g>
</g>
<!-- ============== PART 6: BATTERY + KEYBOARD ============== -->
<g data-part="battery">
<!-- Battery cells: 3 cells across bottom of base interior -->
<g stroke="var(--bp-ink)" stroke-width="1" fill="rgba(127,179,213,0.05)">
<rect x="100" y="600" width="408" height="50" rx="2"/>
</g>
<g stroke="var(--bp-cyan)" stroke-width="0.6" fill="none">
<line x1="236" y1="600" x2="236" y2="650"/>
<line x1="372" y1="600" x2="372" y2="650"/>
<text x="168" y="630" text-anchor="middle" class="label">CELL 1</text>
<text x="304" y="630" text-anchor="middle" class="label">CELL 2</text>
<text x="440" y="630" text-anchor="middle" class="label">CELL 3</text>
</g>
<!-- + / - terminals -->
<g stroke="var(--bp-warm)" stroke-width="0.7" fill="none">
<line x1="110" y1="608" x2="110" y2="612"/>
<line x1="108" y1="610" x2="112" y2="610"/>
</g>
<g stroke="var(--bp-cyan)" stroke-width="0.7">
<line x1="496" y1="610" x2="500" y2="610"/>
</g>
<!-- Label -->
<g>
<line x1="100" y1="600" x2="100" y2="586" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<line x1="100" y1="586" x2="160" y2="586" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="106" y="582" class="label">E · AKKU 3-ZELL</text>
</g>
</g>
<!-- KEYBOARD overlay — also station 6 -->
<g data-part="keyboard">
<!-- Translucent indication of keyboard grid above the chassis cavity -->
<g stroke="var(--bp-cyan)" stroke-width="0.4" fill="none" opacity="0.55">
<!-- Row 1 -->
<g>
<rect x="100" y="384" width="20" height="14"/><rect x="124" y="384" width="20" height="14"/><rect x="148" y="384" width="20" height="14"/>
<rect x="172" y="384" width="20" height="14"/><rect x="196" y="384" width="20" height="14"/><rect x="220" y="384" width="20" height="14"/>
<rect x="244" y="384" width="20" height="14"/><rect x="268" y="384" width="20" height="14"/><rect x="292" y="384" width="20" height="14"/>
<rect x="316" y="384" width="20" height="14"/><rect x="340" y="384" width="20" height="14"/><rect x="364" y="384" width="20" height="14"/>
<rect x="388" y="384" width="20" height="14"/><rect x="412" y="384" width="20" height="14"/><rect x="436" y="384" width="20" height="14"/>
<rect x="460" y="384" width="20" height="14"/><rect x="484" y="384" width="40" height="14"/>
</g>
<!-- subtle hint of more rows below (just outlines) -->
<rect x="100" y="402" width="424" height="14"/>
<rect x="100" y="420" width="424" height="14"/>
</g>
<!-- Trackpad -->
<g stroke="var(--bp-cyan)" stroke-width="0.5" fill="none" opacity="0.6">
<rect x="220" y="554" width="180" height="36" rx="3"/>
</g>
<!-- Label -->
<g>
<line x1="400" y1="572" x2="430" y2="572" stroke="var(--bp-cyan)" stroke-width="0.5"/>
<text x="436" y="576" class="label">F · TASTATUR</text>
</g>
</g>
<!-- ============== PART 7: 3D-PRINTED DETAIL ============== -->
<g data-part="part3d">
<!-- A printed hex-pattern bracket added with arrow callout on left edge -->
<g transform="translate(86, 478)">
<!-- Outline of the printed bracket -->
<g stroke="var(--bp-warm)" stroke-width="1.1" fill="rgba(217,122,74,0.05)">
<path d="M 0 0 L 28 0 L 32 6 L 32 24 L 28 30 L 0 30 Z"/>
</g>
<!-- Infill hex-pattern hint -->
<g stroke="var(--bp-warm)" stroke-width="0.4" fill="none" opacity="0.7">
<path d="M 5 8 L 10 5 L 15 8 L 15 14 L 10 17 L 5 14 Z"/>
<path d="M 17 8 L 22 5 L 27 8 L 27 14 L 22 17 L 17 14 Z"/>
<path d="M 5 16 L 10 13 L 15 16 L 15 22 L 10 25 L 5 22 Z" />
<path d="M 17 16 L 22 13 L 27 16 L 27 22 L 22 25 L 17 22 Z" />
</g>
</g>
<!-- Callout arrow from chassis edge -->
<g stroke="var(--bp-warm)" stroke-width="0.9" fill="none">
<line x1="60" y1="540" x2="40" y2="540"/>
<line x1="40" y1="540" x2="40" y2="500"/>
<line x1="40" y1="500" x2="86" y2="495"/>
<path d="M 84 491 L 86 495 L 82 497"/>
</g>
<!-- Caption -->
<g>
<text x="14" y="556" class="label" fill="var(--bp-warm)">G · 3D-DRUCK</text>
<text x="14" y="568" class="label label-faint">PLA · 0.2&nbsp;MM · 25%&nbsp;INFILL</text>
</g>
</g>
<!-- ============== Display GLOW (station 8) ============== -->
<g class="display-glow">
<defs>
<radialGradient id="warmGlow" cx="50%" cy="50%" r="60%">
<stop offset="0%" stop-color="#d97a4a" stop-opacity="0.55"/>
<stop offset="60%" stop-color="#d97a4a" stop-opacity="0.12"/>
<stop offset="100%" stop-color="#d97a4a" stop-opacity="0"/>
</radialGradient>
</defs>
<rect x="92" y="80" width="436" height="232" fill="url(#warmGlow)"/>
<!-- Final text on the screen -->
<g font-family="Source Serif 4, serif" fill="#fbe4d3">
<text x="310" y="178" text-anchor="middle" font-size="22" font-style="italic">So. Jetzt bist du dran.</text>
<text x="310" y="216" text-anchor="middle" font-family="JetBrains Mono, monospace" font-size="11" letter-spacing="3" fill="#d97a4a">&nbsp;SCROLL · WEITER</text>
</g>
</g>
</svg>
</div>
</aside>
</div>
<!-- =========================== STATION 8 / CTA ======================= -->
<section class="story final" id="st-8" aria-labelledby="final-title">
<div class="final__inner">
<div class="final__caption">07 / 07 — Montage abgeschlossen</div>
<h2 class="final__title" id="final-title">So.<br/>Jetzt bist <em>du</em> dran.</h2>
<p class="final__sub">
Schreib mir eine Mail. Oder ruf an. Oder pack dir 15 Minuten in den Kalender — kostet nichts, verpflichtet zu nichts.
</p>
<div class="display-cta" role="region" aria-label="Kontaktmöglichkeit">
<p class="display-cta__greeting">Schreib mir.</p>
<ul class="cta-list">
<li>
<a href="mailto:info@wraneck.de">
<span><span class="kind">Mail</span><span class="val">info@wraneck.de</span></span>
<span class="arrow"></span>
</a>
</li>
</ul>
<div class="cal-embed">
Telefon und Terminbuchung folgen, sobald die Werkstatt eingeraeumt ist.
</div>
</div>
</div>
</section>
</main>
<!-- ============================== FOOTER ================================ -->
<footer>
<div class="footer__inner">
<div>
<h4>Wraneck</h4>
<p>Krys Baumgarten</p>
<p>IT-Administration · Webseiten · Hosting · IT-Hilfe vor Ort · 3D-Druck</p>
<p style="margin-top:14px; color: var(--bp-ink-dim);">Magdeburg &amp; Umkreis</p>
</div>
<div>
<h4>Kontakt</h4>
<p><a href="mailto:info@wraneck.de">info@wraneck.de</a></p>
<p style="color: var(--bp-ink-dim); margin-top: 8px;">MoFr, abends. Sa, mittags.</p>
</div>
<div>
<h4>Klein gedruckt</h4>
<p><a href="/impressum">Impressum</a></p>
<p><a href="/datenschutz">Datenschutz</a></p>
<p style="color: var(--bp-ink-dim); margin-top: 8px;">Kleingewerbeanmeldung in Arbeit</p>
</div>
</div>
<div class="footer__legal">
<span>© 2026 Wraneck · Krys Baumgarten · Magdeburg</span>
<span>Diese Seite nutzt keine Tracker, keine Cookies, kein US-CDN.</span>
</div>
</footer>
<a href="mailto:info@wraneck.de" class="mobile-cta" aria-label="Per Mail kontaktieren">Schreib mir</a>
<!-- ============================== SCRIPTS =============================== -->
<script>
/* Wraneck — scroll story orchestrator
Plain vanilla IntersectionObserver. Lenis / GSAP not required for this
fidelity; in the Astro build, drop in Lenis for smooth-scroll if desired. */
(function () {
const PARTS = {
1: ['chassis'],
2: ['chassis', 'mainboard'],
3: ['chassis', 'mainboard', 'display'],
4: ['chassis', 'mainboard', 'display', 'ssd'],
5: ['chassis', 'mainboard', 'display', 'ssd', 'cpu'],
6: ['chassis', 'mainboard', 'display', 'ssd', 'cpu', 'battery', 'keyboard'],
7: ['chassis', 'mainboard', 'display', 'ssd', 'cpu', 'battery', 'keyboard', 'part3d'],
};
const notebook = document.querySelector('.notebook');
const allParts = notebook.querySelectorAll('[data-part]');
const stations = document.querySelectorAll('.station[data-station]');
const finalSection = document.getElementById('st-8');
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
// If reduced motion: just show everything from the start.
if (reducedMotion) {
allParts.forEach(p => p.classList.add('is-on'));
notebook.classList.add('is-final');
stations.forEach(s => s.classList.add('is-in'));
return;
}
// Track active station — most recent one whose top has crossed 40% of viewport.
let activeStation = 0;
function updateParts(stationNo) {
if (stationNo === activeStation) return;
activeStation = stationNo;
const visibleParts = new Set(PARTS[stationNo] || []);
allParts.forEach(p => {
const id = p.getAttribute('data-part');
if (visibleParts.has(id)) p.classList.add('is-on');
else p.classList.remove('is-on');
});
}
const stationObserver = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('is-in');
const n = parseInt(e.target.getAttribute('data-station'), 10);
if (n) updateParts(n);
}
});
}, { threshold: 0.35, rootMargin: '0px 0px -10% 0px' });
stations.forEach(s => stationObserver.observe(s));
// Final section — turn display warm + open
const finalObserver = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
// ensure all 7 parts visible
allParts.forEach(p => p.classList.add('is-on'));
notebook.classList.add('is-final');
}
});
}, { threshold: 0.15 });
if (finalSection) finalObserver.observe(finalSection);
// Also: if user lands on page mid-scroll, fire updateParts for the topmost visible station immediately.
setTimeout(() => {
let topMost = null;
stations.forEach(s => {
const r = s.getBoundingClientRect();
if (r.top < window.innerHeight * 0.6 && r.bottom > 0) topMost = s;
});
if (topMost) {
const n = parseInt(topMost.getAttribute('data-station'), 10);
if (n) updateParts(n);
topMost.classList.add('is-in');
} else {
// before first station — show chassis as a teaser hint
updateParts(1);
}
}, 100);
})();
</script>
</body>
</html>