Deutscher Satz für Zahlen, Datum, Telefon und Preise
Festpreis-Tafel einer Schwerter Kfz-Werkstatt, umschaltbar zwischen Rohsatz aus einer englischen Vorlage und deutschem Satz: jede Korrektur an Preis, Spanne, Uhrzeit, Telefon, Datum und Einheit ist markiert und erklärt.
Preisliste, Öffnungszeiten und Kontaktblock einer Werkstatt, Praxis oder eines Salons; zeigt dem Kunden, warum die Zahlen so stehen.
Zahlen sind auf KMU-Seiten der Inhalt: Preise, Öffnungszeiten, Termine, Telefon, Flächen. Das Muster setzt sie nach deutschen Regeln. Datum als „4. November 2026“ oder „04.11.2026“, Uhrzeit „8:30 Uhr“, Spannen mit Halbgeviertstrich („8–18 Uhr“, „Mo–Fr“), Telefon nach DIN 5008 („02304 09471-12“, international „+49 2304 09471-12“), Preise als „1.299,00 €“, Einheiten mit geschütztem Leerzeichen („12 m²“, „19 %“). Dazu tabular-nums für Spalten und kleine Helfer mit Intl.NumberFormat und Intl.DateTimeFormat, damit generierte Inhalte gleich richtig herauskommen.
Falsch gesetzte Zahlen verraten eine Vorlage aus dem Englischen sofort: „€1,299.00“, „04/11/2026“, „8:00-18:00“, „(0 23 04) 9 47 1“. Richtig gesetzte Zahlen lesen sich ruhig, brechen nicht mitten im Preis um und lassen sich antippen. Wer den deutschen Satz beherrscht, wirkt wie ein Betrieb aus der Region.
Wann einsetzen
Auf jeder deutschen Seite mit Preisen, Zeiten, Daten oder Telefonnummern. Pflicht für Preislisten, Öffnungszeiten, Terminbestätigungen, Kontaktblöcke, Impressum, Datenblätter und alles, was ein Generator aus Daten füllt.
Wann nicht
Nicht für fremdsprachige Seiten: dort das Locale der Sprache nehmen. Nicht DIN 5008 und typografischen Satz mischen: eine Regel je Seite wählen (siehe Varianten) und durchhalten. Preisangaben und Pflichtangaben (Endpreis, Grundpreis) sind Rechtsfragen: vom Kunden prüfen lassen, keine Rechtsberatung.
Varianten
- Tafel: Festpreise, Öffnungszeiten und Kontakt mit Umschalter Rohsatz / deutscher Satz, jede Korrektur markiert
- Formatierer: Eingabe von Betrag, Datum und Telefon, Ausgabe in deutschem Satz samt tel:-Link und Code
- Termine: Terminliste mit Wochentag, Datum, Uhrzeitspanne und relativer Angabe („in 2 Tagen“) in Tabellenziffern
Umsetzung
- Eine Regel wählen: typografisch (Duden: „8–18 Uhr“ ohne Leerzeichen) für Werbeseiten, DIN 5008 („8 – 18 Uhr“) nur, wenn der Kunde Geschäftsbriefe so setzt.
- Zeichen: Halbgeviertstrich U+2013 für Spannen, U+00A0 zwischen Zahl und Einheit, Zahl und €, Tag und Monat („4. November“), U+202F (schmales geschütztes Leerzeichen) in Abkürzungen („z. B.“) und vor Einheiten in engen Tabellen, U+2011 für Bindestriche, die nicht umbrechen sollen.
- Preise mit Intl.NumberFormat('de-DE', {style: 'currency', currency: 'EUR'}) (liefert „1.299,00 €“ mit U+00A0). Ganze Euro ohne Nachkommastellen nur, wenn alle Preise der Liste ganz sind.
- Datum mit Intl.DateTimeFormat('de-DE', {day: 'numeric', month: 'long', year: 'numeric'}) und im HTML <time datetime="2026-11-04">. Relative Angaben mit Intl.RelativeTimeFormat('de', {numeric: 'auto'}) („morgen“).
- Telefon: sichtbar nach DIN 5008 (Vorwahl, Leerzeichen, Nummer, Bindestrich, Durchwahl), im href als E.164 ohne Leerzeichen (tel:+4923040947112). Die Länge der Vorwahl steht in den Daten, Intl kann Telefonnummern nicht formatieren.
font-variant-numeric: tabular-nums in Tabellen, Preislisten und Zeiten; proportionale Ziffern im Fließtext.- Demo- und Vorlagennummern: Vorwahl plus führende 0 oder die Nummernblöcke der Bundesnetzagentur, nie echte Nummern.
Robust umsetzen
Telefon. Telefonnummern als tel:-Link mit großer Trefferfläche. Preise und Zeiten brechen nie zwischen Zahl und Einheit um (geschützte Leerzeichen). Tabellen bleiben einspaltig lesbar, Ziffern stehen untereinander.
Ohne Bewegung. Markierungen und Wechsel zwischen Roh- und deutschem Satz erscheinen ohne Übergang.
Barrierefrei. Screenreader lesen „8–18 Uhr“ als „8 bis 18 Uhr“, „€“ als „Euro“. Datum im <time>-Element mit datetime. Telefon-Links haben einen sichtbaren Text mit der Nummer, kein „Hier anrufen“. Keine Ziffern als Bild. Spalten mit tabular-nums erleichtern den Vergleich für alle.
Code
<!DOCTYPE html>
<!--
Deutscher Satz für Zahlen, Datum, Telefon und Preise
Fundus · Typo-Techniken · https://cecodesign.de/lab/fundus/typo-techniken/zahlen-datum-telefon-satz/
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>Deutscher Satz für Zahlen, Datum, Telefon und Preise · 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: 'Mona Sans'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/mona-sans:vf@latest/latin-wdth-normal.woff2') format('woff2-variations'); font-weight: 200 900; font-stretch: 75% 125%; font-display: swap; }
@font-face { font-family: 'Google Sans Flex'; src: url('https://cdn.jsdelivr.net/fontsource/fonts/google-sans-flex:vf@latest/latin-wght-normal.woff2') format('woff2-variations'); font-weight: 100 1000; 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; }
/* Rezept kfz-werkstatt-autohaus: Betongrau, Asphalt, Verkehrsgelb nur für die Handlung */
:root {
--grund: #F2F1ED; --text: #121314; --leise: #595E63; --asphalt: #232629; --asphalt-leise: #B9BEC4;
--gelb: #F5B700; --gruen: #1F7A3E; --rot: #B3261E; --linie: #CECDCA; --linie-dunkel: rgba(255, 255, 255, .14);
--schrift-headline: 'Mona Sans', system-ui, sans-serif;
--schrift-text: 'Google Sans Flex', system-ui, sans-serif;
--auf: cubic-bezier(0.16, 1, 0.3, 1); /* token-toggle-asymmetrisch: öffnen */
--zu: cubic-bezier(0.7, 0, 0.84, 0); /* schließen */
--t-auf: 250ms; --t-zu: 170ms; --t-hover: 120ms;
}
* { box-sizing: border-box; margin: 0; }
html { background: var(--grund); color: var(--text); font-family: var(--schrift-text); -webkit-font-smoothing: antialiased; }
:root:has(:focus-visible) { scroll-behavior: auto; }
html { scroll-padding-bottom: 96px; } /* Fokus nicht unter dem Pult */
body { min-height: 100svh; }
:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }
.dunkel :focus-visible { outline-color: var(--gelb); }
.label { font: 500 11px/1.3 'Geist Mono', ui-monospace, monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--leise); }
.dunkel .label { color: var(--asphalt-leise); }
.ziffern { font-variant-numeric: tabular-nums; }
/* ——— Kopf ——— */
.kopf { background: var(--asphalt); color: #fff; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px 24px; padding: 14px clamp(16px, 3vw, 40px); }
.marke { display: flex; align-items: baseline; gap: 12px; color: inherit; text-decoration: none; }
.marke b { font: 800 26px/1 var(--schrift-headline); font-stretch: 80%; letter-spacing: -.02em; }
.marke span { color: var(--asphalt-leise); font-size: 14px; }
.kopf-tel { color: #fff; text-decoration: none; font: 700 17px/1 var(--schrift-headline); font-stretch: 85%; font-variant-numeric: tabular-nums; padding: 10px 14px; border-radius: 4px; border: 1px solid var(--linie-dunkel); transition: background-color var(--t-hover) var(--auf); }
.kopf-tel:hover { background: rgba(255, 255, 255, .08); }
.kopf-tel small { font: 500 10.5px/1 'Geist Mono', monospace; letter-spacing: .12em; text-transform: uppercase; color: var(--asphalt-leise); margin-right: 8px; }
main { padding: clamp(22px, 3.4vw, 44px) clamp(16px, 3vw, 40px) 100px; max-width: 1320px; margin-inline: auto; }
.einstieg { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px 40px; align-items: end; margin-bottom: clamp(20px, 3vw, 34px); }
@media (min-width: 900px) { .einstieg { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); } }
h1 { font: 800 clamp(2.25rem, 1.4rem + 3vw, 3.75rem)/.98 var(--schrift-headline); font-stretch: 80%; letter-spacing: -.02em; text-wrap: balance; }
.einstieg p:not(.label) { margin-top: 12px; font-size: 1.0625rem; line-height: 1.55; color: var(--leise); max-width: 52ch; text-wrap: pretty; }
/* Satz-Schalter */
.schalter-reihe { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; justify-content: flex-start; }
@media (min-width: 900px) { .schalter-reihe { justify-content: flex-end; } }
.segment { display: inline-flex; padding: 4px; border-radius: 6px; background: #E4E3DE; gap: 2px; }
.segment button { font: 600 14px/1 var(--schrift-text); color: var(--text); background: transparent; border: 0; border-radius: 4px; padding: 11px 14px; cursor: pointer; transition: background-color var(--t-hover) var(--auf), color var(--t-hover) var(--auf); }
.segment button:hover { background: rgba(18, 19, 20, .06); }
.segment button[aria-pressed="true"] { background: var(--asphalt); color: #fff; }
.segment button[aria-pressed="true"].gelb { background: var(--gelb); color: var(--text); box-shadow: inset 0 0 0 2px var(--asphalt); }
.segment[aria-disabled="true"] { opacity: .5; }
.segment[aria-disabled="true"] button { cursor: not-allowed; }
/* ——— Tafel ——— */
.tafel { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
@media (min-width: 980px) { .tafel { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); } }
.flaeche { border-radius: 8px; padding: clamp(18px, 2.4vw, 28px); }
.dunkel { background: var(--asphalt); color: #fff; }
.hell { background: #fff; border: 1px solid var(--linie); }
.flaeche h2 { font: 750 clamp(1.5rem, 1.1rem + 1.4vw, 2.125rem)/1 var(--schrift-headline); font-stretch: 85%; letter-spacing: -.015em; margin: 6px 0 16px; }
table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
caption { text-align: left; }
th, td { padding: 12px 8px; text-align: right; vertical-align: baseline; border-bottom: 1px solid var(--linie-dunkel); }
th:first-child, td:first-child { text-align: left; padding-left: 0; }
th:last-child, td:last-child { padding-right: 0; }
thead th { font: 500 11px/1.3 'Geist Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--asphalt-leise); font-weight: 500; }
tbody th { font-weight: 600; font-size: 1rem; }
tbody th small { display: block; font-weight: 400; color: var(--asphalt-leise); font-size: .875rem; margin-top: 3px; }
td { font: 700 1.25rem/1 var(--schrift-headline); font-stretch: 85%; white-space: nowrap; }
.fuss { margin-top: 14px; font-size: .9375rem; color: var(--asphalt-leise); line-height: 1.5; }
@media (max-width: 620px) {
table, tbody, tr, th, td { display: block; }
thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
tbody tr { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px 8px; padding: 12px 0; border-bottom: 1px solid var(--linie-dunkel); }
tbody th { grid-column: 1 / -1; border: 0; padding: 0 0 6px; }
td { border: 0; padding: 0; text-align: left; font-size: 1.0625rem; }
td::before { content: attr(data-klasse); display: block; font: 500 10px/1.3 'Geist Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--asphalt-leise); margin-bottom: 4px; }
}
.zeiten { list-style: none; padding: 0; display: grid; gap: 0; font-variant-numeric: tabular-nums; }
.zeiten li { display: flex; justify-content: space-between; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--linie); font-size: 1.0625rem; }
.zeiten li b { font-weight: 600; }
.kontakt { margin-top: 20px; display: grid; gap: 10px; }
.tel { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; text-decoration: none; color: var(--text); background: var(--gelb); border-radius: 4px; padding: 14px 16px; box-shadow: inset 0 0 0 2px var(--asphalt); font: 750 1.375rem/1 var(--schrift-headline); font-stretch: 85%; font-variant-numeric: tabular-nums; transition: transform var(--t-hover) var(--auf); }
.tel:hover { transform: translateY(-1px); }
.tel:active { transform: translateY(2px); }
.tel small { font: 500 11px/1.2 'Geist Mono', monospace; letter-spacing: .1em; text-transform: uppercase; }
.fakten { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 4px; }
.fakt { border: 1px solid var(--linie); border-radius: 4px; padding: 12px; }
.fakt b { display: block; font: 750 1.5rem/1 var(--schrift-headline); font-stretch: 85%; font-variant-numeric: tabular-nums; margin-top: 6px; }
.hell .klein { font-size: .9375rem; line-height: 1.5; color: var(--leise); margin-top: 12px; }
/* Markierte Korrekturen */
.k { position: relative; border-radius: 2px; transition: background-color var(--t-zu) var(--zu); }
.k::after { content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 3px; border-radius: 2px; background: var(--gelb); transform: scaleX(0); transform-origin: left; transition: transform var(--t-zu) var(--zu); }
.gut .k::after { transform: scaleX(1); transition: transform var(--t-auf) var(--auf); transition-delay: calc(var(--i, 0) * 40ms); }
.roh .k::after { background: var(--rot); transform: scaleX(1); height: 2px; bottom: -2px; transition: transform var(--t-auf) var(--auf); }
.k[data-hell] { background: rgba(245, 183, 0, .32); transition: background-color var(--t-auf) var(--auf); }
.dunkel .k[data-hell] { background: rgba(245, 183, 0, .3); }
.k sup { font: 600 9.5px/1 'Geist Mono', monospace; vertical-align: super; margin-left: 2px; color: inherit; opacity: .7; }
/* Legende */
.legende { margin-top: 16px; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 8px; list-style: none; padding: 0; }
.legende button { width: 100%; text-align: left; display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 10px; align-items: start; background: #fff; border: 1px solid var(--linie); border-radius: 6px; padding: 12px; cursor: pointer; font: inherit; color: inherit; transition: border-color var(--t-hover) var(--auf), background-color var(--t-hover) var(--auf); }
.legende button:hover, .legende button[aria-pressed="true"] { border-color: var(--asphalt); background: #FBFAF6; }
.legende .n { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; background: var(--gelb); color: var(--text) !important; margin: 0 !important; font: 700 12px/1 'Geist Mono', monospace; box-shadow: inset 0 0 0 1.5px var(--asphalt); }
.legende b { display: block; font-weight: 650; font-size: .9375rem; }
.legende span { display: block; font-size: .875rem; line-height: 1.45; color: var(--leise); margin-top: 3px; }
.legende code { font: 400 12px/1.4 'Geist Mono', monospace; color: var(--text); overflow-wrap: anywhere; }
/* ——— Formatierer ——— */
.werkbank { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
@media (min-width: 980px) { .werkbank { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } }
.feld { display: grid; gap: 6px; margin-bottom: 16px; }
.feld label { font-weight: 600; font-size: .9375rem; }
.feld .hilfe { font-size: .8125rem; color: var(--leise); }
.zeile { display: grid; gap: 8px; grid-template-columns: minmax(0, 1fr); }
.zeile.tel3 { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr) minmax(0, 3fr); }
.zeile.zwei { grid-template-columns: repeat(2, minmax(0, 1fr)); }
input, select { font: 500 1.0625rem/1.2 var(--schrift-text); color: var(--text); background: #fff; border: 1.5px solid #8A8F94; border-radius: 4px; padding: 11px 12px; min-width: 0; width: 100%; font-variant-numeric: tabular-nums; }
input:focus-visible, select:focus-visible { outline: 2px solid var(--text); outline-offset: 1px; border-color: var(--text); }
input[aria-invalid="true"] { border-color: var(--rot); }
.fehler { color: var(--rot); font-size: .875rem; font-weight: 600; }
.fehler:empty { display: none; }
.ausgabe { display: grid; gap: 0; }
.ausgabe > div { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; padding: 14px 0; border-bottom: 1px solid var(--linie-dunkel); }
.ausgabe .wert { font: 750 1.625rem/1.1 var(--schrift-headline); font-stretch: 85%; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.ausgabe .wert a { color: #fff; text-decoration-color: var(--gelb); text-underline-offset: 4px; }
.ausgabe .leer { color: var(--asphalt-leise); font: 400 1rem/1.3 var(--schrift-text); }
.ausgabe code { font: 400 12px/1.5 'Geist Mono', monospace; color: var(--asphalt-leise); overflow-wrap: anywhere; }
.zeichen { display: flex; flex-wrap: wrap; gap: 3px; margin-top: 2px; }
.zeichen span { font: 500 11px/1 'Geist Mono', monospace; padding: 4px 5px; border-radius: 3px; background: rgba(255, 255, 255, .08); color: #fff; }
.zeichen span.sp { background: var(--gelb); color: var(--text); }
/* ——— Termine ——— */
.termine { list-style: none; padding: 0; font-variant-numeric: tabular-nums; }
.termine li { display: grid; grid-template-columns: 3.2em minmax(0, 6.5em) minmax(0, 1fr) minmax(0, 8em) auto; gap: 8px 16px; align-items: baseline; padding: 14px 0; border-bottom: 1px solid var(--linie-dunkel); font-size: 1.0625rem; }
.termine .tag { font: 750 1.375rem/1 var(--schrift-headline); font-stretch: 80%; }
.termine .rel { color: var(--asphalt-leise); font-size: .9375rem; }
.termine .status { font: 600 12px/1 var(--schrift-text); padding: 6px 9px; border-radius: 3px; background: var(--gruen); color: #fff; }
.termine .status.belegt { background: transparent; color: var(--asphalt-leise); box-shadow: inset 0 0 0 1px var(--linie-dunkel); }
@media (max-width: 620px) { .termine li { grid-template-columns: 3em minmax(0, 1fr) auto; } .termine .tag { grid-row: 1 / 3; } .termine time { grid-column: 2; grid-row: 1; } .termine .status { grid-column: 3; grid-row: 1; justify-self: end; } .termine li > .ziffern { grid-column: 2; grid-row: 2; } .termine .rel { grid-column: 3; grid-row: 2; text-align: right; } }
.knopf-gelb { display: inline-flex; margin-top: 18px; background: var(--gelb); color: var(--text); font: 700 1rem/1 var(--schrift-text); padding: 14px 18px; border-radius: 4px; text-decoration: none; box-shadow: 0 4px 0 #8C6A00; transition: transform var(--t-hover) var(--auf), box-shadow var(--t-hover) var(--auf); }
.knopf-gelb:active { transform: translateY(4px); box-shadow: 0 0 0 #8C6A00; }
[hidden] { display: none !important; }
/* Pult */
.pult { position: fixed; right: 16px; bottom: 16px; z-index: 30; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: 5px; border-radius: 6px; background: var(--asphalt); box-shadow: 0 10px 30px rgba(0, 0, 0, .25); }
.pult .label { color: var(--asphalt-leise); padding: 0 8px 0 10px; }
.pult button { font: 500 11px/1 'Geist Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: #fff; background: transparent; border: 0; border-radius: 4px; padding: 9px 11px; cursor: pointer; transition: background-color var(--t-hover) var(--auf); }
.pult button:hover { background: rgba(255, 255, 255, .1); }
.pult button[aria-pressed="true"] { background: var(--gelb); color: var(--text); }
.pult button:focus-visible { outline: 2px solid var(--gelb); outline-offset: 2px; }
.vorschau body { overflow: hidden; }
.vorschau .einstieg p, .vorschau .legende, .vorschau .kopf-tel small { display: none; }
.vorschau main { padding-top: 20px; }
:root.reduziert * { transition-duration: .01ms !important; transition-delay: 0s !important; animation-duration: .01ms !important; }
@media (hover: none) { .legende button { padding-block: 14px; } }
@media (max-width: 360px) { .pult .label { display: none; } .zeile.tel3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
@media (forced-colors: active) {
button, [role=button], [role=tab], [role=switch], input, select, textarea { border: 1px solid ButtonText !important; }
.k::after { background: Highlight; }
}
</style>
</head>
<body>
<header class="kopf">
<a class="marke" href="#inhalt"><b>Kolbenring</b><span>Kfz-Meisterbetrieb in Schwerte</span></a>
<a class="kopf-tel" href="tel:+4923040947112" data-tel><small>Annahme</small><span class="ziffern" id="kopf-nummer">02304 09471-12</span></a>
</header>
<main id="inhalt">
<div class="einstieg">
<div>
<p class="label" id="v-label">Typo-Technik · Zahlensatz</p>
<h1 id="v-titel">Preise, Zeiten und Telefon, deutsch gesetzt.</h1>
<p id="v-text">Links der Rohsatz aus einer englischen Vorlage, rechts dieselben Daten nach deutschen Regeln. Jede Korrektur ist markiert und in der Legende erklärt.</p>
</div>
<div class="schalter-reihe" id="schalter">
<div class="segment" role="group" aria-label="Satz">
<button type="button" data-satz="roh" aria-pressed="false">Rohsatz</button>
<button type="button" class="gelb" data-satz="gut" aria-pressed="true">Deutscher Satz</button>
</div>
<div class="segment" role="group" aria-label="Regelwerk für Spannen und Uhrzeiten" id="regelwerk">
<button type="button" data-regel="duden" aria-pressed="true">Typografisch</button>
<button type="button" data-regel="din" aria-pressed="false">DIN 5008</button>
</div>
</div>
</div>
<!-- Variante tafel -->
<section id="v-tafel" aria-label="Festpreise und Kontakt">
<div class="tafel gut" id="tafel">
<div class="flaeche dunkel">
<p class="label">Festpreise · Endpreise</p>
<h2>Was es kostet</h2>
<table>
<caption class="label" style="margin-bottom:6px">Preise je Fahrzeugklasse</caption>
<thead><tr><th scope="col">Leistung</th><th scope="col">Kleinwagen</th><th scope="col">Mittelklasse</th><th scope="col">Transporter</th></tr></thead>
<tbody id="preise"></tbody>
</table>
<p class="fuss" id="preis-fuss"></p>
</div>
<div class="flaeche hell">
<p class="label">Werkstatt · Annahme</p>
<h2>Wann Sie kommen können</h2>
<ul class="zeiten" id="zeiten"></ul>
<div class="kontakt">
<a class="tel" href="tel:+4923040947112" data-tel><small>Annahme direkt</small><span id="tel-nummer"></span></a>
<div class="fakten">
<div class="fakt"><span class="label">Halle</span><b id="fakt-halle"></b></div>
<div class="fakt"><span class="label">Ersatzwagen</span><b id="fakt-wagen"></b></div>
</div>
<p class="klein" id="kontakt-satz"></p>
</div>
</div>
</div>
<ul class="legende" id="legende" aria-label="Regeln der Korrekturen"></ul>
</section>
<!-- Variante formatierer -->
<section id="v-formatierer" hidden aria-label="Formatierer">
<div class="werkbank">
<form class="flaeche hell" id="form" novalidate>
<p class="label">Eingabe</p>
<h2>Daten eingeben</h2>
<div class="feld"><label for="f-betrag">Betrag in Euro</label><input id="f-betrag" inputmode="decimal" autocomplete="off" value="1149" aria-describedby="h-betrag e-betrag"><span class="hilfe" id="h-betrag">z. B. 1149 oder 1.149,5</span><span class="fehler" id="e-betrag" aria-live="polite"></span></div>
<div class="feld"><label for="f-datum">Datum</label><input id="f-datum" type="date" value="2026-11-04" aria-describedby="h-datum"><span class="hilfe" id="h-datum">Datum und Uhrzeit zeigt das Feld im Format des Browsers, die Ausgabe ist immer de-DE.</span></div>
<div class="feld"><span id="l-zeit" style="font-weight:600;font-size:.9375rem">Uhrzeit von und bis</span><div class="zeile zwei"><input id="f-von" type="time" value="07:30" aria-labelledby="l-zeit" aria-label="von"><input id="f-bis" type="time" value="18:00" aria-label="bis"></div><span class="fehler" id="e-zeit" aria-live="polite"></span></div>
<div class="feld"><span id="l-tel" style="font-weight:600;font-size:.9375rem">Telefon: Vorwahl, Rufnummer, Durchwahl</span><div class="zeile tel3"><input id="f-vorwahl" inputmode="numeric" value="02304" aria-label="Vorwahl"><input id="f-nummer" inputmode="numeric" value="09471" aria-label="Rufnummer"><input id="f-durchwahl" inputmode="numeric" value="12" aria-label="Durchwahl, optional"></div><span class="hilfe">Demo-Nummer: Vorwahl plus führende 0 (Regel der Bundesnetzagentur)</span><span class="fehler" id="e-tel" aria-live="polite"></span></div>
<div class="feld"><label for="f-menge">Menge und Einheit</label><div class="zeile zwei"><input id="f-menge" inputmode="decimal" value="250" aria-describedby="e-menge"><select id="f-einheit" aria-label="Einheit"><option value="m²">m²</option><option value="l">l</option><option value="km">km</option><option value="%">%</option><option value="kg">kg</option></select></div><span class="fehler" id="e-menge" aria-live="polite"></span></div>
</form>
<div class="flaeche dunkel">
<p class="label">Ausgabe · de-DE</p>
<h2>So steht es auf der Seite</h2>
<div class="ausgabe" id="ausgabe" aria-live="polite"></div>
</div>
</div>
</section>
<!-- Variante termine -->
<section id="v-termine" hidden aria-label="Freie Termine">
<div class="tafel gut" id="termin-tafel">
<div class="flaeche dunkel">
<p class="label">Inspektion · nächste Werktage</p>
<h2>Freie Termine</h2>
<ul class="termine" id="termine"></ul>
<a class="knopf-gelb" href="#termin">Termin buchen</a>
</div>
<div class="flaeche hell">
<p class="label">Abgabe und Abholung</p>
<h2>Ablauf am Tag</h2>
<ul class="zeiten" id="ablauf"></ul>
<p class="klein" id="termin-satz"></p>
</div>
</div>
<ul class="legende" id="legende-t" aria-label="Regeln der Korrekturen"></ul>
</section>
</main>
<nav class="pult" aria-label="Variante wählen">
<span class="label">Variante</span>
<button type="button" data-v="tafel" aria-pressed="true">Tafel</button>
<button type="button" data-v="formatierer" aria-pressed="false">Formatierer</button>
<button type="button" data-v="termine" aria-pressed="false">Termine</button>
</nav>
<script>
(() => {
const H = document.documentElement;
const reduziert = () => H.classList.contains('reduziert');
const $ = s => document.querySelector(s);
const NB = ' ', SCHMAL = ' ', BIS = '–';
/* ——— Helfer, wie sie in ein Projekt gehören ——— */
const euro = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
const zahl = new Intl.NumberFormat('de-DE', { maximumFractionDigits: 2 });
const datumLang = new Intl.DateTimeFormat('de-DE', { day: 'numeric', month: 'long', year: 'numeric' });
const datumKurz = new Intl.DateTimeFormat('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
const tagKurz = new Intl.DateTimeFormat('de-DE', { weekday: 'short' });
const tagMonat = new Intl.DateTimeFormat('de-DE', { day: 'numeric', month: 'short' });
const relativ = new Intl.RelativeTimeFormat('de', { numeric: 'auto' });
/* Uhrzeit: typografisch „7:30“, volle Stunde „18“; DIN 5008 „07:30“, „18:00“ */
const uhr = (h, m, din) => din ? `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}` : (m ? `${h}:${String(m).padStart(2, '0')}` : `${h}`);
/* U+2060 (Wortverbinder) um den Strich: Spannen brechen nicht nach dem Strich um */
const spanne = (a, b, din) => din ? `${a}${NB}${BIS} ${b}` : `${a}\u2060${BIS}\u2060${b}`;
const zeitSpanne = (h1, m1, h2, m2, din) => spanne(uhr(h1, m1, din), uhr(h2, m2, din), din) + NB + 'Uhr';
/* Telefon DIN 5008: Vorwahl Leerzeichen Rufnummer Bindestrich Durchwahl; href E.164 */
const telText = (v, n, d, intl) => (intl ? '+49' + NB + v.replace(/^0/, '') : v) + NB + n + (d ? '‑' + d : '');
const telHref = (v, n, d) => 'tel:+49' + v.replace(/^0/, '') + n + (d || '');
let satz = 'gut', din = false;
const v0 = new URLSearchParams(location.search).get('v');
let variante = ['tafel', 'formatierer', 'termine'].includes(v0) ? v0 : 'tafel';
/* ——— Regeln der Legende ——— */
const REGELN = [
['Preis', 'Betrag, geschütztes Leerzeichen, €. Komma für Cent, Punkt für Tausender.', "Intl.NumberFormat('de-DE', {style: 'currency', currency: 'EUR'})"],
['Spanne', () => din ? 'DIN 5008: Halbgeviertstrich mit Leerzeichen („07:30 – 18:00 Uhr“).' : 'Duden: Halbgeviertstrich ohne Leerzeichen („7:30–18 Uhr“, „Mo–Fr“). Ein Wortverbinder verhindert den Umbruch am Strich.', 'U+2013 · U+2060'],
['Uhrzeit', () => din ? 'DIN 5008: Doppelpunkt, zweistellig, mit „Uhr“ („07:30 Uhr“).' : 'Doppelpunkt und „Uhr“, volle Stunde ohne „:00“.', '7:30 Uhr · 18 Uhr'],
['Telefon', 'DIN 5008: Vorwahl, Leerzeichen, Rufnummer ungegliedert, Bindestrich vor der Durchwahl. Im Link E.164.', 'tel:+4923040947112'],
['Datum', '„4. November 2026“ oder „04.11.2026“, nie „04. November“ und nie „11/04“.', "Intl.DateTimeFormat('de-DE', {dateStyle: 'long'})"],
['Einheit', 'Zahl, geschütztes Leerzeichen, Einheit. m² statt qm, „19 %“ mit Leerzeichen.', 'U+00A0'],
['Abkürzung', 'Schmales geschütztes Leerzeichen in „z. B.“, „u. a.“, „inkl.“ ohne Leerzeichen.', 'U+202F']
];
/* Markierte Stelle: n = Regelnummer */
let zaehler = 0;
const k = (n, gut, roh) => satz === 'roh'
? `<span class="k" data-r="${n}">${roh}</span>`
: `<span class="k" data-r="${n}" style="--i:${zaehler++}">${gut}<sup aria-hidden="true">${n}</sup></span>`;
/* ——— Tafel ——— */
const PREISE = [
['Ölwechsel', [4.5, 5.5, 7], [89, 109, 139]],
['Räderwechsel', 'inkl. Auswuchten und Einlagerung', [39, 39, 59]],
['Hauptuntersuchung mit AU', 'Prüfgebühr enthalten', [139, 139, 159]],
['Klimaservice', 'Kältemittel bis 500 g', [99, 119, 149]],
['Zahnriemen mit Wasserpumpe', 'für Modelle der Liste', [649, 789, 1149]]
];
const rohPreis = p => '€' + p.toLocaleString('en-US', { minimumFractionDigits: 2 });
function tafel() {
zaehler = 0;
const kl = ['Kleinwagen', 'Mittelklasse', 'Transporter'];
$('#preise').innerHTML = PREISE.map(([name, info, preise]) => {
const sub = Array.isArray(info)
? 'inkl. ' + info.map(l => k(6, zahl.format(l) + NB + 'l', l + 'l')).join(' / ') + ' Öl'
: info;
return `<tr><th scope="row">${name}<small>${sub}</small></th>${preise.map((p, i) => `<td data-klasse="${kl[i]}">${k(1, euro.format(p), rohPreis(p))}</td>`).join('')}</tr>`;
}).join('');
const stand = new Date(2026, 10, 4);
$('#preis-fuss').innerHTML = `Stand: ${k(5, datumLang.format(stand), '11/04/2026')} · Endpreise ${k(7, 'inkl.' + NB + k(6, '19' + NB + '%', '19%') + ' MwSt.', 'inkl 19% MwSt')} · ${k(7, 'z.' + SCHMAL + 'B.', 'z.B.')} HU ohne Nachprüfung`;
$('#zeiten').innerHTML = [
[spanne('Mo', 'Fr', din), 'Mo-Fr', zeitSpanne(7, 30, 18, 0, din), '7.30-18.00 Uhr'],
['Sa', 'Sa', zeitSpanne(8, 0, 12, 0, din), '08:00 - 12:00'],
['Reifen-Hotline', 'Reifen-Hotline', zeitSpanne(8, 0, 16, 30, din), '8 - 16:30h']
].map(([t, tr, z, zr]) => `<li><b>${k(2, t, tr)}</b><span class="ziffern">${k(3, z, zr)}</span></li>`).join('');
const nummer = k(4, telText('02304', '09471', '12'), '(0 23 04) 94 71 - 12');
$('#tel-nummer').innerHTML = nummer;
$('#fakt-halle').innerHTML = k(6, '250' + NB + 'm²', '250qm');
$('#fakt-wagen').innerHTML = k(1, euro.format(19).replace(',00', ',00'), '€19.00') + '<span style="font:500 13px var(--schrift-text);color:var(--leise)"> /Tag</span>';
$('#kontakt-satz').innerHTML = `Rückruf bei Anruf bis ${k(3, uhr(14, 0, din) + NB + 'Uhr', '2pm')} noch am selben Tag. International: ${k(4, telText('02304', '09471', '12', true), '+49 (0)2304 9471 12')}.`;
legende('#legende', [1, 2, 3, 4, 5, 6, 7]);
}
/* ——— Termine ——— */
function termine() {
zaehler = 0;
const heute = new Date(); heute.setHours(0, 0, 0, 0);
const liste = []; const d = new Date(heute);
const slots = [[8, 0, 9, 30], [10, 0, 11, 30], [13, 0, 14, 30]];
let n = 0;
while (liste.length < 5 && n < 20) {
d.setDate(d.getDate() + (n ? 1 : 0)); n++;
if (d.getDay() === 0 || d.getDay() === 6) continue;
const s = slots[liste.length % 3];
liste.push([new Date(d), s, liste.length === 1]);
}
$('#termine').innerHTML = liste.map(([t, s, belegt]) => {
const tage = Math.round((t - heute) / 864e5);
const iso = t.toISOString().slice(0, 10);
const tag = tagKurz.format(t).replace('.', '');
const dat = din ? datumKurz.format(t) : tagMonat.format(t);
const rohDat = `${t.getMonth() + 1}/${t.getDate()}`;
const rohZeit = `${(s[0] % 12) || 12}:${String(s[1]).padStart(2, '0')}AM-${(s[2] % 12) || 12}:${String(s[3]).padStart(2, '0')}${s[2] >= 12 ? 'PM' : 'AM'}`;
return `<li><span class="tag">${k(5, tag, t.toLocaleDateString('en-US', { weekday: 'short' }))}</span><time datetime="${iso}">${k(5, dat, rohDat)}</time><span class="ziffern">${k(3, zeitSpanne(s[0], s[1], s[2], s[3], din), rohZeit)}</span><span class="rel">${k(5, relativ.format(tage, 'day'), tage + ' days')}</span><span class="status${belegt ? ' belegt' : ''}">${belegt ? 'belegt' : 'frei'}</span></li>`;
}).join('');
$('#ablauf').innerHTML = [
['Abgabe', zeitSpanne(7, 0, 8, 0, din), '7-8am'],
['Rückruf mit Befund', 'bis ' + uhr(11, 0, din) + NB + 'Uhr', 'by 11am'],
['Abholung', 'ab ' + uhr(16, 30, din) + NB + 'Uhr', 'from 4:30pm']
].map(([a, z, r]) => `<li><b>${a}</b><span class="ziffern">${k(3, z, r)}</span></li>`).join('');
$('#termin-satz').innerHTML = `Inspektion ${k(1, 'ab' + NB + euro.format(189), 'from €189')}, der Endpreis hängt vom Wartungsplan ab. Fragen: ${k(4, telText('02304', '09471', '12'), '02304/947112')}.`;
legende('#legende-t', [1, 3, 4, 5]);
}
function legende(sel, nummern) {
const el = $(sel);
el.innerHTML = nummern.map(n => {
const [t, s, c] = REGELN[n - 1];
return `<li><button type="button" data-zeige="${n}" aria-pressed="false"><span class="n" aria-hidden="true">${n}</span><span><b>${t}</b><span>${typeof s === 'function' ? s() : s}</span><code>${c}</code></span></button></li>`;
}).join('');
}
function hebe(n) {
document.querySelectorAll('.k').forEach(x => x.toggleAttribute('data-hell', n && x.dataset.r === String(n)));
document.querySelectorAll('[data-zeige]').forEach(b => b.setAttribute('aria-pressed', b.dataset.zeige === String(n) ? 'true' : 'false'));
}
document.addEventListener('pointerover', e => { const b = e.target.closest('[data-zeige]'); if (b) hebe(b.dataset.zeige); });
document.addEventListener('pointerout', e => { const b = e.target.closest('[data-zeige]'); if (b && !b.contains(e.relatedTarget)) hebe(null); });
document.addEventListener('focusin', e => { const b = e.target.closest('[data-zeige]'); if (b) hebe(b.dataset.zeige); });
document.addEventListener('focusout', e => { if (e.target.closest('[data-zeige]')) hebe(null); });
document.addEventListener('click', e => { const b = e.target.closest('[data-zeige]'); if (b) { const an = b.getAttribute('aria-pressed') !== 'true'; hebe(an ? b.dataset.zeige : null); } });
/* ——— Formatierer ——— */
const zeichenListe = s => [...s].map(c => c === NB ? '<span class="sp" title="geschütztes Leerzeichen">U+00A0</span>' : c === SCHMAL ? '<span class="sp" title="schmales geschütztes Leerzeichen">U+202F</span>' : c === BIS ? '<span class="sp" title="Halbgeviertstrich">U+2013</span>' : c === '‑' ? '<span class="sp" title="geschützter Bindestrich">U+2011</span>' : c === '\u2060' ? '<span class="sp" title="Wortverbinder">U+2060</span>' : `<span>${c === ' ' ? '␠' : c}</span>`).join('');
function liesBetrag(s) {
s = s.trim().replace(/\s|€/g, '');
if (!s) return { leer: true };
if (/^\d{1,3}(\.\d{3})*(,\d{1,2})?$/.test(s) || /^\d+(,\d{1,2})?$/.test(s)) return { wert: +s.replace(/\./g, '').replace(',', '.') };
if (/^\d+(\.\d{1,2})?$/.test(s)) return { wert: +s, hinweis: 'Punkt als Dezimaltrenner erkannt.' };
return { fehler: 'Bitte nur Ziffern, Punkt und Komma, z. B. 1.149,50.' };
}
function formatierer() {
const out = [];
const b = liesBetrag($('#f-betrag').value);
$('#f-betrag').setAttribute('aria-invalid', b.fehler ? 'true' : 'false');
$('#e-betrag').textContent = b.fehler || '';
const zeile = (titel, wert, code) => `<div><span class="label">${titel}</span>${wert}${code ? `<code>${code}</code>` : ''}</div>`;
if (b.wert !== undefined) { const s = euro.format(b.wert); out.push(zeile('Preis', `<span class="wert">${s}</span><span class="zeichen">${zeichenListe(s)}</span>`, `euro.format(${b.wert})`)); }
else out.push(zeile('Preis', `<span class="leer">${b.fehler ? 'Eingabe prüfen' : 'Noch kein Betrag'}</span>`));
const dv = $('#f-datum').value;
if (dv) { const [y, m, d] = dv.split('-').map(Number); const dt = new Date(y, m - 1, d); const s = datumLang.format(dt);
out.push(zeile('Datum', `<span class="wert"><time datetime="${dv}">${s}</time></span><span class="zeichen">${zeichenListe(s)}</span>`, `<time datetime="${dv}"> · kurz ${datumKurz.format(dt)}`)); }
else out.push(zeile('Datum', '<span class="leer">Noch kein Datum</span>'));
const von = $('#f-von').value, bis = $('#f-bis').value;
$('#e-zeit').textContent = von && bis && bis <= von ? '„bis“ liegt vor „von“.' : '';
if (von && bis && bis > von) { const [h1, m1] = von.split(':').map(Number), [h2, m2] = bis.split(':').map(Number);
const s = zeitSpanne(h1, m1, h2, m2, false), sd = zeitSpanne(h1, m1, h2, m2, true);
out.push(zeile('Zeitspanne', `<span class="wert">${s}</span><span class="zeichen">${zeichenListe(s)}</span>`, `DIN 5008: ${sd}`)); }
else out.push(zeile('Zeitspanne', '<span class="leer">Von und bis eingeben</span>'));
const v = $('#f-vorwahl').value.replace(/\D/g, ''), n = $('#f-nummer').value.replace(/\D/g, ''), dw = $('#f-durchwahl').value.replace(/\D/g, '');
const telFehler = !v || !n ? '' : !/^0[1-9]\d{1,4}$/.test(v) ? 'Vorwahl beginnt mit 0 und hat 3 bis 6 Ziffern.' : '';
$('#e-tel').textContent = telFehler;
if (v && n && !telFehler) { const s = telText(v, n, dw), si = telText(v, n, dw, true), h = telHref(v, n, dw);
out.push(zeile('Telefon', `<span class="wert"><a href="${h}">${s}</a></span><span class="zeichen">${zeichenListe(s)}</span>`, `international ${si} · href="${h}"`)); }
else out.push(zeile('Telefon', `<span class="leer">${telFehler ? 'Eingabe prüfen' : 'Vorwahl und Rufnummer eingeben'}</span>`));
const mRoh = $('#f-menge').value.trim(), mWert = liesBetrag(mRoh), e = $('#f-einheit').value;
$('#e-menge').textContent = mWert.fehler ? 'Bitte eine Zahl, z. B. 4,5.' : '';
$('#f-menge').setAttribute('aria-invalid', mWert.fehler ? 'true' : 'false');
if (mWert.wert !== undefined) { const s = zahl.format(mWert.wert) + NB + e;
out.push(zeile('Menge', `<span class="wert">${s}</span><span class="zeichen">${zeichenListe(s)}</span>`, e === '%' ? "auch: Intl.NumberFormat('de-DE', {style: 'percent'})" : 'zahl.format(x) + "\\u00A0' + e + '"')); }
else out.push(zeile('Menge', '<span class="leer">Noch keine Menge</span>'));
$('#ausgabe').innerHTML = out.join('');
}
$('#form').addEventListener('input', formatierer);
$('#form').addEventListener('submit', e => e.preventDefault());
/* ——— Steuerung ——— */
function zeichne() {
if (variante === 'tafel') tafel();
if (variante === 'termine') termine();
if (variante === 'formatierer') formatierer();
['#tafel', '#termin-tafel'].forEach(s => { $(s).classList.toggle('gut', satz === 'gut'); $(s).classList.toggle('roh', satz === 'roh'); });
const kopf = $('#kopf-nummer'); kopf.textContent = satz === 'roh' ? '(0 23 04) 94 71 - 12' : telText('02304', '09471', '12');
}
function setzeSatz(s) {
satz = s;
document.querySelectorAll('[data-satz]').forEach(b => b.setAttribute('aria-pressed', b.dataset.satz === s ? 'true' : 'false'));
$('#regelwerk').setAttribute('aria-disabled', s === 'roh' ? 'true' : 'false');
/* Erst schließen (170 ms), dann neu setzen und öffnen */
document.querySelectorAll('.k').forEach(x => x.closest('.tafel') && x.closest('.tafel').classList.remove('gut'));
setTimeout(zeichne, reduziert() ? 0 : 170);
}
function setzeRegel(r) {
if (satz === 'roh') return;
din = r === 'din';
document.querySelectorAll('[data-regel]').forEach(b => b.setAttribute('aria-pressed', b.dataset.regel === r ? 'true' : 'false'));
zeichne();
}
const TEXTE = {
tafel: ['Typo-Technik · Zahlensatz', 'Preise, Zeiten und Telefon, deutsch gesetzt.', 'Rohsatz aus einer englischen Vorlage oder dieselben Daten nach deutschen Regeln. Jede Korrektur ist markiert und in der Legende erklärt.'],
formatierer: ['Typo-Technik · Intl-Helfer', 'Eingeben, deutsch gesetzt herausbekommen.', 'Die Ausgabe nutzt Intl.NumberFormat und Intl.DateTimeFormat. Telefon formatiert ein kleiner Helfer nach DIN 5008, weil Intl das nicht kann. Gelb markiert: geschützte und besondere Zeichen.'],
termine: ['Typo-Technik · Termine', 'Termine mit Wochentag, Datum und Spanne.', 'Die Liste rechnet ab heute. Relative Angaben kommen aus Intl.RelativeTimeFormat, alle Ziffern stehen in Tabellenziffern untereinander.']
};
function setzeVariante(v, still) {
variante = v;
['tafel', 'formatierer', 'termine'].forEach(x => { $('#v-' + x).hidden = x !== v; });
$('#schalter').hidden = v === 'formatierer';
const [l, t, p] = TEXTE[v]; $('#v-label').textContent = l; $('#v-titel').textContent = t; $('#v-text').textContent = p;
document.querySelectorAll('.pult button').forEach(b => b.setAttribute('aria-pressed', b.dataset.v === v ? 'true' : 'false'));
if (!still) { const q = new URLSearchParams(location.search); q.set('v', v); history.replaceState(null, '', '?' + q.toString()); }
zeichne();
}
document.querySelectorAll('[data-satz]').forEach(b => b.addEventListener('click', () => { pause(); setzeSatz(b.dataset.satz); }));
document.querySelectorAll('[data-regel]').forEach(b => b.addEventListener('click', () => { pause(); setzeRegel(b.dataset.regel); }));
document.querySelectorAll('.pult button').forEach(b => b.addEventListener('click', () => { pause(); setzeVariante(b.dataset.v); }));
/* ——— Vorführung ——— */
let lauf = null;
function neustart() { clearTimeout(lauf); din = false; setzeRegel('duden'); setzeSatz('gut'); hebe(null); }
function vorfuehren() {
clearTimeout(lauf);
const schritte = variante === 'formatierer'
? [() => { $('#f-betrag').value = '89'; formatierer(); }, () => { $('#f-betrag').value = '1149,5'; formatierer(); }, () => { $('#f-durchwahl').value = ''; formatierer(); }, () => { $('#f-durchwahl').value = '12'; $('#f-einheit').value = '%'; $('#f-menge').value = '19'; formatierer(); }, () => { $('#f-einheit').value = 'm²'; $('#f-menge').value = '250'; $('#f-betrag').value = '1149'; formatierer(); }]
: [() => setzeSatz('roh'), () => setzeSatz('gut'), () => hebe(1), () => hebe(4), () => { hebe(null); setzeRegel('din'); }, () => setzeRegel('duden')];
let i = 0;
const takt = () => { if (i < schritte.length) { schritte[i++](); lauf = setTimeout(takt, 1300); } else lauf = setTimeout(vorfuehren, 600); };
takt();
}
function pause() { clearTimeout(lauf); }
function weiter() { vorfuehren(); }
setzeVariante(variante, true);
})();
</script>
</body>
</html>