Mono als Label- und Metaschrift (kleine Versalien)
Projektblatt eines Chemnitzer Architekturbüros, auf dem ein einziges Mono-Token alle Labels trägt: Navigation, Rubriken, Projektdaten, Planbeschriftung, Werkverzeichnis und Visitenkarte.
Eine Monospace-Schrift übernimmt alles, was beschriftet statt erzählt: Navigation, Rubriken, Datum, Zähler, Bildunterschriften, Tabellenköpfe. Sie steht in kleinen Versalien (10 bis 13 px) mit positiver Laufweite. Überschriften und Fließtext bleiben in der Grotesk oder Serif.
Mono trennt die Metaebene sichtbar vom Inhalt. Gleich breite Zeichen und Tabellenziffern wirken technisch und genau, wie Planköpfe oder Etiketten. Die Laufweite hält kleine Versalien lesbar und gibt ihnen Ruhe.
Wann einsetzen
Architektur, Software, Technik, Studios, Archive und Werkverzeichnisse: überall, wo viele kurze Angaben (Nummer, Ort, Jahr, Status) neben dem eigentlichen Inhalt stehen.
Wann nicht
Für Fließtext, lange Navigationspunkte oder ganze Sätze. Nicht bei warmen, verspielten oder sehr klassischen Marken, wo der technische Ton fremd wirkt. Nicht, wenn schon zwei andere Schriften im Spiel sind und Mono nur eine weitere Stimme wäre.
Varianten
- Standard: 11 px, Laufweite +0,1 em, 500 (Clerk)
- Klein und weit: 9,5 px, +0,14 em (Warp)
- Kräftig für Knöpfe: 12 px, +0,1 em, 600 (Terminal Industries)
Umsetzung
Ein Label-Token als Custom Properties festlegen (Familie, Größe, Laufweite, Gewicht) und für alle Meta-Elemente eine Klasse nutzen. Werte: font-size .625 bis .8125rem, letter-spacing +.08 bis +.14em, text-transform: uppercase, Gewicht 400 bis 600. Zahlen mit font-variant-numeric: tabular-nums. Gängige Schnitte sind Geist Mono, DM Mono oder Söhne Mono.
Robust umsetzen
Telefon. Die Größe bleibt gleich, unter 10 px wird es auf dem Telefon zu klein. Lange Labelzeilen umbrechen lassen oder kürzen, nicht verkleinern.
Ohne Bewegung. Nicht relevant, die Technik hat keine Bewegung.
Barrierefrei. text-transform statt Versalien im Quelltext schreiben, damit Screenreader normal vorlesen. Kontrast auch für die leise Labelfarbe prüfen (mindestens 4,5 : 1 bei dieser Größe). Labels nicht unter 10 px setzen und keine Informationen nur über das Label transportieren.
Code
<!DOCTYPE html>
<!--
Mono als Label- und Metaschrift (kleine Versalien)
Fundus · Typo-Techniken · https://cecodesign.de/lab/fundus/typo-techniken/mono-labels-versal/
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>Mono als Label- und Metaschrift (kleine Versalien) · 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: 'Hanken Grotesk'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/hanken-grotesk:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 100 900; font-style: normal; font-display: swap; }
@font-face { font-family: 'Hanken Grotesk'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/hanken-grotesk:vf@latest/latin-wght-italic.woff2') format('woff2-variations'); font-weight: 100 900; font-style: italic; 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; }
:root {
/* Rezept „Architektur: ruhiges Raster“: achromatisch, warmes Fast-Schwarz, ein Interaktionston */
--grund: #ffffff; --flaeche: #e1e3e3; --tinte: #231f20; --tinte-2: #76767a; --tinte-3: #c5c7c7; --dunkel: #1f2323;
--blau: #0022ff; /* Fokus und Interaktion, hier auch die Markierung der Labels */
--kurve: cubic-bezier(0.1, 0.6, 0.4, 1); /* Default-Kurve (Chipperfield, KAAN) */
--ui: 250ms var(--kurve);
--sans: 'Hanken Grotesk', system-ui, sans-serif;
--mono: 'Geist Mono', ui-monospace, monospace;
}
* { box-sizing: border-box; margin: 0; }
html { background: var(--grund); color: var(--tinte); font-family: var(--sans); font-weight: 450; -webkit-font-smoothing: antialiased; overflow-x: clip; }
body { min-height: 100svh; overflow-x: clip; }
button { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--blau); outline-offset: 3px; }
/* ================= Der Effekt: ein Label-Token für die ganze Seite ================= */
.seite {
/* Standard (gemessen wie bei Clerk): 11 px, +0,10 em, 500, versal */
--l-familie: var(--mono); --l-groesse: .6875rem; --l-laufweite: .1em; --l-gewicht: 500;
}
.seite[data-stil='klein'] { --l-groesse: .59375rem; --l-laufweite: .14em; --l-gewicht: 500; } /* 9,5 px wie Warp */
.seite[data-stil='kraeftig']{ --l-groesse: .75rem; --l-laufweite: .1em; --l-gewicht: 600; } /* 12 px wie Terminal Industries */
/* Gegenproben */
.seite[data-stil='grotesk'] { --l-familie: var(--sans); } /* gleiche Werte, Grotesk statt Mono */
.seite[data-stil='eng'] { --l-laufweite: 0em; } /* Mono ohne Laufweite */
.lbl {
font-family: var(--l-familie); font-size: var(--l-groesse); font-weight: var(--l-gewicht);
letter-spacing: var(--l-laufweite); text-transform: uppercase; line-height: 1.35;
font-variant-numeric: tabular-nums slashed-zero;
transition: font-size var(--ui), letter-spacing var(--ui), outline-color var(--ui), background-color var(--ui);
outline: 1px solid transparent; outline-offset: 2px;
}
.lbl:focus-visible { outline: 2px solid var(--blau); outline-offset: 3px; } /* sonst überschreibt die transparente Haarlinie den Fokusring */
.leise { color: var(--tinte-2); }
/* Markieren: jedes Label bekommt eine Haarlinie, ohne dass sich das Layout bewegt */
.seite[data-zeigen='ja'] .lbl { outline-color: var(--blau); background-color: rgba(0, 34, 255, .05); }
/* ================= Fundus-Leiste (außerhalb der Seite, nicht fixiert) ================= */
.leiste { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 24px; padding: 12px clamp(16px, 3vw, 40px); border-bottom: 1px solid var(--flaeche); font: 500 11px/1.3 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--tinte-2); }
.gruppen { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; }
.gruppe { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.gruppe > span { margin-right: 6px; }
.gruppe button { font: inherit; letter-spacing: .08em; text-transform: inherit; color: var(--tinte-2); background: none; border: 1px solid var(--flaeche); border-radius: 999px; height: 28px; padding: 0 11px; cursor: pointer; white-space: nowrap; transition: color var(--ui), background-color var(--ui), border-color var(--ui); }
.gruppe button:hover { color: var(--tinte); border-color: var(--tinte-3); }
.gruppe button[aria-pressed='true'] { background: var(--tinte); border-color: var(--tinte); color: var(--grund); }
.gruppe.gegen button[aria-pressed='true'] { background: var(--grund); color: var(--tinte); border-color: var(--tinte); }
.gruppe button.blau[aria-pressed='true'] { background: var(--blau); border-color: var(--blau); color: #fff; }
.token { font: 450 11px/1.4 var(--mono); letter-spacing: 0; text-transform: none; color: var(--tinte); font-variant-numeric: tabular-nums; }
.token b { font-weight: 450; color: var(--blau); }
/* ================= Seite: Kopf ================= */
.kopf { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 24px; padding: 22px clamp(16px, 3vw, 40px) 0; }
.marke { font-size: 1.0625rem; font-weight: 500; letter-spacing: -.012em; }
.marke em { font-style: italic; font-weight: 450; }
.nav { display: flex; gap: clamp(18px, 2.6vw, 38px); list-style: none; padding: 0; }
.nav a { position: relative; padding-block: 4px; color: var(--tinte-2); transition: color var(--ui); }
.nav a[aria-current] { color: var(--tinte); }
.nav a[aria-current]::before { content: ''; position: absolute; left: -12px; top: 50%; width: 5px; height: 5px; translate: 0 -50%; background: var(--tinte); }
.nav a:hover { color: var(--tinte); }
.kopf .koord { justify-self: end; text-align: right; }
/* ================= Seite: Projektblatt ================= */
.blatt { display: grid; grid-template-columns: minmax(300px, 4fr) 7fr; gap: clamp(24px, 3.4vw, 56px); padding: clamp(36px, 5vw, 72px) clamp(16px, 3vw, 40px) clamp(40px, 5vw, 72px); }
.blatt-text { display: flex; flex-direction: column; gap: 22px; }
.zeile { display: flex; flex-wrap: wrap; gap: 6px 26px; }
h1 { font-size: clamp(2.441rem, 1.4rem + 3vw, 4.4rem); font-weight: 450; letter-spacing: -.03em; line-height: 1; text-wrap: balance; }
h1 em { font-weight: 400; }
.lead { font-size: clamp(1.125rem, 1rem + .35vw, 1.3rem); line-height: 1.45; letter-spacing: -.012em; max-width: 30em; text-wrap: pretty; }
.daten { display: grid; grid-template-columns: max-content 1fr; gap: 0 22px; border-top: 1px solid var(--flaeche); margin-top: 6px; }
.daten dt, .daten dd { padding: 11px 0 10px; border-bottom: 1px solid var(--flaeche); }
.daten dt { color: var(--tinte-2); align-self: baseline; padding-top: 13px; }
.daten dd { font-size: 1rem; font-variant-numeric: tabular-nums; }
.wege { display: flex; flex-wrap: wrap; gap: 10px 26px; margin-top: auto; padding-top: 10px; }
.weg { display: inline-flex; align-items: center; gap: 10px; padding-block: 6px; border-bottom: 1px solid var(--tinte); transition: color var(--ui), border-color var(--ui); }
.weg:hover { color: var(--blau); border-color: var(--blau); }
.weg.zwei { border-color: var(--tinte-3); color: var(--tinte-2); }
/* Zeichnung: SVG für Linien, HTML für Beschriftung (Labels bleiben echte px-Größe) */
.plan { display: flex; flex-direction: column; gap: 14px; }
.plan-kopf, .plan-fuss { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.zeichnung { position: relative; aspect-ratio: 1000 / 680; background: #f3f4f4; }
.zeichnung svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.zeichnung .lbl { position: absolute; white-space: nowrap; line-height: 1; color: var(--tinte); }
.zeichnung .achse { translate: -50% -50%; color: var(--tinte); }
.zeichnung .kote { translate: 0 -100%; line-height: 1.25; }
.zeichnung .mass { translate: -50% 0; color: var(--tinte-2); }
.legende { display: flex; gap: 6px 20px; flex-wrap: wrap; }
.hinweis { color: var(--tinte-2); }
.hinweis::before { content: ''; display: inline-block; width: 16px; height: 0; border-top: 1px solid currentColor; vertical-align: middle; margin-right: 8px; }
.hinweis.neu::before { border-top-style: dashed; }
/* ================= Seite: Werkverzeichnis ================= */
.werk { padding: clamp(24px, 3vw, 40px) clamp(16px, 3vw, 40px) clamp(48px, 6vw, 88px); background: var(--grund); }
.werk-kopf { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-bottom: 26px; }
.werk-kopf h2 { font-size: clamp(1.563rem, 1.2rem + 1vw, 1.953rem); font-weight: 450; letter-spacing: -.02em; }
.liste { list-style: none; padding: 0; border-top: 1px solid var(--tinte); }
.reihe { display: grid; grid-template-columns: 70px 1.6fr 1fr 1.1fr 72px 1fr; gap: 16px; align-items: baseline; padding: 15px 0 14px; border-bottom: 1px solid var(--flaeche); transition: background-color var(--ui), box-shadow var(--ui); }
.reihe.titel { padding-block: 10px; border-bottom-color: var(--tinte-3); }
.reihe a { font-size: 1.125rem; letter-spacing: -.012em; }
.reihe:not(.titel):hover { background: #f3f4f4; box-shadow: -12px 0 0 #f3f4f4, 12px 0 0 #f3f4f4; }
.status { display: inline-flex; align-items: center; gap: 8px; }
.status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--tinte); }
.status.bau::before { background: none; box-shadow: inset 0 0 0 1px var(--tinte); }
.status.preis::before { border-radius: 0; }
/* ================= Seite: Visitenkarte ================= */
.fuss { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; padding: 40px clamp(16px, 3vw, 40px) 44px; background: var(--dunkel); color: #f4f5f5; }
.fuss .leise { color: rgba(244, 245, 245, .56); }
.fuss p { font-size: .9375rem; line-height: 1.5; }
.fuss .lbl { display: block; margin-bottom: 10px; }
.seite[data-zeigen='ja'] .fuss .lbl { outline-color: #7f92ff; background-color: rgba(127, 146, 255, .08); }
/* ================= Vorschau 960 × 720: nur die Bühne ================= */
.vorschau body { overflow: hidden; }
.vorschau .werk, .vorschau .fuss, .vorschau .gruppe.gegen, .vorschau .gruppe > span { display: none; }
.vorschau .blatt { padding-top: 34px; grid-template-columns: 4fr 6fr; }
.vorschau .wege { display: none; }
/* ================= Schmal ================= */
@media (max-width: 1100px) {
.reihe { grid-template-columns: 56px 1.6fr 1fr 64px 1fr; }
.reihe .typ { display: none; }
}
@media (max-width: 900px) {
.kopf { grid-template-columns: 1fr auto; }
.kopf .koord { display: none; }
.blatt { grid-template-columns: 1fr; }
.fuss { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
.kopf { grid-template-columns: 1fr; gap: 14px; }
.nav { gap: 20px; flex-wrap: wrap; }
.nav a[aria-current]::before { display: none; }
.nav a[aria-current] { border-bottom: 1px solid var(--tinte); }
.zeichnung .klein, .zeichnung .achse, .zeichnung .kote .leise, .zeichnung .kote br { display: none; }
.achskreis { r: 6; }
.reihe { grid-template-columns: 44px 1fr auto; row-gap: 4px; }
.reihe .ort, .reihe .typ { display: none; }
.reihe .stat { grid-column: 2 / -1; }
.reihe.titel .stat { display: none; }
.reihe .jahr { grid-column: 3; grid-row: 1; }
.fuss { grid-template-columns: 1fr; }
.token { flex-basis: 100%; }
}
@media (hover: none) {
.gruppe button { height: 36px; padding: 0 13px; }
.reihe:not(.titel):active { background: #f3f4f4; box-shadow: -12px 0 0 #f3f4f4, 12px 0 0 #f3f4f4; }
}
:root.reduziert * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
</style>
</head>
<body>
<div class="leiste">
<div class="gruppen">
<div class="gruppe" role="group" aria-label="Label-Stil">
<span>Label</span>
<button type="button" data-stil-knopf="standard" aria-pressed="true">11 px · .10 em</button>
<button type="button" data-stil-knopf="klein" aria-pressed="false">9,5 px · .14 em</button>
<button type="button" data-stil-knopf="kraeftig" aria-pressed="false">12 px · 600</button>
</div>
<div class="gruppe gegen" role="group" aria-label="Gegenprobe">
<span>Gegenprobe</span>
<button type="button" data-stil-knopf="grotesk" aria-pressed="false">Grotesk</button>
<button type="button" data-stil-knopf="eng" aria-pressed="false">Ohne Laufweite</button>
</div>
<div class="gruppe" role="group" aria-label="Anzeige">
<button type="button" class="blau" data-zeigen-knopf aria-pressed="false">Labels zeigen</button>
</div>
</div>
<p class="token" data-token aria-live="polite"></p>
</div>
<div class="seite" data-buehne data-stil="standard" data-zeigen="nein">
<header class="kopf">
<a class="marke" href="#">Haubold Krenz <em>Architekten</em></a>
<nav aria-label="Hauptnavigation">
<ul class="nav">
<li><a class="lbl" href="#">Büro</a></li>
<li><a class="lbl" href="#" aria-current="page">Projekte</a></li>
<li><a class="lbl" href="#">Team</a></li>
<li><a class="lbl" href="#">Aktuelles</a></li>
<li><a class="lbl" href="#">Kontakt</a></li>
</ul>
</nav>
<p class="koord lbl leise">Chemnitz · 50°50′ N 12°55′ O</p>
</header>
<main class="blatt">
<div class="blatt-text">
<p class="zeile"><span class="lbl">Projekt 014 / 027</span><span class="lbl leise">Wohnen, Umbau</span><span class="lbl leise">2021–2025</span></p>
<h1>Wirkerei Kaßberg</h1>
<p class="lead">Aus einer Strumpfwirkerei von 1907 werden 31 Wohnungen und eine offene Werkstatt im Erdgeschoss. Wir haben die Fassade repariert, <em>nicht</em> erneuert.</p>
<dl class="daten">
<dt class="lbl">Bauherr</dt><dd>Baugemeinschaft Wirkerei GbR</dd>
<dt class="lbl">Leistung</dt><dd>Leistungsphasen 1–8</dd>
<dt class="lbl">BGF</dt><dd>4 860 m²</dd>
<dt class="lbl">Fertig</dt><dd>September 2025</dd>
</dl>
<div class="wege">
<a class="weg lbl" href="#">Projekt ansehen <span aria-hidden="true">→</span></a>
<a class="weg zwei lbl" href="#">Alle Projekte (27)</a>
</div>
</div>
<figure class="plan">
<div class="plan-kopf"><span class="lbl">Ansicht Süd · M 1:200</span><span class="legende"><span class="lbl hinweis">Bestand 1907</span><span class="lbl hinweis neu">Aufstockung 2024</span></span></div>
<div class="zeichnung" data-zeichnung role="img" aria-label="Südansicht der Wirkerei: sieben Achsen, vier Geschosse Bestand, zurückgesetzte Aufstockung"></div>
<figcaption class="plan-fuss"><span class="lbl leise">Wirkerei Kaßberg • Chemnitz • 2025</span><span class="lbl leise">Stand 01.11.2026</span></figcaption>
</figure>
</main>
<section class="werk" aria-labelledby="werk-titel">
<div class="werk-kopf"><h2 id="werk-titel">Werkverzeichnis</h2><span class="lbl leise">5 von 27 · Sortiert nach Jahr</span></div>
<ol class="liste">
<li class="reihe titel"><span class="lbl leise">Nr.</span><span class="lbl leise">Projekt</span><span class="lbl leise ort">Ort</span><span class="lbl leise typ">Typologie</span><span class="lbl leise jahr">Jahr</span><span class="lbl leise stat">Status</span></li>
<li class="reihe"><span class="lbl leise">014</span><a href="#">Wirkerei Kaßberg</a><span class="lbl ort">Chemnitz</span><span class="lbl typ">Wohnen, Umbau</span><span class="lbl jahr">2025</span><span class="lbl stat status">Fertig</span></li>
<li class="reihe"><span class="lbl leise">013</span><a href="#">Grundschule am Schloßteich</a><span class="lbl ort">Chemnitz</span><span class="lbl typ">Bildung</span><span class="lbl jahr">2024</span><span class="lbl stat status">Fertig</span></li>
<li class="reihe"><span class="lbl leise">012</span><a href="#">Werkhalle Rabenstein</a><span class="lbl ort">Chemnitz</span><span class="lbl typ">Gewerbe</span><span class="lbl jahr">2023</span><span class="lbl stat status">Fertig</span></li>
<li class="reihe"><span class="lbl leise">011</span><a href="#">Haus am Zeisigwald</a><span class="lbl ort">Chemnitz</span><span class="lbl typ">Wohnen</span><span class="lbl jahr">2026</span><span class="lbl stat status bau">Im Bau</span></li>
<li class="reihe"><span class="lbl leise">010</span><a href="#">Stadtbibliothek Flöha</a><span class="lbl ort">Flöha</span><span class="lbl typ">Kultur</span><span class="lbl jahr">2022</span><span class="lbl stat status preis">Wettbewerb, 2. Preis</span></li>
</ol>
</section>
<footer class="fuss">
<div><span class="lbl leise">Büro</span><p>Haubold Krenz Architekten PartGmbB<br>Kaßbergstraße 12<br>09112 Chemnitz</p></div>
<div><span class="lbl leise">Kontakt</span><p><a href="#">0371 260 418 0</a><br><a href="#">buero@haubold-krenz.de</a></p></div>
<div><span class="lbl leise">Kammer</span><p>Architektenkammer Sachsen<br>Mitglieder Nr. 4471-1 und 5208-1</p></div>
<div><span class="lbl leise">Sprechzeit</span><p><span class="lbl">Mo–Do 09:00–17:00</span></p></div>
</footer>
</div>
<script>
(() => {
const html = document.documentElement;
const reduziert = () => html.classList.contains('reduziert');
const buehne = document.querySelector('[data-buehne]');
const stilKnoepfe = [...document.querySelectorAll('[data-stil-knopf]')];
const zeigenKnopf = document.querySelector('[data-zeigen-knopf]');
const token = document.querySelector('[data-token]');
// Exakt die Werte aus dem CSS (für die Anzeige)
const STIL = {
standard: { f: 'Geist Mono', g: '11px', l: '.1em', w: 500 },
klein: { f: 'Geist Mono', g: '9.5px', l: '.14em', w: 500 },
kraeftig: { f: 'Geist Mono', g: '12px', l: '.1em', w: 600 },
grotesk: { f: 'Hanken Grotesk', g: '11px', l: '.1em', w: 500 },
eng: { f: 'Geist Mono', g: '11px', l: '0', w: 500 }
};
/* ---------- Zeichnung: Südansicht, sieben Achsen, Bestand + Aufstockung ---------- */
const z = document.querySelector('[data-zeichnung]');
const X0 = 100, ACHSE = 100, N = 7, X1 = X0 + ACHSE * N; // 150 … 850
const EB = { gel: 560, og1: 462, og2: 372, og3: 282, ok: 196, gesims: 180, neu: 116 };
let s = '<svg viewBox="0 0 1000 680" preserveAspectRatio="xMidYMid meet" aria-hidden="true"><defs>'
+ '<pattern id="erde" width="9" height="9" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="9" stroke="#231f20" stroke-width=".7"/></pattern></defs>'
+ '<g fill="none" stroke="#231f20" stroke-linecap="square">';
// Achsen (Strichpunkt) mit Achskreisen
for (let i = 0; i <= N; i++) {
const x = X0 + i * ACHSE;
s += `<line x1="${x}" y1="60" x2="${x}" y2="600" stroke="#76767a" stroke-width=".6" stroke-dasharray="14 4 2 4"/>`;
s += `<circle class="achskreis" cx="${x}" cy="44" r="14" fill="#f3f4f4" stroke-width=".8"/>`;
}
// Baukörper Bestand
s += `<rect x="${X0}" y="${EB.ok}" width="${X1 - X0}" height="${EB.gel - EB.ok}" fill="#fff" stroke-width="1.6"/>`;
s += `<rect x="${X0 - 8}" y="${EB.gesims}" width="${X1 - X0 + 16}" height="${EB.ok - EB.gesims}" fill="#fff" stroke-width="1.2"/>`;
// Lisenen und Geschossbänder
for (let i = 0; i <= N; i++) { const x = X0 + i * ACHSE; s += `<rect x="${x - 7}" y="${EB.ok}" width="14" height="${EB.gel - EB.ok}" fill="#fff" stroke-width=".8"/>`; }
[EB.og1, EB.og2, EB.og3].forEach(y => { s += `<line x1="${X0}" y1="${y}" x2="${X1}" y2="${y}" stroke-width=".8"/><line x1="${X0}" y1="${y + 6}" x2="${X1}" y2="${y + 6}" stroke-width=".5"/>`; });
// Fenster mit Segmentbogen, Sprossen
const fenster = (x, y, b, h) => {
const st = 7;
let f = `<path d="M${x} ${y + h} V${y + st} Q${x + b / 2} ${y - st} ${x + b} ${y + st} V${y + h} Z" fill="#f3f4f4" stroke-width=".9"/>`;
for (let k = 1; k < 3; k++) f += `<line x1="${x + b * k / 3}" y1="${y + 3}" x2="${x + b * k / 3}" y2="${y + h}" stroke-width=".45"/>`;
f += `<line x1="${x}" y1="${y + h * .42}" x2="${x + b}" y2="${y + h * .42}" stroke-width=".45"/>`;
f += `<line x1="${x - 3}" y1="${y + h + 2}" x2="${x + b + 3}" y2="${y + h + 2}" stroke-width="1"/>`;
return f;
};
for (let i = 0; i < N; i++) {
const x = X0 + i * ACHSE + 18, b = ACHSE - 36;
s += fenster(x, EB.ok + 22, b, 50) + fenster(x, EB.og3 + 22, b, 60) + fenster(x, EB.og2 + 22, b, 60);
// Erdgeschoss: Achse 4 wird Werkstatt-Tor, die anderen große Fenster
if (i === 3) s += `<rect x="${x - 4}" y="${EB.og1 + 24}" width="${b + 8}" height="${EB.gel - EB.og1 - 24}" fill="#231f20" stroke="none"/><line x1="${x + b / 2}" y1="${EB.og1 + 24}" x2="${x + b / 2}" y2="${EB.gel}" stroke="#f3f4f4" stroke-width=".8"/>`;
else s += fenster(x, EB.og1 + 30, b, 56);
}
// Aufstockung (neu): zurückgesetzt, gestrichelt, Pfosten-Riegel
const nx0 = X0 + 40, nx1 = X1 - 40;
s += `<g stroke-dasharray="6 4" stroke-width="1.1"><rect x="${nx0}" y="${EB.neu}" width="${nx1 - nx0}" height="${EB.gesims - EB.neu}" fill="#fff"/></g>`;
for (let x = nx0 + 30; x < nx1; x += 30) s += `<line x1="${x}" y1="${EB.neu + 8}" x2="${x}" y2="${EB.gesims}" stroke-width=".4" stroke-dasharray="3 3"/>`;
s += `<line x1="${nx0 - 6}" y1="${EB.neu}" x2="${nx1 + 6}" y2="${EB.neu}" stroke-width="1.4"/>`;
// Gelände
s += `<rect x="40" y="${EB.gel}" width="860" height="16" fill="url(#erde)" stroke="none"/><line x1="40" y1="${EB.gel}" x2="900" y2="${EB.gel}" stroke-width="1.6"/>`;
// Höhenkoten rechts
const KOTEN = [[EB.neu, '+21,40', 'Dach'], [EB.gesims, '+17,90', 'Gesims'], [EB.og3, '+12,60', '3. OG'], [EB.og2, '+8,40', '2. OG'], [EB.og1, '+4,20', '1. OG'], [EB.gel, '±0,00', 'EG']];
KOTEN.forEach(([y]) => { s += `<path d="M${X1 + 22} ${y} H${X1 + 50} M${X1 + 38} ${y} l-5 -8 h10 Z" stroke-width=".8" fill="#fff"/>`; });
// Maßkette unten
const MY = 600;
s += `<line x1="${X0}" y1="${MY}" x2="${X1}" y2="${MY}" stroke-width=".7"/>`;
for (let i = 0; i <= N; i++) { const x = X0 + i * ACHSE; s += `<line x1="${x - 4}" y1="${MY + 4}" x2="${x + 4}" y2="${MY - 4}" stroke-width="1"/>`; }
const MY2 = 636;
s += `<line x1="${X0}" y1="${MY2}" x2="${X1}" y2="${MY2}" stroke-width=".7"/>`;
[X0, X1].forEach(x => { s += `<line x1="${x - 4}" y1="${MY2 + 4}" x2="${x + 4}" y2="${MY2 - 4}" stroke-width="1"/><line x1="${x}" y1="${MY + 6}" x2="${x}" y2="${MY2 + 8}" stroke-width=".5"/>`; });
s += '</g></svg>';
// Beschriftung als HTML (Prozent der viewBox), damit sie das Label-Token erbt
const pos = (x, y) => `left:${x / 10}%;top:${y / 6.8}%`;
let t = '';
for (let i = 0; i <= N; i++) t += `<span class="lbl achse" style="${pos(X0 + i * ACHSE, 44)}">${i + 1}</span>`;
KOTEN.forEach(([y, wert, name], k) => { t += `<span class="lbl kote${k % 2 ? ' klein' : ''}" style="${pos(X1 + 56, y - 3)}">${wert}<br><span class="leise">${name}</span></span>`; });
for (let i = 0; i < N; i++) t += `<span class="lbl mass${i % 2 ? ' klein' : ''}" style="${pos(X0 + i * ACHSE + ACHSE / 2, MY + 8)}">6,40</span>`;
t += `<span class="lbl mass" style="${pos((X0 + X1) / 2, MY2 + 8)}">44,80</span>`;
z.innerHTML = s + t;
/* ---------- Umschalten ---------- */
let stil = 'standard', zeigen = false;
function anzeigen() {
const v = STIL[stil];
token.innerHTML = `font: ${v.w} <b>${v.g}</b> '${v.f}'; letter-spacing: <b>${v.l}</b>; text-transform: uppercase;`;
}
function setzeStil(neu) {
stil = neu; buehne.dataset.stil = neu;
stilKnoepfe.forEach(k => k.setAttribute('aria-pressed', String(k.dataset.stilKnopf === neu)));
anzeigen();
}
function setzeZeigen(an) {
zeigen = an; buehne.dataset.zeigen = an ? 'ja' : 'nein';
zeigenKnopf.setAttribute('aria-pressed', String(an));
}
stilKnoepfe.forEach(k => k.addEventListener('click', () => { pause(); setzeStil(k.dataset.stilKnopf); }));
zeigenKnopf.addEventListener('click', () => { pause(); setzeZeigen(!zeigen); });
anzeigen();
/* ---------- Vorführung: Labels zeigen, dann Gegenproben und Varianten ---------- */
const FOLGE = [
['standard', true], ['standard', false], ['grotesk', false], ['standard', false],
['eng', false], ['standard', false], ['klein', false], ['kraeftig', false]
];
const TAKT = 2200;
let uhr = null, schritt = 0;
function takt() {
const [st, an] = FOLGE[schritt % FOLGE.length];
setzeStil(st); setzeZeigen(an);
schritt++;
uhr = setTimeout(takt, TAKT);
}
function neustart() { pause(); schritt = 0; setzeStil('standard'); setzeZeigen(false); }
function vorfuehren() { neustart(); html.classList.add('vorfuehrung'); uhr = setTimeout(takt, reduziert() ? 600 : 900); }
function pause() { clearTimeout(uhr); uhr = null; }
function weiter() { if (!uhr && html.classList.contains('vorfuehrung')) uhr = setTimeout(takt, 600); }
})();
</script>
</body>
</html>