{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "termin-buchung-zwei-klick",
 "name": "Termin-Buchung per 2-Klick-Einbettung",
 "name_en": "Two-click booking embed",
 "kurz": "Buchungs-Platzhalter in Widget-Höhe: Leistungen, Anbieter und Datenfluss stehen sofort da, der Kalender des Drittanbieters lädt erst nach Klick.",
 "kategorie": "Hero & Section-Layouts",
 "kategorie_slug": "hero-layouts",
 "kategorie_nr": 4,
 "bau_chat": "C2",
 "prioritaet": "B",
 "trendstatus": "etabliert",
 "belegstatus": "unbelegt",
 "website_belege": 0,
 "stimmung": [
  "präzise"
 ],
 "stimmung_roh": [
  "sachlich",
  "vertrauenswürdig"
 ],
 "technik": [
  "html",
  "css",
  "js"
 ],
 "technik_gruppen": [
  "css",
  "andere"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Statt das Buchungs-Widget eines Drittanbieters sofort zu laden, steht an seiner Stelle ein eigener Platzhalter. Er zeigt, was gebucht werden kann, nennt den Anbieter und sagt, welche Daten beim Laden an ihn gehen. Erst ein Klick auf „Online-Termin laden“ oder eine bestehende Einwilligung für genau diesen Dienst setzt iframe oder Script ein. Telefon oder E-Mail stehen immer daneben. Auf Wunsch merkt sich die Seite die Wahl für die Sitzung.",
  "warum_es_wirkt": "Online-Buchung ist für Praxen, Restaurants, Hotels und Fahrschulen der wichtigste CTA. Drittanbieter-Widgets setzen aber Cookies und kosten Ladezeit. Der Platzhalter erfüllt die Einwilligungspflicht und hält den ersten Bildschirm schnell. Wer nicht einwilligen will, hat trotzdem einen Weg: anrufen oder schreiben.",
  "wann_einsetzen": "Arztpraxen, Therapie, Friseur und Beauty, Restaurants mit Tischreservierung, Hotels, Fahrschulen, Beratung mit Kalender-Tool.",
  "wann_nicht": "Wenn die Buchung selbst gehostet ist und keine Daten an Dritte fließen. Dann direkt einbinden. Nie den Platzhalter ohne Alternative lassen: Telefon oder E-Mail gehören immer dazu.",
  "varianten": [
   "Platzhalter mit Leistungen, Hinweis zum Datenfluss und Button „Online-Termin laden“, daneben Telefon",
   "Eigene Vorauswahl (Leistung, Klasse, Woche) vor dem Laden, Übergabe per URL-Parameter an das Widget",
   "Link-out: Die Buchung öffnet beim Anbieter in einem neuen Tab, die eigene Seite lädt nichts nach (mobil oft besser)",
   "Höhe passt sich an: Das iframe wächst ab Chrome 154 mit dem Inhalt (frame-sizing: content-height), wenn der Anbieter das Opt-in-Meta setzt; sonst feste Höhe wie oben"
  ],
  "umsetzung": "Container mit fester Höhe in Widget-Höhe (hier 540 px, mobil 580 px), darin der Platzhalter; die Anbieter-Adresse steht in data-src. Der Klick erzeugt per JS das <iframe> mit title und loading=\"lazy\" oder lädt das Script nach. Das iframe liegt absolut auf derselben Fläche, deshalb springt nichts. Platzhalter und iframe überblenden in 200 ms. Ein Status-Chip mit aria-live meldet „Nicht geladen“, „Verbinde …“ und „Geladen“. Die Freigabe mit der Kategorie im Consent-Banner abgleichen: Ist der Dienst dort erlaubt, lädt das Widget sofort. „Für diesen Besuch merken“ speichert die Wahl in sessionStorage. Ohne JS führt ein normaler Link zum Anbieter. Höhe, die sich anpasst (ab Chrome 154): Setzt der Anbieter im Widget <meta name=\"responsive-embedded-sizing\" content=\"allow-origins=https://ihre-domain.example\"> (oder allow-origins=*), kann das iframe seiner Inhaltshöhe folgen. Dazu der feste Wert als Rückfall und eine Weiche: .widget { height: 540px } @supports (frame-sizing: content-height) { .widget { height: auto; frame-sizing: content-height } }. Der Browser misst beim Laden; ändert sich das Widget danach (nächster Schritt, mehr Termine), ruft der Anbieter window.requestResize() auf. Das Meta lässt sich nicht nachträglich per Skript einsetzen, es muss im ausgelieferten Dokument stehen. Ohne Opt-in oder in Firefox und Safari bleibt die feste Höhe, längere Schritte scrollen im Widget. Den Platzhalter in der üblichen Starthöhe des Widgets reservieren, damit beim Laden nichts springt.",
  "mobil": "Platzhalter einspaltig und etwas höher. Unten eine feste Leiste mit Anmelden, Anrufen und WhatsApp. Auf dem Handy ist Link-out in einen neuen Tab oft besser als ein eingebettetes iframe.",
  "reduzierte_bewegung": "Kein Effekt nötig. Platzhalter und Widget wechseln ohne Überblendung.",
  "barrierefreiheit": "Echter <button>, klarer Text zum Datenfluss, iframe mit title. Nach dem Laden geht der Fokus in das Widget. Der Status-Chip meldet den Zustand per aria-live. Link-out mit Hinweis „öffnet in neuem Tab“ für Screenreader. Ein Button „Kalender wieder entfernen“ nimmt die Einwilligung zurück."
 },
 "messwerte": {
  "easing": "",
  "dauer_ms": "",
  "stagger_ms": "",
  "distanz": "",
  "sonstiges": "Platzhalter-Höhe fest (kein Layout-Sprung); Widget erst nach Klick oder Einwilligung",
  "herkunft": "typisch",
  "quelle": ""
 },
 "kurve": null,
 "gesehen_bei": [],
 "tutorials": [],
 "kombinierbar_mit": [
  "consent-banner-gestaltet",
  "button-zustaende",
  "mobile-bottom-navigation",
  "karte-zwei-klick",
  "kontakt-anfrage-formular"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/hero-layouts/termin-buchung-zwei-klick/",
  "meta": "https://cecodesign.de/lab/fundus/hero-layouts/termin-buchung-zwei-klick/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/hero-layouts/termin-buchung-zwei-klick/demo"
 },
 "herkunft": {
  "quelldateien": [
   "r3-ad-korrekturen"
  ],
  "pruefnotizen": [
   "Runde 3 (31.10.2026): neu angelegt nach der Art-Director-Prüfung der 18 Rezepte – Praxis, Gastro, Hotel und Fahrschule verlangten Online-Buchung nur in den Regeln, ein Muster dafür fehlte. Noch ohne Website-Beleg; Messwerte typisch."
  ],
  "prioritaet_hinweis": "Grundbaustein für KMU-Templates (Lücke aus der Art-Director-Prüfung der Rezepte, Runde 3), kein Trendmuster; Website-Belege fehlen noch."
 },
 "bau": {
  "status": "fertig",
  "kurz": "Buchungs-Platzhalter in Widget-Höhe: Leistungen, Anbieter und Datenfluss stehen sofort da, der Kalender des Drittanbieters lädt erst nach Klick.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "hoehe": "540 px (Desktop), 580 px bis 560 px Breite; Platzhalter und iframe exakt gleich hoch, iframe absolut auf derselben Fläche",
   "easing_ui": "cubic-bezier(0.4, 0, 0.2, 1)",
   "austausch": "opacity 200 ms cubic-bezier(0.4, 0, 0.2, 1): Platzhalter aus, iframe ein",
   "lade_simulation_ms": 650,
   "lade_simulation_reduziert_ms": 120,
   "button": "transform und box-shadow 350 ms cubic-bezier(0.34, 1.56, 0.64, 1); Hover -2 px (Schatten 6 px), Druck +3 px in 150 ms (Schatten 1 px), Ruhe Schatten 4 px; Rand 2 px, Radius 12 px",
   "segmente_vorauswahl": "Hintergrund, Rand, Farbe 200 ms cubic-bezier(0.4, 0, 0.2, 1)",
   "status_chip": "aria-live; Punkt grau (nicht geladen), Himmelblau mit Puls 900 ms alternate (lädt), Grün #1f8a4c (geladen)",
   "marker": "Gelbe Fläche hinter „Kehre“, scaleX 0 → 1, 800 ms cubic-bezier(0.16, 1, 0.3, 1), Verzögerung 300 ms",
   "strasse": "Maske stroke-dashoffset 1 → 0 (pathLength 1), 1800 ms cubic-bezier(0.16, 1, 0.3, 1), Verzögerung 150 ms; Straße 15 px Navy, Mittellinie 1.6 px, dasharray 7 9",
   "link_out_tab": "nachgestellter Tab: opacity und translate 14 px → 0, 200 ms cubic-bezier(0.4, 0, 0.2, 1), Schleier rgba(14, 29, 56, .28)",
   "url_parameter": "?klasse=B&leistung=erste-fahrstunde&ab=2026-11-02",
   "merken": "sessionStorage „spitzkehre-terminwerk“ = 1, lädt beim nächsten Aufruf in der Sitzung sofort",
   "karte": "Radius 20 px, Rand 2 px Navy, harter Schatten 0 8px 0 Navy",
   "farben": "Grund #f8f8ec, Sektion #eef0d8, Navy #142b50, Himmel #3fbadf, Kennzeichen-Gelb #ffd60a (nur Fläche), gedämpft #566175",
   "schrift": "Bricolage Grotesque h1 clamp(2.5rem, 0.5rem + 5vw, 5.5rem), wght 700, opsz 96, -0.02em, Zeilenhöhe 0.98; Atkinson Hyperlegible Next 17 px / 1.6, Preise tabellarisch; Geist Mono 11 px / 0.14em für Labels",
   "vorfuehrung": "Schleife aus drei Szenen (Platzhalter, Vorauswahl, Link-out): Zeiger klickt Laden, wartet auf das iframe, wählt einen Termin; Zeigerfahrt 650 ms, je Szene etwa 6 bis 9 s"
  },
  "ausloeser": "klick",
  "touch": "Einspaltig, Platzhalter 580 px hoch, große Ziele (Merken-Zeile 44 px). Feste untere Leiste mit Anmelden, Anrufen und WhatsApp. Buttons heben sich nicht beim Hover. Link-out öffnet den nachgestellten Tab bildschirmfüllend.",
  "reduziert": "Keine Überblendung, kein sich zeichnender Marker, keine sich zeichnende Straße, kein Puls am Status-Chip, kein Heben der Buttons. Nachgestellte Ladezeit 120 statt 650 ms. Die Vorführung springt mit dem Zeiger von Schritt zu Schritt.",
  "korrekturen": {
   "beschreibung": "Statt das Buchungs-Widget eines Drittanbieters sofort zu laden, steht an seiner Stelle ein eigener Platzhalter. Er zeigt, was gebucht werden kann, nennt den Anbieter und sagt, welche Daten beim Laden an ihn gehen. Erst ein Klick auf „Online-Termin laden“ oder eine bestehende Einwilligung für genau diesen Dienst setzt iframe oder Script ein. Telefon oder E-Mail stehen immer daneben. Auf Wunsch merkt sich die Seite die Wahl für die Sitzung.",
   "warum_es_wirkt": "Online-Buchung ist für Praxen, Restaurants, Hotels und Fahrschulen der wichtigste CTA. Drittanbieter-Widgets setzen aber Cookies und kosten Ladezeit. Der Platzhalter erfüllt die Einwilligungspflicht und hält den ersten Bildschirm schnell. Wer nicht einwilligen will, hat trotzdem einen Weg: anrufen oder schreiben.",
   "wann_einsetzen": "Arztpraxen, Therapie, Friseur und Beauty, Restaurants mit Tischreservierung, Hotels, Fahrschulen, Beratung mit Kalender-Tool.",
   "wann_nicht": "Wenn die Buchung selbst gehostet ist und keine Daten an Dritte fließen. Dann direkt einbinden. Nie den Platzhalter ohne Alternative lassen: Telefon oder E-Mail gehören immer dazu.",
   "varianten": [
    "Platzhalter mit Leistungen, Hinweis zum Datenfluss und Button „Online-Termin laden“, daneben Telefon",
    "Eigene Vorauswahl (Leistung, Klasse, Woche) vor dem Laden, Übergabe per URL-Parameter an das Widget",
    "Link-out: Die Buchung öffnet beim Anbieter in einem neuen Tab, die eigene Seite lädt nichts nach (mobil oft besser)",
    "Höhe passt sich an: Das iframe wächst ab Chrome 154 mit dem Inhalt (frame-sizing: content-height), wenn der Anbieter das Opt-in-Meta setzt; sonst feste Höhe wie oben"
   ],
   "umsetzung": "Container mit fester Höhe in Widget-Höhe (hier 540 px, mobil 580 px), darin der Platzhalter; die Anbieter-Adresse steht in data-src. Der Klick erzeugt per JS das <iframe> mit title und loading=\"lazy\" oder lädt das Script nach. Das iframe liegt absolut auf derselben Fläche, deshalb springt nichts. Platzhalter und iframe überblenden in 200 ms. Ein Status-Chip mit aria-live meldet „Nicht geladen“, „Verbinde …“ und „Geladen“. Die Freigabe mit der Kategorie im Consent-Banner abgleichen: Ist der Dienst dort erlaubt, lädt das Widget sofort. „Für diesen Besuch merken“ speichert die Wahl in sessionStorage. Ohne JS führt ein normaler Link zum Anbieter. Höhe, die sich anpasst (ab Chrome 154): Setzt der Anbieter im Widget <meta name=\"responsive-embedded-sizing\" content=\"allow-origins=https://ihre-domain.example\"> (oder allow-origins=*), kann das iframe seiner Inhaltshöhe folgen. Dazu der feste Wert als Rückfall und eine Weiche: .widget { height: 540px } @supports (frame-sizing: content-height) { .widget { height: auto; frame-sizing: content-height } }. Der Browser misst beim Laden; ändert sich das Widget danach (nächster Schritt, mehr Termine), ruft der Anbieter window.requestResize() auf. Das Meta lässt sich nicht nachträglich per Skript einsetzen, es muss im ausgelieferten Dokument stehen. Ohne Opt-in oder in Firefox und Safari bleibt die feste Höhe, längere Schritte scrollen im Widget. Den Platzhalter in der üblichen Starthöhe des Widgets reservieren, damit beim Laden nichts springt.",
   "mobil": "Platzhalter einspaltig und etwas höher. Unten eine feste Leiste mit Anmelden, Anrufen und WhatsApp. Auf dem Handy ist Link-out in einen neuen Tab oft besser als ein eingebettetes iframe.",
   "reduzierte_bewegung": "Kein Effekt nötig. Platzhalter und Widget wechseln ohne Überblendung.",
   "barrierefreiheit": "Echter <button>, klarer Text zum Datenfluss, iframe mit title. Nach dem Laden geht der Fokus in das Widget. Der Status-Chip meldet den Zustand per aria-live. Link-out mit Hinweis „öffnet in neuem Tab“ für Screenreader. Ein Button „Kalender wieder entfernen“ nimmt die Einwilligung zurück."
  },
  "geprueft": "02.11.2026",
  "notiz": "Fahrschule Spitzkehre in Innsbruck-Pradl (Rezept fahrschule-freundlich-buchbar, Bricolage Grotesque und Atkinson Hyperlegible Next). Der Klick erzeugt ein echtes <iframe>. Das Widget des erfundenen Anbieters Terminwerk kommt als srcdoc aus der Datei, die Ladezeit von 650 ms ist nachgestellt; im Einsatz steht dort src mit der Anbieter-URL. Link-out ist als nachgestellter Tab gezeigt, echt öffnet target=\"_blank\". Nordkette und Serpentine sind eigene SVG. Die Maßlinie am Rand zeigt die feste Höhe. Vorführung: drei Szenen in Schleife, je Variante laden und Termin wählen. AD-Review 01.11.2026: Note 5. Zugang 02.11.2026: 320 px: Variantenschalter im Pult darf umbrechen, Werte-Zeile bricht lange Kurven um. Kontrastmodus: Knöpfe mit Rahmen ButtonText. Korrektur 02.11.2026: Variante „Höhe passt sich an“ (?v=hoehe): Widget mit Opt-in-Meta responsive-embedded-sizing, längerem Schritt 2 und requestResize(); @supports-Weiche auf frame-sizing: content-height, Rückfall feste Höhe mit sichtbarem Hinweis. Umschalter schreibt ?v= in die URL, die Demo startet in der Variante aus der URL. Geprüft nur der Rückfall (Headless-Chromium 153 kennt frame-sizing nicht); die native Größenanpassung ist ungeprüft, Angaben aus den Chrome-154-Versionshinweisen und developer.chrome.com/blog/responsive-iframes.",
  "varianten": [
   {
    "id": "platzhalter",
    "name": "Platzhalter mit 2-Klick",
    "knopf": "Platzhalter",
    "wann": "Standard für Praxis, Friseur, Fahrschule, Restaurant: Leistungen und Datenfluss sofort, Widget erst nach Klick.",
    "werte": {
     "hoehe": "540 px, 580 px bis 560 px Breite, fest",
     "lade_simulation_ms": 650
    }
   },
   {
    "id": "vorauswahl",
    "name": "Vorauswahl vor dem Laden",
    "knopf": "Vorauswahl",
    "wann": "Wenn es mehrere Leistungen oder Klassen gibt (Fahrschule, Physiotherapie, Kosmetik): eigene Felder, Übergabe per URL-Parameter.",
    "werte": {
     "url_parameter": "?klasse=B&leistung=erste-fahrstunde&ab=2026-11-02",
     "segmente": "Hintergrund, Rand, Farbe 200 ms cubic-bezier(0.4, 0, 0.2, 1)"
    }
   },
   {
    "id": "linkout",
    "name": "Link-out in neuem Tab",
    "knopf": "Link-out",
    "wann": "Mobil oder wenn das Widget schlecht einzubetten ist: Buchung beim Anbieter in neuem Tab, die Seite lädt nichts nach.",
    "werte": {
     "link_out_tab": "opacity und translate 14 px → 0, 200 ms cubic-bezier(0.4, 0, 0.2, 1)"
    }
   },
   {
    "id": "hoehe",
    "name": "Höhe passt sich an",
    "knopf": "Höhe wächst mit",
    "wann": "Wenn das Buchungs-Widget je Schritt unterschiedlich lang ist und der Anbieter das Opt-in-Meta setzt (Praxis, Friseur, Fitness, Hotel); greift ab Chrome 154, sonst feste Höhe.",
    "werte": {
     "css": "@supports (frame-sizing: content-height) { .widget { position: relative; height: auto; frame-sizing: content-height } .embed { height: auto } } erst nach dem Laden; davor Platzhalter 540 px",
     "opt_in": "<meta name=\"responsive-embedded-sizing\" content=\"allow-origins=*\"> im Widget-Dokument",
     "nachmessen": "window.requestResize() im Widget nach Schrittwechsel, nur wenn vorhanden",
     "rueckfall": "feste Höhe 540 px (580 px mobil), Schritt 2 scrollt im Widget; sichtbarer Hinweis unter dem Rahmen",
     "browser": "frame-sizing ab Chrome 154; Firefox und Safari nicht",
     "vorfuehrung": "laden, Termin wählen, Weiter zu Schritt 2 (Schleife nur diese Variante)"
    }
   }
  ]
 }
}
