Editorial-/Magazin-Layout
Ein Journalbeitrag in drei Satzspiegeln (Magazin, Zeitung, Kunstbuch) auf einem 12er-Raster, mit Initiale, Pull-Quote, Marginalie, Zeilen-Reveal und leichter Bildparallaxe.
Journal, Case Study oder Haltungstext mit einem starken Bild: Serif-Titel links, Bild rechts, Pull-Quote und randloses Breitbild.
Eine Seite, gesetzt wie ein gedrucktes Magazin. Ein 12er-Raster mit viel Weißraum trägt eine große Serif, oft mit kursivem Akzent, und eine kleine Grotesk für Labels. Bilder wechseln bewusst Format und Größe: mal randabfallend, mal klein mit Nummer und Bildunterschrift. Dazu kommen Elemente aus dem Print: Rubrik und Kicker, ein größerer Lead, Initiale, Pull-Quote, mehrspaltiger Text, Marginalien und Fußnoten. Haarlinien, Kapitelnummern und Datumszeilen gliedern die Abschnitte. Die Bewegung bleibt leise: weiches Scrollen, Zeilen-Reveals, leichte Bildparallaxe.
Die Seite signalisiert Inhalt, Sorgfalt und Kuratierung. Leser kennen die Konventionen aus dem Print und vertrauen ihnen. Größenkontraste und eine klare Lesereihenfolge führen durch den Text. So entsteht ein Gegenentwurf zum austauschbaren SaaS-Look.
Wann einsetzen
Für Case Studies, Journale und Blogs, Studios mit Haltung im Text, Kultur, Mode, Architektur und Personal Brands mit echtem Inhalt.
Wann nicht
Bei Conversion-Landingpages mit nur einem CTA. Und wenn es keinen redaktionellen Inhalt gibt, denn dann wirkt das Layout leer.
Varianten
- Magazin: Serif-Grotesk-Kombination mit Pull-Quotes
- Zeitung: Titelkopf, Rubriken, Spaltensatz mit Linien
- Kunstbuch: wenige große Bilder, kaum Text
- Magazin-Cover als Hero mit Titel, Ausgabe und Datum
Umsetzung
12-Spalten-Grid. Bilder und Textblöcke per grid-column und grid-row bewusst unterschiedlich platzieren. Varianten lassen sich mit demselben HTML über ein Attribut am Wrapper umschalten. Typo-Feinheiten: text-wrap: balance für Headlines, text-wrap: pretty und hyphens: auto für Fließtext, initial-letter für Initialen (Chrome; Safari mit -webkit-; sonst float als Fallback), hängende Anführungszeichen per negativem text-indent oder hanging-punctuation (nur Safari), font-variant-numeric: oldstyle-nums. Mehrspaltigen Satz mit columns nur für kurze Blöcke verwenden, sonst leidet der Lesefluss. Bilder als <figure> mit <figcaption>. Zeilen-Reveals mit GSAP SplitText (mask: 'lines'), Parallaxe mit ScrollTrigger scrub. Lenis für weiches Scrollen ist optional und standardmäßig aus: Reveals und Parallaxe laufen mit nativem Scroll. Nur in Eigenprojekten einschalten, nie in Rezepten, die smooth-scroll-lenis ausschließen.
Robust umsetzen
Telefon. Einspaltig, aber Größenkontraste und Bildformatwechsel bleiben. Marginalien stehen unter dem Absatz, Spaltensatz wird einspaltig. Weiches Scrollen auf Touch-Geräten abschalten.
Ohne Bewegung. Keine Parallaxe, kein weiches Scrollen, keine Zeilen-Reveals. Der Text ist sofort sichtbar.
Barrierefrei. Saubere Überschriftenhierarchie trotz Print-Optik: eine H1, Zwischenüberschriften als H2. Pull-Quotes als <blockquote>; wiederholt ein Pull-Quote nur den Fließtext, bekommt es aria-hidden. Marginalien als <aside>. Mehrspaltigen Satz vermeiden, wenn er Scrollen hoch und runter erzwingt. Ein rein dekorativer Titelkopf bekommt aria-hidden.
Code
<!DOCTYPE html>
<!--
Editorial-/Magazin-Layout
Fundus · Hero & Section-Layouts · https://cecodesign.de/lab/fundus/hero-layouts/editorial-magazin-layout/
Eigenständige Datei. Bilder liegen hier unter bilder/ – eigene einsetzen.
-->
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Editorial-/Magazin-Layout · Fundus-Demo</title>
<script>document.documentElement.classList.add('js');if(matchMedia('(prefers-reduced-motion: reduce)').matches)document.documentElement.classList.add('reduziert')</script>
<style>
@font-face { font-family: 'Instrument Sans'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/instrument-sans:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 400 700; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/geist-mono:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'Instrument Serif'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/instrument-serif@latest/latin-400-normal.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Instrument Serif'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/instrument-serif@latest/latin-400-italic.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: 'Source Serif 4'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/source-serif-4@latest/latin-400-normal.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
/* Editorial-Layout: ein Beitrag, drei Satzspiegel (Magazin, Zeitung, Kunstbuch).
Gleiches HTML, nur die Rasterplätze wechseln über [data-variante]. */
:root {
--papier: #ebe7de; --tafel: #f4f1ea; --tinte: #1b1a17; --leise: rgba(27, 26, 23, .66); --linie: rgba(27, 26, 23, .18);
--ziegel: #a3402a;
--kurve: cubic-bezier(0.25, 1, 0.5, 1); /* power3.out */
--rand: clamp(16px, 3.4vw, 48px);
--spalt: clamp(12px, 1.6vw, 24px);
--fliess: clamp(17px, 1.3vw, 19px); /* Fließtext */
--lead: clamp(21px, 1.85vw, 26px); /* Lead ≈ 1,4 × Fließtext */
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { background: var(--papier); color: var(--tinte); font-family: 'Instrument Sans', system-ui, sans-serif; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
html.lenis, html.lenis body { height: auto; }
.lenis-smooth { scroll-behavior: auto !important; }
html, body { overflow-x: clip; }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
em { font-family: 'Instrument Serif', Georgia, serif; font-style: italic; font-weight: 400; }
.mono { font: 500 11px/1.45 'Geist Mono', ui-monospace, monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--leise); }
.mono b { font-weight: 500; color: var(--tinte); }
.raster { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--spalt); padding-inline: var(--rand); }
/* ---------- Kopf ---------- */
.kopf { padding-inline: var(--rand); }
.kopf__leiste { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px; min-height: 60px; border-bottom: 1px solid var(--linie); }
.kopf__leiste > :last-child { justify-self: end; }
.marke { display: flex; align-items: baseline; gap: 14px; white-space: nowrap; }
.marke__name { font: italic 400 26px/1 'Instrument Serif', Georgia, serif; letter-spacing: -.01em; }
.kopf__datum { display: none; }
.kopf__titel, .kopf__rubriken { display: none; }
.modi { display: flex; gap: 4px; }
.modi button { font: inherit; letter-spacing: inherit; text-transform: inherit; color: var(--leise); background: none; border: 1px solid var(--linie); border-radius: 999px; height: 28px; padding: 0 11px; cursor: pointer; transition: color 150ms linear, background-color 150ms linear, border-color 150ms linear; }
.modi button:hover { color: var(--tinte); border-color: rgba(27, 26, 23, .4); }
.modi button[aria-pressed='true'] { background: var(--tinte); color: var(--papier); border-color: var(--tinte); }
.modi button:focus-visible { outline: 2px solid var(--ziegel); outline-offset: 2px; }
/* ---------- Bausteine des Beitrags ---------- */
.beitrag { padding-top: clamp(28px, 5vh, 56px); padding-bottom: clamp(64px, 12vh, 140px); align-items: start; }
.kicker { display: flex; gap: 18px; flex-wrap: wrap; }
.kicker__rubrik { color: var(--ziegel); }
.titel { font: 400 clamp(56px, 9.4vw, 148px)/.88 'Instrument Serif', Georgia, serif; letter-spacing: -.035em; text-wrap: balance; margin-top: 18px; }
.titel em { letter-spacing: -.02em; padding-right: .05em; }
.lead { font-size: var(--lead); line-height: 1.32; letter-spacing: -.012em; text-wrap: pretty; margin-top: clamp(22px, 3.4vh, 36px); max-width: 30em; }
.byline { margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--linie); display: flex; gap: 6px 18px; flex-wrap: wrap; }
.abb { display: grid; gap: 10px; }
.abb__rahmen { position: relative; overflow: hidden; background: var(--tafel); }
.abb__rahmen :is(img, svg) { display: block; width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.abb figcaption { display: flex; gap: 12px; }
.abb figcaption b { color: var(--tinte); font-weight: 500; white-space: nowrap; }
.abb--hero .abb__rahmen { aspect-ratio: 4 / 5; }
.abb--hero img { object-fit: contain; }
.abb--breit .abb__rahmen { aspect-ratio: 21 / 9; background: #e7e7e7; }
.abb--breit figcaption { padding-inline: var(--rand); }
.text { font: 400 var(--fliess)/1.62 'Source Serif 4', Georgia, serif; font-variant-numeric: oldstyle-nums proportional-nums; max-width: 65ch; text-wrap: pretty; hyphens: auto; }
.text p + p { text-indent: 1.4em; }
.text sup { font-size: .62em; line-height: 0; color: var(--ziegel); font-family: 'Geist Mono', monospace; padding-left: 1px; }
.initial::first-letter { -webkit-initial-letter: 3; initial-letter: 3; font-family: 'Instrument Serif', Georgia, serif; color: var(--ziegel); margin-right: .1em; }
@supports not ((initial-letter: 3) or (-webkit-initial-letter: 3)) {
.initial::first-letter { float: left; font-size: 4.4em; line-height: .78; padding-top: .06em; }
}
.zwischen { font: italic 400 clamp(26px, 2.4vw, 34px)/1.05 'Instrument Serif', Georgia, serif; letter-spacing: -.01em; margin-bottom: .55em; }
.marginalie { display: grid; gap: 8px; padding-top: 10px; border-top: 1px solid var(--linie); font-size: 14px; line-height: 1.5; color: var(--leise); max-width: 30ch; }
.marginalie b { color: var(--ziegel); font-weight: 500; font-family: 'Geist Mono', monospace; font-size: 12px; }
.zitat { margin-block: clamp(64px, 12vh, 140px); }
.zitat p { font: italic 400 clamp(36px, 4.8vw, 76px)/1.02 'Instrument Serif', Georgia, serif; letter-spacing: -.02em; text-wrap: balance; }
.zitat p { text-indent: -.42em; } /* hängendes » wie hanging-punctuation: first (Safari) */
.zitat .zeile-mask { padding-inline: .5em; margin-inline: -.5em; }
.zitat .zeile-mask, .zitat .zeile { text-indent: 0; }
.zitat .zeile-mask:first-child .zeile { text-indent: -.42em; }
.zitat footer { margin-top: 22px; }
/* Speisekarte als gesetzte Tafel (Abb. 3) */
.karte { background: var(--tafel); padding: clamp(18px, 2vw, 28px); display: grid; gap: 14px; border: 1px solid var(--linie); }
.karte__kopf { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 10px; border-bottom: 2px solid var(--tinte); }
.karte__name { font: 400 clamp(24px, 2.2vw, 30px)/1 'Instrument Serif', Georgia, serif; letter-spacing: .02em; text-transform: uppercase; }
.karte__spalten { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 20px; }
.karte__rubrik { font: 500 10px/1 'Geist Mono', monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--ziegel); padding-bottom: 6px; margin-bottom: 4px; border-bottom: 1px solid var(--linie); }
.karte__posten { display: flex; justify-content: space-between; gap: 8px; font: 400 14px/1.75 'Source Serif 4', Georgia, serif; font-variant-numeric: oldstyle-nums; }
/* Nächster Beitrag */
.naechster { padding-block: clamp(28px, 5vh, 48px) clamp(40px, 8vh, 96px); border-top: 1px solid var(--linie); margin-inline: var(--rand); padding-inline: 0; align-items: end; row-gap: 18px; }
.naechster > .mono { grid-column: 1 / 4; align-self: start; }
.naechster h2 { grid-column: 4 / 10; font: 400 clamp(32px, 3.6vw, 56px)/.98 'Instrument Serif', Georgia, serif; letter-spacing: -.025em; text-wrap: balance; }
.naechster h2 a { background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size 600ms var(--kurve); }
.naechster h2 a:hover { background-size: 100% 1px; }
.naechster figure { grid-column: 10 / 13; }
.naechster .abb__rahmen { aspect-ratio: 3 / 2; background: #232e32; }
.kolophon { padding: 0 var(--rand) 28px; display: flex; justify-content: space-between; gap: 12px 24px; flex-wrap: wrap; }
/* Cover-Bausteine: nur in der Variante Cover sichtbar */
.abb__rahmen .abb__cover, .titelzeilen, .preis, .nur-cover { display: none; }
/* Werte-Anzeige */
.werte { position: fixed; z-index: 20; right: 12px; bottom: 12px; display: grid; justify-items: start; gap: 7px; max-width: min(430px, calc(100vw - 24px)); /* schmal genug, um rechts neben der Textspalte zu bleiben */ padding: 8px 12px; background: rgba(244, 241, 234, .9); border: 1px solid var(--linie); backdrop-filter: blur(6px); font-size: 10px; }
/* =========================================================
Variante MAGAZIN: Serif-Grotesk mit Bild rechts, Pull-Quote
========================================================= */
[data-variante='magazin'] .kicker { grid-column: 1 / -1; grid-row: 1; }
[data-variante='magazin'] .titel { grid-column: 1 / 9; grid-row: 2; }
[data-variante='magazin'] .lead { grid-column: 1 / 7; grid-row: 3; }
[data-variante='magazin'] .byline { grid-column: 1 / 7; grid-row: 4; }
[data-variante='magazin'] .abb--hero { grid-column: 9 / 13; grid-row: 2 / 6; margin-top: 18px; }
[data-variante='magazin'] .text--1 { grid-column: 3 / 9; grid-row: 5; margin-top: clamp(40px, 7vh, 80px); }
[data-variante='magazin'] .marginalie { grid-column: 1 / 3; grid-row: 5; margin-top: clamp(40px, 7vh, 80px); }
[data-variante='magazin'] .zitat { grid-column: 2 / 12; grid-row: 7; }
[data-variante='magazin'] .abb--breit { grid-column: 1 / -1; grid-row: 8; margin-inline: calc(var(--rand) * -1); }
[data-variante='magazin'] .text--2 { grid-column: 3 / 9; grid-row: 9; margin-top: clamp(48px, 9vh, 104px); }
[data-variante='magazin'] .abb--karte { grid-column: 10 / 13; grid-row: 9; margin-top: clamp(48px, 9vh, 104px); }
[data-variante='magazin'] .karte__spalten { grid-template-columns: 1fr; }
/* =========================================================
Variante ZEITUNG: Titelkopf, Rubriken, Spaltensatz mit Linien
========================================================= */
[data-variante='zeitung'] .marke { display: none; }
[data-variante='zeitung'] .kopf__datum { display: block; }
[data-variante='zeitung'] .kopf__leiste { border-bottom: 0; min-height: 48px; }
[data-variante='zeitung'] .kopf__titel { display: block; text-align: center; font: 400 clamp(60px, 9vw, 132px)/.86 'Instrument Serif', Georgia, serif; letter-spacing: -.03em; padding-block: 2px 14px; border-top: 1px solid var(--tinte); }
[data-variante='zeitung'] .kopf__rubriken { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px 28px; padding-block: 10px; border-top: 3px double var(--tinte); border-bottom: 1px solid var(--tinte); }
[data-variante='zeitung'] .kopf__rubriken a[aria-current] { color: var(--tinte); }
[data-variante='zeitung'] .beitrag { padding-top: clamp(20px, 3.4vh, 36px); }
[data-variante='zeitung'] .kicker { grid-column: 1 / -1; grid-row: 1; }
[data-variante='zeitung'] .titel { grid-column: 1 / 10; grid-row: 2; font-size: clamp(48px, 7vw, 108px); line-height: .9; margin-top: 12px; }
[data-variante='zeitung'] .lead { grid-column: 10 / 13; grid-row: 2; align-self: end; margin-top: 0; font: italic 400 clamp(19px, 1.4vw, 21px)/1.22 'Instrument Serif', Georgia, serif; letter-spacing: 0; }
[data-variante='zeitung'] .byline { grid-column: 1 / -1; grid-row: 3; margin-top: 18px; padding-block: 9px; border-top-color: var(--tinte); border-bottom: 1px solid var(--linie); }
[data-variante='zeitung'] .abb--hero { grid-column: 1 / 7; grid-row: 4 / 6; margin-top: 22px; }
[data-variante='zeitung'] .abb--hero .abb__rahmen { aspect-ratio: 3 / 2; }
[data-variante='zeitung'] .text--1 { grid-column: 7 / 13; grid-row: 4; margin-top: 22px; max-width: none; columns: 2; column-gap: calc(var(--spalt) * 1.5); column-rule: 1px solid var(--linie); font-size: 15.5px; line-height: 1.5; }
[data-variante='zeitung'] .marginalie { grid-column: 7 / 13; grid-row: 5; margin-top: 18px; max-width: none; }
[data-variante='zeitung'] .zitat { grid-column: 1 / -1; grid-row: 6; margin-block: clamp(36px, 7vh, 72px); padding-block: 24px; border-block: 1px solid var(--tinte); text-align: center; }
[data-variante='zeitung'] .zitat p { font-size: clamp(30px, 3.6vw, 56px); }
[data-variante='zeitung'] .zitat p, [data-variante='zeitung'] .zitat .zeile-mask:first-child .zeile { text-indent: 0; }
[data-variante='zeitung'] .abb--breit { grid-column: 1 / 9; grid-row: 7; }
[data-variante='zeitung'] .abb--breit .abb__rahmen { aspect-ratio: 3 / 2; }
[data-variante='zeitung'] .abb--breit figcaption { padding-inline: 0; }
[data-variante='zeitung'] .text--2 { grid-column: 9 / 13; grid-row: 7 / 9; max-width: none; font-size: 15.5px; line-height: 1.5; padding-left: var(--spalt); border-left: 1px solid var(--linie); }
[data-variante='zeitung'] .abb--karte { grid-column: 1 / 9; grid-row: 8; margin-top: 28px; }
[data-variante='zeitung'] .karte__spalten { grid-template-columns: repeat(3, 1fr); }
/* =========================================================
Variante KUNSTBUCH: große Tafeln, kaum Text, viel Weißraum
========================================================= */
[data-variante='kunstbuch'] .beitrag { padding-top: clamp(36px, 7vh, 80px); }
[data-variante='kunstbuch'] .kicker { grid-column: 1 / 4; grid-row: 1; flex-direction: column; gap: 4px; }
[data-variante='kunstbuch'] .abb--hero { grid-column: 4 / 13; grid-row: 1 / 4; }
[data-variante='kunstbuch'] .abb--hero .abb__rahmen { aspect-ratio: 16 / 10; }
[data-variante='kunstbuch'] .abb--hero figcaption { justify-content: flex-end; }
[data-variante='kunstbuch'] .titel { grid-column: 1 / 4; grid-row: 2; align-self: end; font: italic 400 clamp(30px, 2.6vw, 40px)/1.02 'Instrument Serif', Georgia, serif; letter-spacing: -.01em; }
[data-variante='kunstbuch'] .text--1 { grid-column: 1 / 4; grid-row: 3; align-self: end; margin-top: 18px; padding-bottom: 24px; font: 400 13px/1.55 'Instrument Sans', sans-serif; color: var(--leise); }
[data-variante='kunstbuch'] .text--1 p:not(:first-child), [data-variante='kunstbuch'] .text--1 sup { display: none; }
[data-variante='kunstbuch'] .initial::first-letter { initial-letter: normal; -webkit-initial-letter: normal; font: inherit; color: inherit; margin: 0; float: none; }
[data-variante='kunstbuch'] .lead,
[data-variante='kunstbuch'] .byline,
[data-variante='kunstbuch'] .marginalie,
[data-variante='kunstbuch'] .zitat,
[data-variante='kunstbuch'] .text--2 { display: none; }
[data-variante='kunstbuch'] .abb--breit { grid-column: 1 / 10; grid-row: 4; margin-top: clamp(80px, 16vh, 180px); }
[data-variante='kunstbuch'] .abb--breit .abb__rahmen { aspect-ratio: 16 / 10; }
[data-variante='kunstbuch'] .abb--breit figcaption { padding-inline: 0; }
[data-variante='kunstbuch'] .abb--karte { grid-column: 7 / 12; grid-row: 5; margin-top: clamp(80px, 16vh, 180px); }
[data-variante='kunstbuch'] .karte__spalten { grid-template-columns: repeat(3, 1fr); }
[data-variante='kunstbuch'] figcaption b::before { content: 'Tafel '; }
[data-variante='kunstbuch'] figcaption b span { display: none; }
/* =========================================================
Variante COVER: Magazin-Titel als Hero, dann der Beitrag
========================================================= */
[data-variante='cover'] { --kopf-h: 200px; }
[data-variante='cover'] .kopf { position: absolute; z-index: 3; inset: 0 0 auto; color: var(--papier); }
[data-variante='cover'] .kopf .mono, [data-variante='cover'] .kopf .mono b { color: rgba(244, 241, 234, .78); }
[data-variante='cover'] .kopf__leiste { border-bottom-color: rgba(244, 241, 234, .26); }
[data-variante='cover'] .marke { display: none; }
[data-variante='cover'] .kopf__datum { display: block; }
[data-variante='cover'] .kopf__titel { display: block; text-align: center; font: 400 clamp(96px, 19.5vw, 300px)/.8 'Instrument Serif', Georgia, serif; letter-spacing: -.045em; padding-top: clamp(6px, 1.2vw, 16px); }
[data-variante='cover'] .modi button { color: rgba(244, 241, 234, .8); border-color: rgba(244, 241, 234, .32); }
[data-variante='cover'] .modi button:hover { color: var(--papier); border-color: rgba(244, 241, 234, .7); }
[data-variante='cover'] .modi button[aria-pressed='true'] { background: var(--papier); color: var(--tinte); border-color: var(--papier); }
[data-variante='cover'] .beitrag { padding-top: 0; grid-template-rows: auto 1fr auto auto auto; }
[data-variante='cover'] .abb--hero { grid-column: 1 / -1; grid-row: 1 / 6; margin-inline: calc(var(--rand) * -1); min-height: max(100svh, 640px); position: relative; }
[data-variante='cover'] .abb--hero .abb__rahmen { position: absolute; inset: 0; aspect-ratio: auto; background: #1c2731; }
[data-variante='cover'] .abb--hero .abb__rahmen::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(13, 18, 22, .62), rgba(13, 18, 22, .1) 62%), linear-gradient(0deg, rgba(13, 18, 22, .55), transparent 40%); pointer-events: none; }
[data-variante='cover'] .abb--hero .abb__rahmen > svg:not(.abb__cover) { display: none; }
[data-variante='cover'] .abb--hero .abb__cover { display: block; }
[data-variante='cover'] .abb--hero figcaption { position: absolute; z-index: 1; right: var(--rand); bottom: 22px; color: rgba(244, 241, 234, .6); }
[data-variante='cover'] .abb--hero figcaption b { color: rgba(244, 241, 234, .85); }
[data-variante='cover'] .nur-heft { display: none; }
[data-variante='cover'] .nur-cover { display: inline; }
[data-variante='cover'] .kicker, [data-variante='cover'] .titel, [data-variante='cover'] .lead, [data-variante='cover'] .byline, [data-variante='cover'] .titelzeilen, [data-variante='cover'] .preis { position: relative; z-index: 2; color: var(--papier); }
[data-variante='cover'] .kicker { grid-column: 1 / 7; grid-row: 1; margin-top: calc(var(--kopf-h) + 22px); }
[data-variante='cover'] .kicker span, [data-variante='cover'] .kicker__rubrik { color: rgba(244, 241, 234, .85); }
[data-variante='cover'] .titelzeilen { display: grid; grid-column: 9 / 13; grid-row: 1 / 3; align-self: start; margin-top: calc(var(--kopf-h) + 18px); list-style: none; gap: 12px; }
[data-variante='cover'] .titelzeilen li { display: grid; grid-template-columns: 3.6em 1fr; gap: 8px; align-items: baseline; padding-top: 10px; border-top: 1px solid rgba(244, 241, 234, .3); font: italic 400 clamp(20px, 1.7vw, 26px)/1.1 'Instrument Serif', Georgia, serif; }
[data-variante='cover'] .titelzeilen b { font: 500 11px/1 'Geist Mono', monospace; letter-spacing: .14em; color: rgba(244, 241, 234, .7); font-style: normal; }
[data-variante='cover'] .titel { grid-column: 1 / 9; grid-row: 3; align-self: end; font-size: clamp(56px, 7.6vw, 124px); text-shadow: 0 2px 30px rgba(13, 18, 22, .35); }
[data-variante='cover'] .lead { grid-column: 1 / 7; grid-row: 4; color: rgba(244, 241, 234, .9); margin-top: 18px; font-size: clamp(18px, 1.45vw, 22px); }
[data-variante='cover'] .byline { grid-column: 1 / 7; grid-row: 5; margin-bottom: 30px; border-top-color: rgba(244, 241, 234, .3); }
[data-variante='cover'] .byline, [data-variante='cover'] .byline b { color: rgba(244, 241, 234, .78); }
[data-variante='cover'] .preis { display: grid; grid-column: 10 / 13; grid-row: 5; justify-self: end; align-self: end; justify-items: end; gap: 6px; margin-bottom: 56px; color: rgba(244, 241, 234, .78); }
[data-variante='cover'] .preis svg { width: 96px; height: 30px; color: var(--papier); background: none; }
[data-variante='cover'] .text--1 { grid-column: 3 / 9; grid-row: 6; margin-top: clamp(56px, 10vh, 112px); }
[data-variante='cover'] .marginalie { grid-column: 1 / 3; grid-row: 6; margin-top: clamp(56px, 10vh, 112px); }
[data-variante='cover'] .zitat { grid-column: 2 / 12; grid-row: 7; }
[data-variante='cover'] .abb--breit { grid-column: 1 / -1; grid-row: 8; margin-inline: calc(var(--rand) * -1); }
[data-variante='cover'] .text--2 { grid-column: 3 / 9; grid-row: 9; margin-top: clamp(48px, 9vh, 104px); }
[data-variante='cover'] .abb--karte { grid-column: 10 / 13; grid-row: 9; margin-top: clamp(48px, 9vh, 104px); }
[data-variante='cover'] .karte__spalten { grid-template-columns: 1fr; }
/* ---------- Bewegung: Startzustände nur mit JS und ohne .reduziert ---------- */
.js:not(.reduziert) [data-zeilen] { visibility: hidden; }
.zeile-mask { padding-block: .08em; margin-block: -.08em; }
/* ---------- Mittlere Breiten ---------- */
@media (max-width: 1080px) {
[data-variante='magazin'] .abb--hero { grid-row: 2 / 5; }
[data-variante='magazin'] .text--1, [data-variante='magazin'] .text--2 { grid-column: 1 / 9; }
[data-variante='magazin'] .marginalie { grid-column: 10 / 13; }
[data-variante='zeitung'] .text--1 { columns: 1; }
[data-variante='zeitung'] .lead { grid-column: 1 / 10; grid-row: 3; margin-top: 14px; }
[data-variante='zeitung'] .byline { grid-row: 4; }
[data-variante='zeitung'] .abb--hero { grid-row: 5 / 7; }
[data-variante='zeitung'] .text--1 { grid-row: 5; }
[data-variante='zeitung'] .marginalie { grid-row: 6; }
[data-variante='zeitung'] .zitat { grid-row: 7; }
[data-variante='zeitung'] .abb--breit, [data-variante='zeitung'] .text--2 { grid-row: 8; }
[data-variante='zeitung'] .abb--karte { grid-row: 9; }
[data-variante='cover'] .titelzeilen { grid-column: 8 / 13; }
[data-variante='cover'] .text--1, [data-variante='cover'] .text--2 { grid-column: 1 / 9; }
[data-variante='cover'] .marginalie { grid-column: 10 / 13; }
}
/* ---------- Telefon: einspaltig, Größenkontraste bleiben ---------- */
@media (max-width: 760px) {
.kopf__ausgabe { display: none; }
.kopf__leiste { grid-template-columns: 1fr auto; }
.marke .mono { display: none; }
.beitrag > * { grid-column: 1 / -1 !important; grid-row: auto !important; }
.beitrag .abb--breit { margin-inline: calc(var(--rand) * -1); }
.titel { font-size: clamp(52px, 15vw, 72px); }
.text { max-width: none; }
.abb--hero { margin-top: 28px !important; }
.marginalie { margin-top: 18px !important; max-width: none; }
.zitat p, .zitat .zeile-mask:first-child .zeile { text-indent: 0 !important; }
.karte__spalten { grid-template-columns: 1fr 1fr !important; }
.naechster > * { grid-column: 1 / -1 !important; }
.naechster figure { max-width: 60%; }
[data-variante='magazin'] .abb--hero .abb__rahmen { aspect-ratio: 4 / 3; }
[data-variante='zeitung'] .kopf__datum { display: none; }
[data-variante='zeitung'] .kopf__leiste { grid-template-columns: 1fr auto; }
[data-variante='zeitung'] .kopf__leiste::before { content: 'Nr. 07 · Herbst 2026'; font: 500 10px/1 'Geist Mono', monospace; letter-spacing: .14em; color: var(--leise); }
[data-variante='zeitung'] .kopf__titel { font-size: 21vw; }
[data-variante='zeitung'] .kopf__rubriken { gap: 4px 12px; font-size: 10px; letter-spacing: .08em; }
[data-variante='zeitung'] .titel { font-size: clamp(40px, 11.5vw, 56px); }
[data-variante='zeitung'] .text--1, [data-variante='zeitung'] .text--2 { columns: 1; border-left: 0; padding-left: 0; font-size: 16px; }
[data-variante='zeitung'] .text--2 { margin-top: 28px; }
[data-variante='kunstbuch'] .titel { font-size: 34px; margin-top: 24px; }
[data-variante='kunstbuch'] .abb--hero .abb__rahmen { aspect-ratio: 4 / 5; }
[data-variante='kunstbuch'] .abb--hero img { object-fit: contain; }
[data-variante='kunstbuch'] .abb--breit .abb__rahmen { aspect-ratio: 4 / 5; }
[data-variante='kunstbuch'] .abb--karte { margin-top: 64px !important; }
.werte { position: static; margin: 0 var(--rand) 24px; max-width: none; }
[data-variante='cover'] .kopf__datum { display: none; }
[data-variante='cover'] .kopf__titel { font-size: 25vw; }
[data-variante='cover'] .beitrag > .abb--hero { grid-row: 1 / 6 !important; margin-top: 0 !important; min-height: 100svh; }
[data-variante='cover'] .beitrag > .kicker { grid-row: 1 !important; }
[data-variante='cover'] .beitrag > .preis { grid-row: 2 !important; justify-self: start; justify-items: start; align-self: start; margin: 18px 0 0; }
[data-variante='cover'] .beitrag > .titel { grid-row: 3 !important; font-size: clamp(46px, 13vw, 64px); }
[data-variante='cover'] .beitrag > .lead { grid-row: 4 !important; font-size: 18px; }
[data-variante='cover'] .beitrag > .byline { grid-row: 5 !important; }
[data-variante='cover'] .titelzeilen { display: none; }
[data-variante='cover'] .abb--hero figcaption { display: none; }
.kopf__leiste { row-gap: 2px; padding-block: 10px; }
.kopf .modi { grid-column: 1 / -1; justify-self: start; gap: 3px; }
.kopf .modi button { padding: 0 9px; }
}
/* Touch: größere Schalter, kein Hover-Unterstrich nötig */
@media (hover: none) {
.modi button { height: 34px; padding: 0 12px; }
.naechster h2 a { background-size: 100% 1px; }
}
/* Reduzierte Bewegung */
:root.reduziert * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
/* Vorschau in der Galerie: nur die Bühne */
.vorschau body { overflow: hidden; }
.vorschau .kolophon { display: none; }
.werte__zahlen { display: flex; flex-wrap: wrap; gap: 4px 14px; }
/* Lenis ist eine Option, standardmäßig aus: viele Rezepte schließen smooth-scroll-lenis aus, der Effekt läuft mit nativem Scroll */
.lenis-schalter { display: inline-flex; align-items: center; gap: 8px; font: inherit; letter-spacing: inherit; text-transform: inherit; color: var(--leise); background: none; border: 0; padding: 2px 0; cursor: pointer; transition: color 150ms linear; }
.lenis-schalter:hover, .lenis-schalter[aria-pressed='true'] { color: var(--tinte); }
.lenis-schalter:focus-visible { outline: 2px solid var(--ziegel); outline-offset: 2px; }
.lenis-schalter__spur { position: relative; width: 22px; height: 12px; border: 1px solid currentColor; border-radius: 999px; flex: none; }
.lenis-schalter__spur::after { content: ''; position: absolute; top: 2px; left: 2px; width: 6px; height: 6px; border-radius: 50%; background: currentColor; transition: translate 150ms var(--kurve); }
.lenis-schalter[aria-pressed='true'] .lenis-schalter__spur { background: var(--tinte); border-color: var(--tinte); }
.lenis-schalter[aria-pressed='true'] .lenis-schalter__spur::after { translate: 10px 0; background: var(--papier); }
.reduziert .lenis-schalter, .reduziert .lenis-schalter__spur::after { transition: none; }
@media (hover: none), (pointer: coarse) { .lenis-schalter { display: none; } } /* Lenis greift nur mit Maus oder Trackpad */
.reduziert .lenis-schalter { display: none; }
.vorschau .werte { display: none; } /* würde in 960 px die Marginalie verdecken */
@media (forced-colors: active) { button, [role=button], [role=tab], [role=switch] { border: 1px solid ButtonText !important; } }
</style>
</head>
<body>
<div class="seite" data-variante="magazin">
<header class="kopf">
<div class="kopf__leiste">
<p class="marke"><span class="marke__name">Das Blatt</span><span class="mono">Journal von Ahorn & Kreide</span></p>
<p class="kopf__datum mono">Köln, Samstag, 31. Oktober 2026</p>
<p class="kopf__ausgabe mono">Ausgabe <b>07</b> · Herbst 2026</p>
<div class="modi mono" role="group" aria-label="Satzspiegel">
<button type="button" data-v="magazin" aria-pressed="true">Magazin</button>
<button type="button" data-v="zeitung" aria-pressed="false">Zeitung</button>
<button type="button" data-v="kunstbuch" aria-pressed="false">Kunstbuch</button>
<button type="button" data-v="cover" aria-pressed="false">Cover</button>
</div>
</div>
<p class="kopf__titel" data-zeilen aria-hidden="true">Das Blatt</p>
<nav class="kopf__rubriken mono" aria-label="Rubriken">
<a href="#beitrag" aria-current="page">Gestaltung</a><a href="#beitrag">Gastronomie</a><a href="#beitrag">Handwerk</a><a href="#beitrag">Stadt</a><a href="#beitrag">Briefe</a>
</nav>
</header>
<main>
<article class="beitrag raster" id="beitrag">
<p class="kicker mono"><span class="kicker__rubrik">Erscheinungsbild</span><span>Gastronomie · S. 12</span></p>
<h1 class="titel" data-zeilen>Ein Kiosk, den man <em>lesen</em> kann.</h1>
<p class="lead" data-zeilen>Seit 1956 steht die Trinkhalle am Rheinufer, ein Würfel unter einem weit auskragenden Flugdach. Als Selin und Paul Okafor sie übernahmen, sollte die Marke nichts erfinden, was der Kiosk nicht längst erzählt. Sie sollte es nur lesbar machen.</p>
<p class="byline mono"><span>Text <b>Mira Lenz</b></span><span>Fotos <b>Ahorn & Kreide</b></span><span>7 Min. Lesezeit</span></p>
<ul class="titelzeilen" aria-label="Weitere Themen dieser Ausgabe">
<li><b>S. 20</b> Zwischen Setzkasten und Siebdruck</li>
<li><b>S. 28</b> Papier, das nachdunkelt</li>
<li><b>S. 34</b> Briefe an das Büro</li>
</ul>
<p class="preis mono" aria-hidden="true"><span>Nr. 07 · Herbst 2026</span><span>9,50 €</span><svg viewBox="0 0 96 30"><g fill="currentColor"><rect x="0" width="2" height="30"/><rect x="4" width="1" height="30"/><rect x="7" width="3" height="30"/><rect x="12" width="1" height="30"/><rect x="15" width="2" height="30"/><rect x="20" width="1" height="30"/><rect x="23" width="3" height="30"/><rect x="28" width="1" height="30"/><rect x="31" width="2" height="30"/><rect x="35" width="1" height="30"/><rect x="38" width="3" height="30"/><rect x="43" width="2" height="30"/><rect x="47" width="1" height="30"/><rect x="50" width="3" height="30"/><rect x="55" width="1" height="30"/><rect x="58" width="2" height="30"/><rect x="62" width="1" height="30"/><rect x="65" width="3" height="30"/><rect x="70" width="1" height="30"/><rect x="73" width="2" height="30"/><rect x="77" width="3" height="30"/><rect x="82" width="1" height="30"/><rect x="85" width="2" height="30"/><rect x="89" width="1" height="30"/><rect x="92" width="2" height="30"/><rect x="95" width="1" height="30"/></g></svg></p>
<figure class="abb abb--hero">
<div class="abb__rahmen"><svg viewBox="0 0 400 500" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Bildmarke der Trinkhalle Rheinblick: eine Linienzeichnung des Kiosks mit weit auskragendem Flugdach über dem Schriftzug in Versalien">
<rect width="400" height="500" fill="#f4f1ea"/>
<g fill="none" stroke="#2b2a27" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round">
<path d="M64 168 L336 150 L338 160 L66 178 Z"/>
<path d="M118 175 V300 M282 164 V300"/>
<path d="M118 300 H282"/>
<path d="M146 196 H254 V252 H146 Z"/>
<path d="M140 258 H260"/>
<path d="M146 210 H254 M146 224 H254 M146 238 H254" stroke-width="1.2"/>
<path d="M200 196 V252" stroke-width="1.2"/>
<path d="M300 300 V214 M292 214 a8 8 0 1 0 16 0 a8 8 0 1 0 -16 0"/>
<path d="M40 300 H360" stroke-width="1.4"/>
<path d="M52 312 H348" stroke-width="1" stroke-dasharray="2 7"/>
<circle cx="214" cy="232" r="0" />
</g>
<g fill="#2b2a27"><rect x="166" y="244" width="10" height="8" rx="1.5"/><rect x="226" y="242" width="8" height="10" rx="1.5"/></g>
<text x="200" y="378" text-anchor="middle" fill="#2b2a27" font-family="'Instrument Serif', Georgia, serif" font-size="52" letter-spacing="9">TRINKHALLE</text>
<text x="200" y="410" text-anchor="middle" fill="#2b2a27" font-family="'Geist Mono', monospace" font-size="12.5" letter-spacing="4.2">RHEINBLICK · SEIT 1956</text>
</svg><svg class="abb__cover" viewBox="0 0 1600 1000" preserveAspectRatio="xMidYMid slice" role="img" aria-label="Illustration: die Trinkhalle am Abend am Rheinufer, das Ausgabefenster leuchtet warm, dahinter Brückenbögen über dem dunklen Fluss">
<defs><linearGradient id="ed-himmel" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#1c2731"/><stop offset=".55" stop-color="#3a4752"/><stop offset="1" stop-color="#6b5a4b"/></linearGradient>
<linearGradient id="ed-fluss" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#26313a"/><stop offset="1" stop-color="#151c22"/></linearGradient>
<radialGradient id="ed-licht" cx=".5" cy=".5" r=".5"><stop offset="0" stop-color="#f2c46b" stop-opacity=".55"/><stop offset="1" stop-color="#f2c46b" stop-opacity="0"/></radialGradient></defs>
<rect width="1600" height="620" fill="url(#ed-himmel)"/><circle cx="898" cy="230" r="1.2" fill="#f4f1ea" opacity="0.3"/><circle cx="448" cy="235" r="1.2" fill="#f4f1ea" opacity="0.3"/><circle cx="1325" cy="239" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="384" cy="36" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="518" cy="144" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="1581" cy="138" r="1.2" fill="#f4f1ea" opacity="0.5"/><circle cx="290" cy="186" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="1157" cy="79" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="1337" cy="354" r="1.6" fill="#f4f1ea" opacity="0.7"/><circle cx="82" cy="273" r="1.2" fill="#f4f1ea" opacity="0.3"/><circle cx="880" cy="127" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="689" cy="171" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="1315" cy="181" r="1.2" fill="#f4f1ea" opacity="0.7"/><circle cx="440" cy="355" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="693" cy="220" r="1.2" fill="#f4f1ea" opacity="0.3"/><circle cx="573" cy="341" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="91" cy="222" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="1570" cy="157" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="342" cy="372" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="1165" cy="261" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="799" cy="131" r="1" fill="#f4f1ea" opacity="0.3"/><circle cx="321" cy="26" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="237" cy="222" r="1.2" fill="#f4f1ea" opacity="0.3"/><circle cx="1127" cy="47" r="1" fill="#f4f1ea" opacity="0.3"/><circle cx="1375" cy="331" r="1.2" fill="#f4f1ea" opacity="0.7"/><circle cx="1584" cy="261" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="54" cy="60" r="1" fill="#f4f1ea" opacity="0.7"/><circle cx="1217" cy="77" r="1.2" fill="#f4f1ea" opacity="0.7"/><circle cx="526" cy="331" r="1" fill="#f4f1ea" opacity="0.3"/><circle cx="742" cy="60" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="608" cy="197" r="1" fill="#f4f1ea" opacity="0.3"/><circle cx="1112" cy="252" r="1.2" fill="#f4f1ea" opacity="0.3"/><circle cx="637" cy="218" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="819" cy="68" r="1" fill="#f4f1ea" opacity="0.3"/><circle cx="1271" cy="207" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="851" cy="247" r="1" fill="#f4f1ea" opacity="0.7"/><circle cx="401" cy="346" r="1.2" fill="#f4f1ea" opacity="0.5"/><circle cx="865" cy="80" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="761" cy="103" r="1" fill="#f4f1ea" opacity="0.7"/><circle cx="305" cy="187" r="1.2" fill="#f4f1ea" opacity="0.5"/><circle cx="529" cy="297" r="1" fill="#f4f1ea" opacity="0.7"/><circle cx="345" cy="22" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="247" cy="299" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="1465" cy="327" r="1.2" fill="#f4f1ea" opacity="0.7"/><circle cx="155" cy="286" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="600" cy="202" r="1" fill="#f4f1ea" opacity="0.3"/><circle cx="1283" cy="20" r="1.6" fill="#f4f1ea" opacity="0.3"/><circle cx="1248" cy="180" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="1163" cy="176" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="1255" cy="336" r="1.2" fill="#f4f1ea" opacity="0.5"/><circle cx="288" cy="148" r="1.6" fill="#f4f1ea" opacity="0.5"/><circle cx="1355" cy="194" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="169" cy="330" r="1" fill="#f4f1ea" opacity="0.7"/><circle cx="1274" cy="110" r="1.2" fill="#f4f1ea" opacity="0.5"/><circle cx="404" cy="314" r="1.2" fill="#f4f1ea" opacity="0.7"/><circle cx="1271" cy="67" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="1322" cy="111" r="1.2" fill="#f4f1ea" opacity="0.7"/><circle cx="761" cy="187" r="1" fill="#f4f1ea" opacity="0.5"/><circle cx="47" cy="329" r="1" fill="#f4f1ea" opacity="0.7"/><circle cx="1545" cy="65" r="1.2" fill="#f4f1ea" opacity="0.3"/>
<circle cx="1320" cy="190" r="34" fill="#efe6cf" opacity=".9"/>
<path d="M0 520 L120 500 L180 512 L260 470 L300 480 L380 430 L420 440 L470 380 L500 395 L560 420 L640 455 L760 470 L900 488 L1040 470 L1180 492 L1320 480 L1600 500 V560 H0 Z" fill="#2a353e"/>
<rect x="0" y="548" width="1600" height="14" fill="#33414c"/><path d="M-40 560 Q45 470 130 560" fill="none" stroke="#33414c" stroke-width="10"/><path d="M130 560 Q215 470 300 560" fill="none" stroke="#33414c" stroke-width="10"/><path d="M300 560 Q385 470 470 560" fill="none" stroke="#33414c" stroke-width="10"/><path d="M470 560 Q555 470 640 560" fill="none" stroke="#33414c" stroke-width="10"/><path d="M640 560 Q725 470 810 560" fill="none" stroke="#33414c" stroke-width="10"/><path d="M810 560 Q895 470 980 560" fill="none" stroke="#33414c" stroke-width="10"/><path d="M980 560 Q1065 470 1150 560" fill="none" stroke="#33414c" stroke-width="10"/>
<rect y="560" width="1600" height="440" fill="url(#ed-fluss)"/><rect x="1392" y="773" width="109" height="3" fill="#f2c46b" opacity="0.18"/><rect x="417" y="798" width="114" height="3" fill="#f2c46b" opacity="0.4"/><rect x="842" y="684" width="126" height="3" fill="#f2c46b" opacity="0.4"/><rect x="874" y="899" width="103" height="3" fill="#f2c46b" opacity="0.18"/><rect x="586" y="882" width="111" height="3" fill="#f2c46b" opacity="0.18"/><rect x="1201" y="793" width="41" height="3" fill="#f2c46b" opacity="0.28"/><rect x="1252" y="799" width="170" height="3" fill="#f2c46b" opacity="0.18"/><rect x="927" y="856" width="113" height="3" fill="#f2c46b" opacity="0.28"/><rect x="1004" y="722" width="99" height="3" fill="#f2c46b" opacity="0.28"/><rect x="611" y="662" width="60" height="3" fill="#f2c46b" opacity="0.18"/><rect x="1027" y="783" width="172" height="3" fill="#f2c46b" opacity="0.4"/><rect x="1407" y="881" width="127" height="3" fill="#f2c46b" opacity="0.18"/><rect x="1459" y="740" width="57" height="3" fill="#f2c46b" opacity="0.28"/><rect x="495" y="865" width="110" height="3" fill="#f2c46b" opacity="0.18"/><rect x="808" y="863" width="122" height="3" fill="#f2c46b" opacity="0.4"/><rect x="1223" y="741" width="122" height="3" fill="#f2c46b" opacity="0.18"/><rect x="206" y="757" width="111" height="3" fill="#f2c46b" opacity="0.4"/><rect x="1340" y="761" width="71" height="3" fill="#f2c46b" opacity="0.28"/><rect x="443" y="788" width="157" height="3" fill="#f2c46b" opacity="0.18"/><rect x="167" y="822" width="61" height="3" fill="#f2c46b" opacity="0.28"/><rect x="1462" y="807" width="44" height="3" fill="#f2c46b" opacity="0.28"/><rect x="671" y="804" width="79" height="3" fill="#f2c46b" opacity="0.4"/><rect x="920" y="679" width="115" height="3" fill="#f2c46b" opacity="0.4"/><rect x="472" y="867" width="114" height="3" fill="#f2c46b" opacity="0.18"/><rect x="592" y="835" width="80" height="3" fill="#f2c46b" opacity="0.28"/><rect x="1253" y="644" width="133" height="3" fill="#f2c46b" opacity="0.18"/><rect x="1011" y="726" width="133" height="3" fill="#f2c46b" opacity="0.28"/><rect x="674" y="689" width="152" height="3" fill="#f2c46b" opacity="0.18"/><rect x="948" y="746" width="69" height="3" fill="#f2c46b" opacity="0.18"/><rect x="207" y="668" width="83" height="3" fill="#f2c46b" opacity="0.4"/><rect x="1466" y="716" width="50" height="3" fill="#f2c46b" opacity="0.4"/><rect x="1084" y="767" width="122" height="3" fill="#f2c46b" opacity="0.18"/><rect x="330" y="789" width="144" height="3" fill="#f2c46b" opacity="0.4"/><rect x="490" y="884" width="91" height="3" fill="#f2c46b" opacity="0.18"/>
<path d="M0 860 L1600 820 V1000 H0 Z" fill="#11171c"/>
<g transform="translate(980 560)">
<ellipse cx="190" cy="150" rx="330" ry="170" fill="url(#ed-licht)"/>
<path d="M-40 70 L430 40 L432 58 L-38 88 Z" fill="#0d1216"/>
<rect x="40" y="80" width="300" height="230" fill="#161d22"/>
<rect x="88" y="120" width="204" height="104" fill="#f2c46b"/>
<path d="M88 150 H292 M88 180 H292 M190 120 V224" stroke="#d29b3e" stroke-width="3"/>
<rect x="76" y="226" width="228" height="12" fill="#0d1216"/>
<rect x="120" y="186" width="18" height="38" rx="3" fill="#a3402a"/><rect x="230" y="192" width="14" height="32" rx="3" fill="#2b8a8f"/>
<path d="M370 310 V150" stroke="#0d1216" stroke-width="6"/><circle cx="370" cy="140" r="20" fill="#a3402a"/>
<rect x="-20" y="308" width="440" height="6" fill="#0d1216"/>
</g>
<g fill="#0d1216"><rect x="1460" y="800" width="10" height="60"/><circle cx="1465" cy="790" r="18"/><rect x="900" y="830" width="120" height="8"/><rect x="910" y="838" width="6" height="30"/><rect x="1004" y="838" width="6" height="30"/></g>
</svg></div>
<figcaption class="mono"><b><span>Abb. </span>1</b><span class="nur-heft">Bild- und Wortmarke, Grafit auf Naturkarton</span><span class="nur-cover">Titelbild: die Trinkhalle am Abend</span></figcaption>
</figure>
<div class="text text--1">
<p class="initial">Am Anfang stand kein Logo, sondern ein Querschnitt. Ein Würfel aus Beton, ein Ausgabefenster mit vier Flügeln und ein Dach, das zwei Meter über die Wand hinausragt. Zwei Tage lang haben wir die Trinkhalle gezeichnet, bevor wir den ersten Buchstaben gesetzt haben. Aus diesen Skizzen ist die Bildmarke entstanden: eine einzige Linie, die Flugdach, Fenster und Theke nachzieht.<sup>1</sup></p>
<p>Die Schrift ist schmal und weit gesperrt, wie die Leuchtbuchstaben, die früher auf dem Dach standen. Sie trägt auf der Markise genauso wie auf dem Kassenbon, und sie braucht keine Farbe, um zu wirken. Auf Papier steht sie in Grafit, auf Glas in Weiß, auf der Preistafel in der Handschrift von Paul.</p>
</div>
<aside class="marginalie" aria-label="Anmerkung">
<b>1</b>
<p>Die Trinkhalle wurde 1956 für die Fähre gebaut, die damals hier anlegte. Das Flugdach ist original und steht seit 2011 unter Denkmalschutz.</p>
</aside>
<blockquote class="zitat">
<p data-zeilen>»Wir wollten kein Logo, das man sieht. Wir wollten eines, das man wiedererkennt.«</p>
<footer class="mono"><b>Selin Okafor</b>, Inhaberin Trinkhalle Rheinblick</footer>
</blockquote>
<figure class="abb abb--breit">
<div class="abb__rahmen"><svg viewBox="0 0 1260 540" preserveAspectRatio="xMidYMid slice" role="img" aria-label="Aufgeschlagenes Hausmagazin von Ahorn und Kreide: links ein Inhaltsverzeichnis mit großen Seitenzahlen und türkisen Linien, rechts eine Seite im Zweispaltensatz">
<rect width="1260" height="540" fill="#e4e3df"/>
<g transform="translate(0 6)"><path d="M190 70 L630 82 L1070 70 L1076 486 L630 498 L184 486 Z" fill="#000" opacity=".08" transform="translate(8 14)"/>
<path d="M190 70 L630 82 L630 498 L184 486 Z" fill="#f7f4ec"/><path d="M630 82 L1070 70 L1076 486 L630 498 Z" fill="#fbf9f3"/>
<path d="M600 80 L630 82 L630 498 L600 496 Z" fill="#000" opacity=".06"/><path d="M630 82 L662 81 L662 497 L630 498 Z" fill="#000" opacity=".04"/></g>
<text x="236" y="168" font-family="'Instrument Serif', Georgia, serif" font-size="96" fill="#1b1a17" letter-spacing="-3">Inhalt</text>
<text x="520" y="132" font-family="'Geist Mono', monospace" font-size="12" letter-spacing="2.5" fill="#2b8a8f">AUSGABE 04</text>
<text x="236" y="262" font-family="'Instrument Serif', Georgia, serif" font-size="40" fill="#1b1a17">04</text><text x="300" y="256" font-family="'Geist Mono', monospace" font-size="12" letter-spacing="2.5" fill="#1b1a17">RUBRIKEN STATT KATEGORIEN</text><line x1="236" y1="278" x2="600" y2="278" stroke="#2b8a8f" stroke-width="1.5"/><text x="236" y="320" font-family="'Instrument Serif', Georgia, serif" font-size="40" fill="#1b1a17">12</text><text x="300" y="314" font-family="'Geist Mono', monospace" font-size="12" letter-spacing="2.5" fill="#1b1a17">EIN KIOSK AM WASSER</text><line x1="236" y1="336" x2="600" y2="336" stroke="#2b8a8f" stroke-width="1.5"/><text x="236" y="378" font-family="'Instrument Serif', Georgia, serif" font-size="40" fill="#1b1a17">20</text><text x="300" y="372" font-family="'Geist Mono', monospace" font-size="12" letter-spacing="2.5" fill="#1b1a17">PAPIER, DAS NACHDUNKELT</text><line x1="236" y1="394" x2="600" y2="394" stroke="#2b8a8f" stroke-width="1.5"/><text x="236" y="436" font-family="'Instrument Serif', Georgia, serif" font-size="40" fill="#1b1a17">28</text><text x="300" y="430" font-family="'Geist Mono', monospace" font-size="12" letter-spacing="2.5" fill="#1b1a17">BRIEFE</text><line x1="236" y1="452" x2="600" y2="452" stroke="#2b8a8f" stroke-width="1.5"/>
<text x="742" y="150" font-family="'Instrument Serif', Georgia, serif" font-style="italic" font-size="44" fill="#1b1a17">Rubriken statt Kategorien</text>
<line x1="956" y1="196" x2="956" y2="420" stroke="#1b1a17" stroke-opacity=".25"/>
<rect x="742" y="196" width="190" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="196" width="200" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="218" width="170" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="218" width="160" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="240" width="150" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="240" width="180" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="262" width="170" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="262" width="150" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="284" width="170" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="284" width="160" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="306" width="200" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="306" width="200" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="328" width="170" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="328" width="180" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="350" width="200" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="350" width="200" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="372" width="210" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="372" width="180" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="394" width="170" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="394" width="200" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="742" y="416" width="190" height="5" rx="1" fill="#1b1a17" opacity=".55"/><rect x="972" y="416" width="150" height="5" rx="1" fill="#1b1a17" opacity=".55"/>
<text x="742" y="458" font-family="'Geist Mono', monospace" font-size="11" letter-spacing="2.5" fill="#1b1a17" opacity=".6">S. 05</text>
</svg></div>
<figcaption class="mono"><b><span>Abb. </span>2</b><span>Vorbild für die Karte: unser Hausmagazin, Ausgabe 04</span></figcaption>
</figure>
<div class="text text--2">
<h2 class="zwischen">Ein Raster aus dem Feuilleton</h2>
<p>Für die Preistafel haben wir das Raster unseres Hausmagazins übernommen: zwei Spalten, Haarlinien, Rubriken statt Kategorien. Kaffee steht unter »Morgens«, Eis unter »Nachmittags«, Kölsch unter »Spät«. Die Preise stehen in Mediävalziffern, damit sie im Satz bleiben und nicht schreien.</p>
<p>Gedruckt wird auf ungestrichenem Naturkarton, der in der Sonne nachdunkelt. Nach einem Sommer sieht die Tafel aus, als hätte sie schon immer im Fenster gehangen. Genau das war das Ziel.</p>
</div>
<figure class="abb abb--karte">
<div class="karte" role="img" aria-label="Preistafel der Trinkhalle Rheinblick im Zeitungsraster mit den Rubriken Morgens, Nachmittags und Spät">
<div class="karte__kopf"><span class="karte__name">Trinkhalle</span><span class="mono">Tafel · Herbst</span></div>
<div class="karte__spalten">
<div><p class="karte__rubrik">Morgens</p><p class="karte__posten">Filterkaffee <span>2,40</span></p><p class="karte__posten">Milchkaffee <span>3,20</span></p><p class="karte__posten">Mettbrötchen <span>3,50</span></p></div>
<div><p class="karte__rubrik">Nachmittags</p><p class="karte__posten">Eis, zwei Kugeln <span>3,60</span></p><p class="karte__posten">Waffel <span>3,20</span></p><p class="karte__posten">Limonade <span>2,90</span></p></div>
<div><p class="karte__rubrik">Spät</p><p class="karte__posten">Kölsch, 0,33 l <span>2,80</span></p><p class="karte__posten">Apfelschorle <span>2,60</span></p></div>
</div>
</div>
<figcaption class="mono"><b><span>Abb. </span>3</b><span>Die Preistafel: Rubriken statt Kategorien</span></figcaption>
</figure>
</article>
<aside class="naechster raster" aria-label="Nächster Beitrag">
<p class="mono">Nächster Beitrag · S. 20</p>
<h2><a href="#beitrag">Zwischen Setzkasten und Siebdruck: <em>eine Druckwerkstatt</em> zieht um</a></h2>
<figure class="abb"><div class="abb__rahmen"><svg viewBox="0 0 600 400" preserveAspectRatio="xMidYMid slice" role="img" aria-label="Holzlettern in einer Druckwerkstatt, spiegelverkehrt mit roter Farbe eingefärbt, davor eine Farbwalze">
<rect width="600" height="400" fill="#232e32"/>
<rect x="0" y="260" width="600" height="140" fill="#1a2326"/>
<rect x="70" y="120" width="110" height="140" rx="4" fill="#c9a77c"/><rect x="70" y="120" width="110" height="10" fill="#000" opacity=".12"/><text x="125.0" y="223.6" text-anchor="middle" font-family="'Instrument Serif', Georgia, serif" font-size="101" fill="#a3402a" transform="scale(-1 1) translate(-250 0)">A</text><rect x="192" y="150" width="90" height="110" rx="4" fill="#b88d5c"/><rect x="192" y="150" width="90" height="10" fill="#000" opacity=".12"/><text x="237.0" y="231.4" text-anchor="middle" font-family="'Instrument Serif', Georgia, serif" font-size="79" fill="#a3402a" transform="scale(-1 1) translate(-474 0)">&</text><rect x="294" y="104" width="120" height="156" rx="4" fill="#d4b48a"/><rect x="294" y="104" width="120" height="10" fill="#000" opacity=".12"/><text x="354.0" y="219.44" text-anchor="middle" font-family="'Instrument Serif', Georgia, serif" font-size="112" fill="#a3402a" transform="scale(-1 1) translate(-708 0)">R</text><rect x="426" y="168" width="80" height="92" rx="4" fill="#c19a6b"/><rect x="426" y="168" width="80" height="10" fill="#000" opacity=".12"/><text x="466.0" y="236.07999999999998" text-anchor="middle" font-family="'Instrument Serif', Georgia, serif" font-size="66" fill="#a3402a" transform="scale(-1 1) translate(-932 0)">e</text>
<g transform="translate(120 300) rotate(-6)"><rect x="0" y="0" width="300" height="34" rx="17" fill="#a3402a"/><rect x="0" y="0" width="300" height="10" rx="5" fill="#fff" opacity=".18"/><path d="M300 17 H360 V60" fill="none" stroke="#d9d4c7" stroke-width="7" stroke-linecap="round"/></g>
</svg></div></figure>
</aside>
</main>
<footer class="kolophon mono"><span>Das Blatt erscheint viermal im Jahr</span><span>Ahorn & Kreide · Büro für Gestaltung · Köln</span></footer>
<div class="werte mono">
<p class="werte__zahlen" data-werte aria-live="polite"></p>
<button type="button" class="lenis-schalter" data-lenis aria-pressed="false"><span class="lenis-schalter__spur" aria-hidden="true"></span>Weiches Scrollen (Lenis, nur Eigenprojekt)</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/SplitText.min.js"></script>
<!-- Lenis nur bei Bedarf: wird erst geladen, wenn „Weiches Scrollen“ eingeschaltet ist -->
<template id="lenis-quelle"><script src="https://cdn.jsdelivr.net/npm/lenis@1.3.26/dist/lenis.min.js"></script></template>
<script>
(() => {
gsap.registerPlugin(ScrollTrigger, SplitText);
const html = document.documentElement;
const reduziert = () => html.classList.contains('reduziert');
const seite = document.querySelector('.seite');
const werte = document.querySelector('[data-werte]');
const sichtbar = el => el.getClientRects().length > 0;
const alle = s => [...document.querySelectorAll(s)].filter(sichtbar);
// Eine Kurve für alles Sichtbare: power3.out = cubic-bezier(0.25, 1, 0.5, 1)
const W = {
kurve: 'power3.out',
titel: { dauer: 1.0, versatz: 0.1 }, // Zeilen der Headline
lead: { dauer: 0.9, versatz: 0.08, verzoegerung: 0.3 },
zitat: { dauer: 1.1, versatz: 0.12 },
bild: { dauer: 1.2, verzoegerung: 0.15 }, // Bildrahmen öffnet von unten
meta: { dauer: 0.9, versatz: 0.06, weg: 12 },
block: { dauer: 1.0, weg: 24 }, // Fließtext beim Scrollen
parallaxe: 4, // yPercent ±4 = 8 % der Bildhöhe
};
const RASTER = {
magazin: 'Titel Sp. 1–8 · Bild 9–12 · Text 3–8',
zeitung: 'Titel Sp. 1–9 · Bild 1–7 · Text 8–12 in 2 Spalten',
kunstbuch: 'Tafel Sp. 4–12 · Titel 1–3 · kaum Text',
cover: 'Cover 100svh · Titelkopf 19,5vw · Titel Sp. 1–8 über dem Bild',
};
const REIHE = ['magazin', 'zeitung', 'kunstbuch', 'cover'];
// Variante aus der URL (?v=), sonst die erste
const vUrl = new URLSearchParams(location.search).get('v');
let variante = REIHE.includes(vUrl) ? vUrl : REIHE[0], teilungen = [], lenis = null;
seite.dataset.variante = variante;
document.querySelectorAll('[data-v]').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.v === variante)));
function urlSchreiben() { const u = new URL(location.href); u.searchParams.set('v', variante); history.replaceState(history.state, '', u); }
// Höhe des Kopfs für das Cover (Titelkopf liegt über dem Bild)
const kopf = document.querySelector('.kopf');
new ResizeObserver(() => seite.style.setProperty('--kopf-h', kopf.offsetHeight + 'px')).observe(kopf);
function zeigeWerte() {
werte.innerHTML = reduziert()
? `<span>Raster <b>12 Sp.</b></span><span><b>${RASTER[variante]}</b></span><span>Reduziert: <b>keine Reveals, keine Parallaxe</b></span>`
: `<span>Raster <b>12 Sp.</b></span><span><b>${RASTER[variante]}</b></span><span>Zeilen <b>power3.out 1000 ms / 100 ms</b></span><span>Parallaxe <b>8 %</b></span><span>Lead <b>1,4×</b></span><span>Scroll <b>${lenis ? 'Lenis lerp 0.1' : 'nativ'}</b></span>`;
}
// Zeilen aus ihrer Maske heben. Der Tween kommt aus onSplit zurück,
// damit autoSplit ihn bei neuem Umbruch sauber neu aufsetzt.
function zeilen(el, w, extra = {}) {
const t = SplitText.create(el, {
type: 'lines', mask: 'lines', autoSplit: true, linesClass: 'zeile',
onSplit(self) {
gsap.set(el, { visibility: 'visible' });
return gsap.from(self.lines, { yPercent: 105, duration: w.dauer, stagger: w.versatz, ease: W.kurve, delay: w.verzoegerung || 0, ...extra });
},
});
teilungen.push(t);
return t;
}
const bewegt = () => ['.beitrag > *', '.kopf__rubriken', '.kopf__titel', '.kicker', '.byline', '.abb figcaption', '.text', '.marginalie', '.abb--karte', '.naechster', '.abb__rahmen', '.abb__rahmen > img', '.abb__rahmen > svg', '.beitrag', '.zitat footer', '.titelzeilen li', '.preis'];
function aufraeumen() {
teilungen.forEach(t => t.revert());
teilungen = [];
ScrollTrigger.getAll().forEach(t => t.kill());
const els = document.querySelectorAll(bewegt().join(','));
gsap.killTweensOf(els);
gsap.set(els, { clearProps: 'all' });
document.querySelectorAll('[data-zeilen]').forEach(el => gsap.set(el, { clearProps: 'visibility' }));
}
function aufbauen() {
aufraeumen();
zeigeWerte();
if (reduziert()) { document.querySelectorAll('[data-zeilen]').forEach(el => (el.style.visibility = 'visible')); return; }
// 1) Ankunft im ersten Bildschirm
alle('.kopf__titel').forEach(el => zeilen(el, { dauer: 1.0, versatz: 0 }));
zeilen(document.querySelector('.titel'), W.titel, { delay: alle('.kopf__titel').length ? 0.2 : 0.05 });
alle('.lead').forEach(el => zeilen(el, W.lead));
gsap.from(alle('.kicker, .byline, .abb--hero figcaption, .kopf__rubriken, .titelzeilen li, .preis'), { opacity: 0, y: W.meta.weg, duration: W.meta.dauer, stagger: W.meta.versatz, ease: W.kurve, delay: 0.25 });
const held = document.querySelector('.abb--hero .abb__rahmen');
gsap.fromTo(held, { clipPath: 'inset(100% 0% 0% 0%)' }, { clipPath: 'inset(0% 0% 0% 0%)', duration: W.bild.dauer, ease: W.kurve, delay: W.bild.verzoegerung });
// 2) Leichte Bildparallaxe: Bild 110 % groß, wandert yPercent -4 → 4
alle('.abb--hero, .abb--breit').forEach(fig => {
const img = [...fig.querySelectorAll('.abb__rahmen > img, .abb__rahmen > svg')].find(sichtbar);
gsap.set(img, { scale: 1.1 });
gsap.fromTo(img, { yPercent: -W.parallaxe }, { yPercent: W.parallaxe, ease: 'none', scrollTrigger: { trigger: fig, start: 'top bottom', end: 'bottom top', scrub: true } });
});
// 3) Beim Scrollen: Pull-Quote zeilenweise, Textblöcke weich einblenden (einmal)
alle('.zitat p').forEach(el => zeilen(el, W.zitat, { scrollTrigger: { trigger: el, start: 'top 82%', once: true } }));
alle('.text, .marginalie, .abb--karte, .abb--breit figcaption, .zitat footer, .naechster').forEach(el => {
gsap.from(el, { opacity: 0, y: W.block.weg, duration: W.block.dauer, ease: W.kurve, scrollTrigger: { trigger: el, start: 'top 88%', once: true } });
});
ScrollTrigger.refresh();
}
function setzeKnopf() {
document.querySelectorAll('[data-v]').forEach(b => b.setAttribute('aria-pressed', String(b.dataset.v === variante)));
}
function nachOben() { lenis ? lenis.scrollTo(0, { immediate: true, force: true }) : scrollTo(0, 0); }
// Variantenwechsel: Headline-Zeilen steigen aus der Maske, Rest blendet aus, neuer Satzspiegel baut sich auf
let wechselLaeuft = null;
function wechsel(neu) {
if (wechselLaeuft) return wechselLaeuft;
const fertig = () => { variante = neu; seite.dataset.variante = neu; setzeKnopf(); urlSchreiben(); nachOben(); aufbauen(); wechselLaeuft = null; };
if (reduziert()) { fertig(); return Promise.resolve(); }
const zeilenAlt = document.querySelectorAll('.titel .zeile, .kopf__titel .zeile');
wechselLaeuft = new Promise(ok => {
const tl = gsap.timeline({ onComplete: () => { fertig(); ok(); } });
tl.to(zeilenAlt, { yPercent: -105, duration: 0.5, ease: 'power3.in', stagger: 0.04 }, 0)
.to(alle('.beitrag > :not(.titel), .kopf__rubriken, .naechster'), { opacity: 0, duration: 0.35, ease: 'power3.in' }, 0.05);
});
return wechselLaeuft;
}
document.querySelector('.modi').addEventListener('click', e => {
const b = e.target.closest('[data-v]');
if (!b || b.dataset.v === variante) return;
pause(); gsap.globalTimeline.resume();
wechsel(b.dataset.v);
});
// Weiches Scrollen (Lenis): standardmäßig aus, der Effekt läuft mit nativem Scroll (ScrollTrigger liest scrollY).
// Nur auf Wunsch im Pult und nur mit Maus/Trackpad, nicht in Vorschau, Touch oder reduzierter Bewegung.
const lenisKnopf = document.querySelector('[data-lenis]');
let lenisWunsch = new URLSearchParams(location.search).has('lenis'), lenisTakt = null;
const lenisMoeglich = () => !reduziert() && !html.classList.contains('vorschau') && matchMedia('(hover: hover) and (pointer: fine)').matches;
function lenisLaden() {
if (typeof Lenis !== 'undefined') return Promise.resolve();
return new Promise((ok, fehler) => {
const vorlage = document.getElementById('lenis-quelle').content.querySelector('script');
const s = document.createElement('script');
s.src = vorlage.getAttribute('src'); s.onload = ok; s.onerror = fehler;
document.head.append(s);
});
}
async function lenisSetzen(an) {
lenisWunsch = an;
lenisKnopf.setAttribute('aria-pressed', String(an));
const u = new URL(location.href); an ? u.searchParams.set('lenis', '1') : u.searchParams.delete('lenis');
history.replaceState(history.state, '', u);
if (an && !lenis && lenisMoeglich()) {
try { await lenisLaden(); } catch (e) { lenisKnopf.setAttribute('aria-pressed', 'false'); return; }
if (!lenisWunsch || lenis) return;
lenis = new Lenis({ lerp: 0.1, wheelMultiplier: 1, autoRaf: false });
lenis.on('scroll', ScrollTrigger.update);
lenisTakt = t => lenis.raf(t * 1000);
gsap.ticker.add(lenisTakt);
gsap.ticker.lagSmoothing(0);
} else if (!an && lenis) {
gsap.ticker.remove(lenisTakt); lenis.destroy(); lenis = null; lenisTakt = null;
gsap.ticker.lagSmoothing(500, 33); // GSAP-Standard
}
zeigeWerte();
}
lenisKnopf.addEventListener('click', () => lenisSetzen(lenisKnopf.getAttribute('aria-pressed') !== 'true'));
// Vorführung: die gewählte Variante baut sich auf, scrollt ein Stück (Parallaxe, Pull-Quote) und beginnt von vorn
let uhr = null, lauf = 0, scrollTween = null;
const warte = ms => new Promise(ok => { uhr = setTimeout(ok, ms); });
function scrolleZu(y, dauer) {
if (reduziert()) { scrollTo(0, y); return Promise.resolve(); }
if (lenis) return new Promise(ok => lenis.scrollTo(y, { duration: dauer, easing: t => 1 - Math.pow(1 - t, 3), onComplete: ok }));
const o = { y: scrollY };
return new Promise(ok => { scrollTween = gsap.to(o, { y, duration: dauer, ease: 'power3.inOut', onUpdate: () => scrollTo(0, o.y), onComplete: ok }); });
}
async function schleife(id) {
while (id === lauf) {
nachOben(); aufbauen();
await warte(3000); if (id !== lauf) return;
await scrolleZu(Math.round(innerHeight * (variante === 'cover' ? 0.8 : 0.55)), 1.8); if (id !== lauf) return;
await warte(1600); if (id !== lauf) return;
}
}
function vorfuehren() {
pause();
gsap.globalTimeline.resume();
const id = ++lauf;
bereit.then(() => schleife(id));
}
function pause() { lauf++; clearTimeout(uhr); uhr = null; if (scrollTween) scrollTween.kill(); }
function neustart() { pause(); gsap.globalTimeline.resume(); bereit.then(() => { nachOben(); aufbauen(); }); }
const bereit = document.fonts.ready.then(() => { // erst nach den Schriften teilen, sonst falsche Umbrüche
if (lenisWunsch) lenisSetzen(true);
if (lauf === 0) aufbauen();
});
})();
</script>
</body>
</html>