Kolophon: Schriften, Bildnachweis, Stand, Gewicht
Footer eines Studios mit der ruhigen Zeile „Stand 3. November 2026 · Kolophon“; dahinter eine Kolophon-Seite mit Schriftmustern, benannten Farben, Bildnachweis je Bild und gemessenem Seitengewicht ohne CO2-Wert.
Jede Studio-, Architektur- oder Kulturseite mit Kolophon-Seite: nur der Stand und ein Link, unauffällig in der Unterzeile.
Am Ende der Seite steht eine ruhige Zeile „Kolophon“ mit Stand der Seite, daneben ein Link auf eine eigene Seite. Dort stehen wie im Buch die Schriften mit ihren Gestalterinnen und Gestaltern, die Farben, Bildnachweise je Foto, Werkzeuge und Hosting, Mitwirkende und das gemessene Seitengewicht mit Datum. Keine Bewegung, gesetzt als Definitionsliste.
Der Kolophon zeigt Sorgfalt, ohne zu werben, und löst nebenbei eine Pflicht: den Bildnachweis für Fotos mit Nutzungsrecht. Für Studios und Kulturhäuser ist er ein Zeichen von Handwerk, wie die Impressumsseite eines guten Buchs.
Wann einsetzen
Kreativstudios, Freelancer, Fotografie, Architektur, Kultur, Manufakturen. Überall, wo Bildnachweise nötig sind und die Gestaltung Teil des Angebots ist.
Wann nicht
Pflegedienst, Bestattung, Kfz: Dort genügt eine Zeile Bildnachweis im Impressum. Nie als Ersatz für Impressum oder Datenschutz. Keine CO2-Angaben pro Seitenaufruf und keine Badges wie „sauberer als x % aller Websites“: Seit 27.09.2026 sind Umweltaussagen ohne Nachweis riskant, vom Kunden prüfen lassen. Generik-Gefahr: Eine Zeile „Made with Framer“ ist kein Kolophon.
Varianten
- zeile: nur „Stand: November 2026 · Kolophon“ im Footer, die Seite dahinter
- seite: eigene Seite /kolophon mit dl (Schrift, Farbe, Bild, Technik, Dank) und Bildnachweis je Foto
- gewicht: Seitengewicht in KiB und Zahl der Anfragen, beim Bau gemessen und datiert, ohne Umweltbezug
Umsetzung
- Footer: eine Zeile mit time datetime für den Stand und Link „Kolophon“ (in mega-footer-sitemap bzw. studio-visitenkarte-footer).
- Seite /kolophon: h1, dann dl-Gruppen Schrift, Farbe, Bild, Technik, Dank; Schriftmuster in der jeweiligen Schrift gesetzt.
- Bildnachweis je Foto aus derselben Datenquelle wie die Bilder (z. B. bilder.json), damit nichts fehlt; im Impressum darauf verweisen.
- Seitengewicht beim Bau messen (Summe der Übertragungsgröße der Startseite, kalt geladen) und mit Datum eintragen; live gemessene transferSize ist bei Cache und Fremdquellen 0.
- Farben als Liste mit Namen und Wert, Kontrast der Musterflächen zum Text prüfen.
- Kein JS nötig.
Robust umsetzen
Telefon. dl einspaltig, Schriftmuster brechen um.
Ohne Bewegung. Keine Bewegung.
Barrierefrei. Reiner Text, echte dl, Kontrast 4,5:1 auch für die Footer-Zeile (nicht Grau auf Grau). 320 px und 200 % Zoom ohne Abschneiden. Farbmuster nie nur über Farbe benannt.
Code
<!DOCTYPE html>
<!--
Kolophon: Schriften, Bildnachweis, Stand, Gewicht
Fundus · Footer · https://cecodesign.de/lab/fundus/footer/kolophon-footer/
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>Kolophon: Schriften, Bildnachweis, Stand, Gewicht · 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: 'TikTok Sans'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/tiktok-sans:vf@latest/latin-wdth-normal.woff2') format('woff2-variations'); font-weight: 300 900; font-stretch: 75% 150%; font-display: swap; }
@font-face { font-family: 'DM Mono'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/dm-mono@latest/latin-400-normal.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'DM Mono'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/dm-mono@latest/latin-500-normal.woff2') format('woff2'); font-weight: 500; font-display: swap; }
/* Rezept kreativstudio-buehne: Schwarz und Weiß, eine Signalfarbe, TikTok Sans in zwei Breiten, DM Mono für Labels */
:root {
--grund: #0b0b0b; --hell: #f2f2f2; --text: #ffffff; --leise: #9a9a9a; --linie: #323232; --signal: #ff5a1f; --meta-hell: #6B6B6B;
--kurve: cubic-bezier(0.16, 1, 0.3, 1); /* nur Hover-Farbe und Vorführ-Scroll; der Kolophon selbst bewegt sich nicht */
--t-ui: 200ms;
--rand: clamp(16px, 2.6vw, 40px);
}
* { box-sizing: border-box; margin: 0; }
html { background: var(--grund); color: var(--text); font-family: 'TikTok Sans', system-ui, sans-serif; font-size: 100%; -webkit-font-smoothing: antialiased; }
:root:has(:focus-visible) { scroll-behavior: auto; }
body { min-height: 100svh; overflow-x: clip; font-size: 1.125rem; line-height: 1.45; display: flex; flex-direction: column; }
main { flex: 1; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .18em; transition: color var(--t-ui) var(--kurve), text-decoration-color var(--t-ui) var(--kurve); }
a:hover { color: var(--signal); }
:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }
.mono { font-family: 'DM Mono', ui-monospace, monospace; font-weight: 500; font-size: .75rem; letter-spacing: .04em; text-transform: uppercase; line-height: 1.5; }
.leise { color: var(--leise); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
[hidden] { display: none !important; }
/* ── Kopf ──────────────────────────────────────────────────────────── */
.kopf { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 18px var(--rand); border-bottom: 1px solid var(--linie); }
.kopf .marke { font-weight: 800; font-stretch: 75%; font-size: 1.375rem; letter-spacing: -.01em; text-decoration: none; text-transform: uppercase; }
.kopf ul { list-style: none; padding: 0; display: flex; gap: 4px 24px; flex-wrap: wrap; }
.kopf ul a { text-decoration: none; font-size: 1rem; }
.kopf ul a[aria-current] { text-decoration: underline; }
/* ── Variante zeile: Seitenende eines Studios ──────────────────────── */
.ende { padding: clamp(64px, 10vw, 160px) var(--rand) clamp(48px, 7vw, 112px); display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 32px; align-items: end; }
.ende h2 { font-weight: 600; font-size: clamp(2rem, 4.5vw, 4.5rem); line-height: .98; letter-spacing: -.02em; text-wrap: balance; }
.ende .post { font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem); font-weight: 500; text-decoration: none; border-bottom: 2px solid var(--signal); padding-bottom: 4px; justify-self: start; }
/* ── Footer (alle Varianten) ───────────────────────────────────────── */
.fuss { border-top: 1px solid var(--linie); padding: clamp(32px, 4vw, 56px) var(--rand) 20px; }
.fuss.mit-pult { padding-bottom: 72px; } /* nur Demo: Platz unter dem Pult, damit die Kolophon-Zeile frei bleibt */
.spalten { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }
.spalten h3 { margin-bottom: 10px; color: var(--leise); }
.spalten ul { list-style: none; padding: 0; display: grid; gap: 6px; font-size: 1rem; }
.spalten ul a { text-decoration: none; }
.spalten address { font-style: normal; font-size: 1rem; }
.wortmarke { font-weight: 800; font-stretch: 75%; text-transform: uppercase; font-size: clamp(3.5rem, 19.4vw, 19rem); line-height: .8; letter-spacing: -.035em; margin: clamp(32px, 5vw, 72px) 0 18px; white-space: nowrap; }
.wortmarke span { display: inline-block; } /* Breite per ResizeObserver eingepasst, auch bei erhöhten Textabständen */
/* Die Kolophon-Zeile: ruhig, aber 4,5 : 1 (nicht Grau auf Grau) */
.unterzeile { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 24px; padding-top: 14px; border-top: 1px solid var(--linie); }
.unterzeile .rechtliches { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.unterzeile a { text-decoration: none; }
.unterzeile a:hover { text-decoration: underline; }
.kolophon-zeile { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.kolophon-zeile .trenn { color: var(--leise); }
.kolophon-zeile a[aria-current] { text-decoration: underline; }
.kolophon-zeile .gewicht-kurz { font-variant-numeric: tabular-nums; }
.kolophon-zeile.gezeigt a { color: var(--signal); text-decoration: underline; text-decoration-thickness: 2px; }
/* ── Kolophon-Seite ────────────────────────────────────────────────── */
.kolophon { padding: clamp(40px, 6vw, 96px) var(--rand) clamp(48px, 7vw, 112px); }
.kolophon h1 { font-weight: 800; font-stretch: 75%; font-size: clamp(3.5rem, 13vw, 13rem); line-height: .86; letter-spacing: -.03em; text-transform: uppercase; }
.kolophon .einleitung { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); gap: 24px; margin-top: clamp(24px, 3vw, 40px); padding-bottom: clamp(32px, 4vw, 56px); border-bottom: 1px solid var(--linie); }
.kolophon .einleitung p:last-child { font-size: clamp(1.25rem, 1rem + .9vw, 1.75rem); line-height: 1.3; max-width: 34ch; }
.gruppe { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); gap: 16px 24px; padding: clamp(28px, 3.5vw, 48px) 0; border-bottom: 1px solid var(--linie); }
.gruppe > h2 { font-family: 'DM Mono', ui-monospace, monospace; font-weight: 500; font-size: .75rem; letter-spacing: .04em; text-transform: uppercase; color: var(--leise); padding-top: 6px; }
.gruppe dl { display: grid; gap: 0; }
.eintrag { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 5fr); gap: 4px 24px; padding: 14px 0; border-top: 1px solid var(--linie); }
.eintrag:first-child { border-top: 0; padding-top: 0; }
.eintrag dt { font-family: 'DM Mono', ui-monospace, monospace; font-size: .8125rem; letter-spacing: .02em; color: var(--leise); padding-top: 4px; }
.eintrag dd { font-size: 1.0625rem; }
.eintrag dd small { display: block; color: var(--leise); font-size: .9375rem; margin-top: 2px; }
/* Schriftmuster in der jeweiligen Schrift */
.muster { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.muster figure { border: 1px solid var(--linie); padding: 18px 20px 16px; display: grid; gap: 10px; align-content: space-between; min-height: 220px; }
.muster .glyphen { font-size: clamp(4rem, 9vw, 8rem); line-height: .9; letter-spacing: -.03em; }
.muster .tt75 { font-weight: 800; font-stretch: 75%; }
.muster .tt150 { font-weight: 300; font-stretch: 150%; font-size: clamp(3rem, 6.4vw, 5.75rem); }
.muster .dm { font-family: 'DM Mono', ui-monospace, monospace; font-weight: 400; font-size: clamp(2.75rem, 5.6vw, 4.75rem); letter-spacing: 0; }
.muster figcaption { display: grid; gap: 2px; font-size: .9375rem; }
.muster figcaption b { font-weight: 600; }
/* Farben mit Namen und Wert */
.farben { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.farben li { display: grid; gap: 8px; font-size: .9375rem; }
.farben .flaeche { aspect-ratio: 4 / 3; border: 1px solid var(--linie); display: flex; align-items: flex-end; padding: 8px; font-family: 'DM Mono', monospace; font-size: .75rem; }
.farben b { font-weight: 600; }
.farben span { color: var(--leise); font-family: 'DM Mono', monospace; font-size: .8125rem; }
/* Bildnachweis je Foto */
.bilder { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 16px; }
.bilder figure { display: grid; gap: 8px; }
.bilder img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 4px; background: #1a1a1a; }
.bilder figcaption { font-size: .875rem; line-height: 1.4; }
.bilder figcaption b { display: block; font-weight: 600; font-size: .9375rem; }
.bilder figcaption span { color: var(--leise); }
/* ── Variante gewicht ──────────────────────────────────────────────── */
.waage { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(24px, 4vw, 64px); align-items: start; }
.zahl { font-weight: 800; font-stretch: 75%; font-size: clamp(5rem, 14vw, 13rem); line-height: .82; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.zahl small { font-size: .32em; font-weight: 600; font-stretch: 100%; letter-spacing: 0; margin-left: .15em; }
.waage .unter { margin-top: 16px; font-size: 1.125rem; }
.anteile { display: grid; gap: 14px; }
.balken { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr) 5.5rem; gap: 12px; align-items: center; font-variant-numeric: tabular-nums; }
.balken .spur { height: 14px; background: #1c1c1c; position: relative; }
.balken .spur i { position: absolute; inset: 0 auto 0 0; width: var(--a); background: var(--text); }
.balken.haupt .spur i { background: var(--signal); }
.balken b { font-weight: 500; text-align: right; font-size: 1rem; }
.protokoll { width: 100%; border-collapse: collapse; margin-top: 28px; font-variant-numeric: tabular-nums; font-size: 1rem; }
.protokoll caption { text-align: left; padding-bottom: 8px; }
.protokoll th, .protokoll td { text-align: left; padding: 9px 0; border-bottom: 1px solid var(--linie); font-weight: 400; vertical-align: top; }
.protokoll th { color: var(--leise); font-family: 'DM Mono', monospace; font-size: .8125rem; padding-right: 16px; width: 38%; }
.ohne { margin-top: 24px; border: 1px solid var(--linie); padding: 14px 16px; font-size: .9375rem; color: var(--hell); }
.ohne b { color: var(--text); }
/* ── Pult ──────────────────────────────────────────────────────────── */
.pult { position: fixed; right: 12px; bottom: 12px; z-index: 40; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 6px 6px 6px 12px; border-radius: 999px; background: rgba(242, 242, 242, .95); color: #333; font: 500 10.5px/1 'DM Mono', ui-monospace, monospace; letter-spacing: .14em; text-transform: uppercase; max-width: calc(100vw - 24px); }
.pult .knoepfe { display: flex; flex-wrap: wrap; gap: 4px; }
.pult button { font: inherit; letter-spacing: inherit; text-transform: inherit; height: 30px; padding: 0 12px; border-radius: 999px; border: 1px solid rgba(0, 0, 0, .2); background: none; color: #222; cursor: pointer; }
.pult button[aria-pressed='true'] { background: #0b0b0b; color: #fff; border-color: #0b0b0b; }
.pult :focus-visible { outline-color: #0b0b0b; }
/* Vorschau */
.vorschau body { overflow: hidden; }
.vorschau .kopf ul { display: none; }
.vorschau .fuss.mit-pult { padding-bottom: 20px; }
@media (max-width: 900px) {
.ende, .kolophon .einleitung, .gruppe, .waage { grid-template-columns: minmax(0, 1fr); }
.spalten { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.farben { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
.kopf ul { display: none; }
.eintrag { grid-template-columns: minmax(0, 1fr); }
.muster { grid-template-columns: minmax(0, 1fr); }
.farben { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.unterzeile { flex-direction: column; }
.balken { grid-template-columns: 6rem minmax(0, 1fr) 4.5rem; }
}
@media (max-width: 360px) { .spalten { grid-template-columns: minmax(0, 1fr); } .bilder { grid-template-columns: minmax(0, 1fr); } .balken { grid-template-columns: minmax(0, 1fr) 4.5rem; } .balken .spur { grid-column: 1 / -1; grid-row: 2; } }
:root.reduziert *, :root.reduziert *::before, :root.reduziert *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
@media (forced-colors: active) {
button, [role=button], [role=tab], [role=switch], input, select, textarea { border: 1px solid ButtonText !important; }
.balken .spur { border: 1px solid CanvasText; } .balken .spur i { background: CanvasText; forced-color-adjust: none; }
.farben .flaeche { forced-color-adjust: none; }
}
</style>
</head>
<body data-v="zeile">
<header class="kopf">
<a class="marke" href="?v=zeile">Hallraum</a>
<nav aria-label="Hauptnavigation"><ul><li><a href="?v=zeile">Arbeiten</a></li><li><a href="?v=zeile">Studio</a></li><li><a href="?v=zeile">Kontakt</a></li></ul></nav>
</header>
<main id="inhalt">
<!-- Variante zeile: Seitenende des Studios, die Kolophon-Zeile steht im Footer -->
<section class="ende nur-zeile" aria-labelledby="h-ende">
<h2 id="h-ende">Hast du etwas, das wir bauen sollen?</h2>
<a class="post" href="mailto:hallo@hallraum.example">hallo@hallraum.example</a>
</section>
<!-- Varianten seite und gewicht: die Kolophon-Seite -->
<article class="kolophon nur-seite" aria-labelledby="h-kolophon" hidden>
<h1 id="h-kolophon">Kolophon</h1>
<div class="einleitung">
<p class="mono leise">Stand <time datetime="2026-11-03">3. November 2026</time></p>
<p>Womit diese Seite gemacht ist, wer daran gearbeitet hat und woher die Bilder kommen. Wie die letzte Seite eines Buchs.</p>
</div>
<section class="gruppe nur-seite-voll" aria-labelledby="g-schrift">
<h2 id="g-schrift">Schrift</h2>
<div>
<div class="muster">
<figure>
<p class="glyphen" aria-hidden="true"><span class="tt75">Aa</span> <span class="tt150">Aa</span></p>
<figcaption><b>TikTok Sans</b><span class="leise">Grilli Type mit Contrast Foundry · OFL 1.1 · Breite 75 und 150 für Überschriften und Text</span></figcaption>
</figure>
<figure>
<p class="glyphen dm" aria-hidden="true">Aa 01</p>
<figcaption><b>DM Mono</b><span class="leise">Colophon Foundry · OFL 1.1 · Labels, Daten, diese Zeile</span></figcaption>
</figure>
</div>
<dl style="margin-top: 20px">
<div class="eintrag"><dt>Einbindung</dt><dd>Selbst gehostet als WOFF2, keine Anfrage an fremde Server.</dd></div>
</dl>
</div>
</section>
<section class="gruppe nur-seite-voll" aria-labelledby="g-farbe">
<h2 id="g-farbe">Farbe</h2>
<ul class="farben">
<li><span class="flaeche" style="background:#0b0b0b; color:#fff">Aa</span><b>Nachtschwarz</b><span>#0B0B0B · Grund</span></li>
<li><span class="flaeche" style="background:#ffffff; color:#0b0b0b">Aa</span><b>Weiß</b><span>#FFFFFF · Text, 19,8 : 1</span></li>
<li><span class="flaeche" style="background:#f2f2f2; color:#0b0b0b">Aa</span><b>Kreide</b><span>#F2F2F2 · heller Grund</span></li>
<li><span class="flaeche" style="background:#6b6b6b; color:#fff">Aa</span><b>Schiefer</b><span>#6B6B6B · Meta auf Kreide, 4,8 : 1</span></li>
<li><span class="flaeche" style="background:#ff5a1f; color:#0b0b0b">Aa</span><b>Signal</b><span>#FF5A1F · nur Handlung und Hover</span></li>
</ul>
</section>
<section class="gruppe nur-seite-voll" aria-labelledby="g-bild">
<h2 id="g-bild">Bild</h2>
<ul class="bilder" id="bildnachweis"><!-- aus derselben Liste wie die Bilder der Seite, siehe Skript --></ul>
</section>
<section class="gruppe nur-seite-voll" aria-labelledby="g-technik">
<h2 id="g-technik">Technik</h2>
<dl>
<div class="eintrag"><dt>Gebaut mit</dt><dd>HTML und CSS von Hand, ein paar Zeilen JavaScript. Kein Baukasten.</dd></div>
<div class="eintrag"><dt>Hosting</dt><dd>[Hoster des Kunden], Rechenzentrum in Frankfurt am Main <small>Platzhalter: im Projekt eintragen</small></dd></div>
<div class="eintrag"><dt>Geprüft</dt><dd>Tastatur, Bildschirmleser, 200 % Zoom, Windows-Kontrastmodus</dd></div>
</dl>
</section>
<section class="gruppe nur-seite-voll" aria-labelledby="g-dank">
<h2 id="g-dank">Dank</h2>
<dl>
<div class="eintrag"><dt>Gestaltung</dt><dd>Lene Hartung, Can Özdemir</dd></div>
<div class="eintrag"><dt>Text</dt><dd>Ruth Weimann</dd></div>
<div class="eintrag"><dt>Fotografie</dt><dd>Jonte Ries <small>Studioaufnahmen der Arbeiten</small></dd></div>
</dl>
</section>
<!-- Variante gewicht: gemessenes Seitengewicht mit Datum, ohne Umweltangabe -->
<section class="gruppe nur-gewicht" aria-labelledby="g-gewicht" hidden>
<h2 id="g-gewicht">Gewicht</h2>
<div class="waage">
<div>
<p class="zahl"><span id="kib">––</span><small>KiB</small></p>
<p class="unter">in <b id="anfragen">––</b> Anfragen, beim Bau gemessen am <time datetime="2026-11-03">3. November 2026</time>.</p>
</div>
<div>
<div class="anteile" id="anteile" role="list" aria-label="Anteile nach Art"></div>
<table class="protokoll">
<caption class="mono leise">Messprotokoll</caption>
<tbody>
<tr><th scope="row">Seite</th><td>Kolophon, diese Seite</td></tr>
<tr><th scope="row">Gemessen</th><td>Summe der Übertragungsgrößen, kalt geladen, ohne Cache</td></tr>
<tr><th scope="row">Browser</th><td>Chromium 153, 1280 × 800</td></tr>
<tr><th scope="row">Datum</th><td><time datetime="2026-11-03">03.11.2026</time>, neu messen nach jeder größeren Änderung</td></tr>
</tbody>
</table>
<p class="ohne"><b>Bewusst ohne CO2-Wert.</b> Gramm je Aufruf wären eine Schätzung aus Modellannahmen, kein Messwert. Umweltaussagen ohne Nachweis sind seit 27.09.2026 riskant. Hier stehen nur Zahlen, die sich nachmessen lassen.</p>
</div>
</div>
</section>
</article>
</main>
<footer class="fuss mit-pult">
<div class="spalten">
<div><h3 class="mono">Studio</h3><address>Hallraum Studio<br>Pirmasenser Straße 41<br>67655 Kaiserslautern</address></div>
<div><h3 class="mono">Kontakt</h3><ul><li><a href="mailto:hallo@hallraum.example">hallo@hallraum.example</a></li><li><a href="tel:+49631000000">0631 000 000</a></li></ul></div>
<div><h3 class="mono">Seiten</h3><ul><li><a href="?v=zeile">Arbeiten</a></li><li><a href="?v=zeile">Studio</a></li><li><a href="?v=zeile">Jobs</a></li></ul></div>
<div><h3 class="mono">Post</h3><ul><li><a href="?v=zeile">Newsletter, viermal im Jahr</a></li></ul></div>
</div>
<p class="wortmarke" aria-hidden="true"><span>Hallraum</span></p>
<div class="unterzeile mono">
<div class="rechtliches"><span>© 2026 Hallraum Studio</span><a href="?v=zeile">Impressum</a><a href="?v=zeile">Datenschutz</a></div>
<p class="kolophon-zeile" id="kolophon-zeile">
<span>Stand <time datetime="2026-11-03">3. November 2026</time></span><span class="trenn" aria-hidden="true">·</span>
<span class="gewicht-kurz nur-gewicht" hidden><span id="kib-kurz">––</span> KiB, <span id="anfragen-kurz">––</span> Anfragen</span><span class="trenn nur-gewicht" aria-hidden="true" hidden>·</span>
<a href="?v=seite" id="kolophon-link">Kolophon</a>
</p>
</div>
</footer>
<div class="pult">
<span>Variante</span>
<div class="knoepfe" role="group" aria-label="Variante">
<button type="button" data-v="zeile" aria-pressed="true">Zeile</button>
<button type="button" data-v="seite" aria-pressed="false">Seite</button>
<button type="button" data-v="gewicht" aria-pressed="false">Gewicht</button>
</div>
</div>
<script>
(() => {
const h = document.documentElement;
const reduziert = () => h.classList.contains('reduziert');
/* Beim Bau gemessen (03.11.2026, Chromium 153, kalt, ohne Cache): diese Demo-Seite in Variante gewicht */
const MESSUNG = { kib: 153, anfragen: 4, anteile: [{ art: 'Schriften', n: 3, kib: 119.0 }, { art: 'HTML', n: 1, kib: 33.7 }, { art: 'Bilder', n: 0, kib: 0 }] }; // MESSUNG
/* Bilder der Seite und ihr Nachweis aus derselben Liste */
const BILDER = [
{ datei: 'typo-plakat.jpg', titel: 'Plakat „Licht“', alt: 'Plakat mit dem Wort LICHT in riesigen schwarzen Versalien und einer orangeroten Kreisscheibe auf limettengrünem Grund', nachweis: 'Foto: Jonte Ries, Studioaufnahme' },
{ datei: 'magazin-doppelseite.jpg', titel: 'Magazin „Die Ruhe der Dinge“', alt: 'Aufgeschlagenes Magazin mit ganzseitigem Foto von Keramik und der Überschrift Die Ruhe der Dinge', nachweis: 'Foto: Jonte Ries, Studioaufnahme' },
{ datei: 'marke-roestkontor.jpg', titel: 'Marke Röstkontor', alt: 'Wortmarke RÖSTKONTOR in Creme auf tomatenrotem Grund', nachweis: 'Abbildung mit Freigabe der Kundin, 2025' },
{ datei: 'marke-eselsohr.jpg', titel: 'Marke Eselsohr', alt: 'Kursive Wortmarke Eselsohr in Creme auf fast schwarzem Grund', nachweis: 'Abbildung mit Freigabe des Kunden, 2026' }
];
const liste = document.getElementById('bildnachweis');
BILDER.forEach(b => {
const li = document.createElement('li'), fig = document.createElement('figure'), img = document.createElement('img'), cap = document.createElement('figcaption');
img.src = 'bilder/' + b.datei; img.alt = b.alt; img.width = 1200; img.height = 800; img.loading = 'lazy';
const t = document.createElement('b'); t.textContent = b.titel; const n = document.createElement('span'); n.textContent = b.nachweis;
cap.append(t, n); fig.append(img, cap); li.append(fig); liste.append(li);
});
/* Wortmarke auf Spaltenbreite einpassen (Textabstände 1.4.12, Schriftwechsel) */
const wm = document.querySelector('.wortmarke span');
function passe() {
const p = wm.parentElement, w = wm.getBoundingClientRect().width, soll = p.clientWidth;
if (!w || !soll || Math.abs(w - soll) < 2) return;
p.style.fontSize = (parseFloat(getComputedStyle(p).fontSize) * soll / w) + 'px';
}
if ('ResizeObserver' in window) { const ro = new ResizeObserver(() => requestAnimationFrame(passe)); ro.observe(wm); ro.observe(wm.parentElement); }
if (document.fonts) document.fonts.ready.then(passe);
/* Messwerte eintragen */
const de = (n, d = 0) => n.toLocaleString('de-DE', { minimumFractionDigits: d, maximumFractionDigits: d });
function trageEin() {
if (!MESSUNG.kib) return;
document.getElementById('kib').textContent = de(MESSUNG.kib);
document.getElementById('kib-kurz').textContent = de(MESSUNG.kib);
document.getElementById('anfragen').textContent = MESSUNG.anfragen;
document.getElementById('anfragen-kurz').textContent = MESSUNG.anfragen;
const ziel = document.getElementById('anteile'); ziel.innerHTML = '';
const max = Math.max(...MESSUNG.anteile.map(a => a.kib));
MESSUNG.anteile.forEach((a, i) => {
const z = document.createElement('div'); z.className = 'balken' + (i === 0 ? ' haupt' : ''); z.setAttribute('role', 'listitem');
z.innerHTML = '<span class="mono"></span><span class="spur" aria-hidden="true"><i></i></span><b></b>';
z.children[0].textContent = a.art + ' (' + a.n + ')';
z.children[1].firstChild.style.setProperty('--a', (a.kib / max * 100).toFixed(1) + '%');
z.children[2].textContent = (a.kib ? de(a.kib, a.kib < 10 ? 1 : 0) : '0') + ' KiB';
ziel.append(z);
});
}
trageEin();
/* Varianten */
const pultKnoepfe = [...document.querySelectorAll('.pult [data-v]')];
const link = document.getElementById('kolophon-link');
let v = 'zeile';
function setzeVariante(neu, url) {
v = ['zeile', 'seite', 'gewicht'].includes(neu) ? neu : 'zeile';
document.body.dataset.v = v;
document.querySelectorAll('.nur-zeile').forEach(e => { e.hidden = v !== 'zeile'; });
document.querySelectorAll('.nur-seite').forEach(e => { e.hidden = v === 'zeile'; });
document.querySelectorAll('.nur-seite-voll').forEach(e => { e.hidden = v !== 'seite'; });
document.querySelectorAll('.nur-gewicht').forEach(e => { e.hidden = v !== 'gewicht'; });
if (v === 'zeile') { link.href = '?v=seite'; link.removeAttribute('aria-current'); }
else { link.href = '?v=' + v; link.setAttribute('aria-current', 'page'); }
pultKnoepfe.forEach(b => b.setAttribute('aria-pressed', b.dataset.v === v ? 'true' : 'false'));
if (url) { const u = new URL(location.href); u.searchParams.set('v', v); history.replaceState(history.state, '', u); }
}
pultKnoepfe.forEach(b => b.addEventListener('click', () => { pause(); setzeVariante(b.dataset.v, true); scrollTo(0, 0); }));
/* Im Demo führt der Link zur Variante seite, ohne neu zu laden */
link.addEventListener('click', e => { if (v === 'zeile') { e.preventDefault(); setzeVariante('seite', true); scrollTo(0, 0); document.getElementById('h-kolophon').focus({ preventScroll: true }); } });
document.getElementById('h-kolophon').tabIndex = -1;
/* Vorführung: zur Kolophon-Zeile scrollen und sie zeigen; auf der Seite die Gruppen nacheinander */
let zeit = [], laeuft = false;
const warte = ms => new Promise(r => zeit.push(setTimeout(r, ms)));
const fahre = y => scrollTo({ top: y, behavior: reduziert() ? 'auto' : 'smooth' });
const unten = () => document.documentElement.scrollHeight - innerHeight;
const zeile = document.getElementById('kolophon-zeile');
async function runde(lauf) {
fahre(0); await warte(1200); if (laeuft !== lauf) return;
if (v === 'zeile') {
fahre(unten()); await warte(1400); if (laeuft !== lauf) return;
zeile.classList.add('gezeigt'); await warte(1800); zeile.classList.remove('gezeigt');
} else if (v === 'seite') {
for (const id of ['g-schrift', 'g-farbe', 'g-bild', 'g-technik']) {
if (laeuft !== lauf) return;
fahre(document.getElementById(id).getBoundingClientRect().top + scrollY - 24); await warte(1700);
}
fahre(unten()); await warte(1200); if (laeuft !== lauf) return;
zeile.classList.add('gezeigt'); await warte(1400); zeile.classList.remove('gezeigt');
} else {
fahre(document.getElementById('g-gewicht').getBoundingClientRect().top + scrollY - 24); await warte(2400); if (laeuft !== lauf) return;
fahre(unten()); await warte(1200); if (laeuft !== lauf) return;
zeile.classList.add('gezeigt'); await warte(1600); zeile.classList.remove('gezeigt');
}
if (laeuft === lauf) runde(lauf);
}
function neustart() { pause(); setzeVariante(v, false); scrollTo(0, 0); }
function vorfuehren() { pause(); laeuft = Symbol(); runde(laeuft); }
function pause() { laeuft = false; zeit.forEach(clearTimeout); zeit = []; zeile.classList.remove('gezeigt'); }
function weiter() { vorfuehren(); }
setzeVariante(new URLSearchParams(location.search).get('v'), false);
})();
</script>
</body>
</html>