{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "oeffnungszeiten-status",
 "name": "Öffnungszeiten mit Live-Status",
 "name_en": "Opening hours with live open/closed status",
 "kurz": "„Jetzt geöffnet, schließt in 40 Min.“ aus echten Zeiten mit Mittagspause, Feiertagen und Sonderzeiten, gerechnet in Europe/Berlin, ohne Layout-Sprung.",
 "kategorie": "Sektionen & Funktionen",
 "kategorie_slug": "sektionen",
 "kategorie_nr": 16,
 "bau_chat": "D",
 "prioritaet": "D",
 "trendstatus": "etabliert",
 "belegstatus": "teilbelegt",
 "website_belege": 1,
 "stimmung": [
  "ruhig",
  "präzise"
 ],
 "stimmung_roh": [
  "ruhig",
  "funktional",
  "vertrauenswürdig"
 ],
 "technik": [
  "vanilla-js",
  "intl",
  "intl-datetimeformat",
  "css"
 ],
 "technik_gruppen": [
  "css",
  "js"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Eine Statuszeile sagt, was jetzt gilt: „Jetzt geöffnet, schließt in 40 Min.“, „Mittagspause, ab 14.00 Uhr wieder da“ oder „Heute geschlossen (Allerheiligen), öffnet Montag um 8.00 Uhr“. Grundlage sind die echten Zeiten: Wochenplan mit Mittagspause, dazu Feiertage, Urlaub und Sonderzeiten mit Datum. Gerechnet wird immer in der Zeit des Ortes (Europe/Berlin über Intl), nicht in der Zeit des Besuchers. Der Platz für die Statuszeile ist reserviert, der Server liefert einen neutralen Text, JS ersetzt ihn ohne Layout-Sprung.",
  "warum_es_wirkt": "Die häufigste Frage an eine Praxis, ein Lokal oder einen Laden ist „Haben die gerade offen?“. Eine Wochentabelle beantwortet das erst nach Rechnen und Abgleichen mit dem Kalender. Die Statuszeile beantwortet es sofort und nennt den nächsten Schritt: anrufen, vorbeikommen oder wann es wieder geht.",
  "wann_einsetzen": "Praxis, Therapie, Apotheke, Restaurant, Café, Laden, Werkstatt, Museum, Bürgerbüro. Im Kopf der Seite, in der Kontakt- oder Anfahrt-Sektion und in der unteren Leiste auf dem Telefon.",
  "wann_nicht": "Wenn die Zeiten nicht gepflegt werden: Ein falsches „Jetzt geöffnet“ an einem Feiertag ist schlimmer als gar keine Anzeige. Bei Terminbetrieb ohne offene Sprechstunde lieber „Telefon erreichbar“ statt „geöffnet“.",
  "varianten": [
   "Sprechzeiten-Karte: Status, Tagesleiste mit Mittagspause, Wochentabelle und Sonderzeiten",
   "Kopfzeile kompakt: Status als Pille im Kopf, Woche im Popover",
   "Termin nach Vereinbarung (Kanzlei, Architekturbüro): Status nur fürs Telefon, „Telefon erreichbar bis 17 Uhr“",
   "Auslastung jetzt (Museum, Sauna, Studio) aus echten Zählwerten mit dem üblichen Tagesverlauf; ohne frischen Zählwert entfällt der Block",
   "Gastronomie über Mitternacht (18 bis 1 Uhr) und Küche schließt früher als die Bar",
   "Mehrere Standorte mit eigenem Status in einer Liste",
   "Hinweisleiste über dem Kopf aus denselben Sonderzeiten (Betriebsferien, Sonderöffnung): im ersten HTML, schließbar mit Merken der Meldungs-id, klebt nicht"
  ],
  "umsetzung": "Daten nach schema.org-Logik: WOCHE je Wochentag (0 = Sonntag) als Liste von Zeiträumen ['08:00','12:00'], Mittagspause = zwei Zeiträume; SONDER als Liste { von, bis?, grund, zeiten } für Feiertage, Urlaub und Aktionen, die den Tag ganz überschreiben. Ortszeit: Intl.DateTimeFormat('de-DE', { timeZone: 'Europe/Berlin', hourCycle: 'h23', year, month, day, hour, minute, weekday }).formatToParts(new Date()). Daraus eine Liste absoluter Intervalle in Minuten ab heute 0 Uhr (gestern bis + 21 Tage; Ende ≤ Beginn → + 1440 für Zeiten über Mitternacht). Zustand: aktuelles Intervall → geöffnet (ab 60 Min. Countdown, ab 30 Min. „schließt bald“); vorheriges und nächstes Intervall heute → Mittagspause; sonst nächster Beginn (heute, morgen, Wochentag, ab 7 Tagen mit Datum). Takt: setTimeout auf die nächste volle Minute und bei visibilitychange. Ohne Layout-Sprung: Die Statusbox hat eine feste Mindesthöhe; der Server schreibt einen neutralen Text mit den regulären Zeiten hinein, JS ersetzt nur den Inhalt. Die Wochentabelle kommt fertig vom Server, JS markiert nur den heutigen Tag und hängt geänderte Zeiten an. Zeitzone des Besuchers: Status bleibt Ortszeit; weicht die Zone ab, zeigt eine reservierte Zeile die Uhrzeit beim Besucher. In der Demo ersetzt das Pult die Uhr (Tag, Uhrzeit, Echtzeit) und schaltet den Server-Text ein.",
  "mobil": "Eine Spalte. In der Kopfzeilen-Variante steht der Status in der unteren Leiste neben Anrufen und Termin; Tippen öffnet die Woche als Blatt. Kurztexte statt ganzer Sätze.",
  "reduzierte_bewegung": "Keine Bewegung nötig. Farbwechsel des Statuspunkts ohne Übergang, kein Pulsieren.",
  "barrierefreiheit": "Status nie nur über Farbe: Kopfzeile sagt immer „geöffnet“, „Mittagspause“ oder „geschlossen“. Die minütliche Aktualisierung ist still; nur ein Zustandswechsel wird über eine eigene aria-live=polite-Region angesagt. Tabelle mit scope=row und scope=col, der heutige Tag zusätzlich mit dem Wort „heute“ markiert. Notfallnummern 116 117 und 112 als tel:-Links immer sichtbar. Text ab 17 px, Kontrast leiser Text #596666 auf Weiß 5,97:1. Feiertage sind Ländersache: Liste je Standort pflegen und vom Kunden prüfen lassen."
 },
 "messwerte": {
  "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
  "dauer_ms": "150–250",
  "stagger_ms": "",
  "distanz": "",
  "sonstiges": "„Schließt bald“ ab 30 Min. vor Ende, Countdown ab 60 Min.; Aktualisierung zur vollen Minute",
  "herkunft": "eigene Festlegung",
  "quelle": "Rezept praxis-gesundheit-ruhig (bewegung: token-tech-praezise, 150–250 ms)"
 },
 "kurve": {
  "bezier": [
   0.2,
   0.0,
   0.38,
   0.9
  ],
  "css": "cubic-bezier(0.2, 0, 0.38, 0.9)",
  "name": "eigene Kurve",
  "dauer_ms": 200
 },
 "gesehen_bei": [
  {
   "seite": "Apple Store Hannover",
   "url": "https://www.apple.com/de/retail/hannover/",
   "auszeichnung": "",
   "beobachtung": "Per WebFetch am 01.11.2026 gelesen: Statuszeile „Geöffnet bis 20:00 Uhr“ unter dem Namen, darunter eine Tabelle der nächsten sieben Tage mit Tag, Datum und Zeiten. Geänderte Zeiten tragen ein Sternchen mit Fußnote „Geänderte Öffnungszeiten“, geschlossene Tage stehen als „Geschlossen“.",
   "art": "website"
  },
  {
   "seite": "schema.org: OpeningHoursSpecification",
   "url": "https://schema.org/OpeningHoursSpecification",
   "auszeichnung": "",
   "beobachtung": "Datenmodell für Öffnungszeiten: opens/closes je Wochentag, validFrom/validThrough für befristete Zeiten. Schließt closes vor opens, gilt der Zeitraum bis in den nächsten Tag. specialOpeningHoursSpecification überschreibt die regulären Zeiten, etwa an Feiertagen.",
   "art": "artikel"
  },
  {
   "seite": "npm: @phoenix344/opening-hours",
   "url": "https://www.npmjs.com/package/%40phoenix344%2Fopening-hours",
   "auszeichnung": "",
   "beobachtung": "Bibliothek ohne Abhängigkeiten für Öffnungszeiten mit Intl.DateTimeFormat, Standard-Zeitzone Europe/Berlin, Zeiten über Mitternacht, Pausen und Abfrage „geöffnet, öffnet bald, schließt bald“. Sonderzeiten für Zeiträume stehen laut Readme noch auf der Liste.",
   "art": "demo"
  }
 ],
 "tutorials": [
  {
   "titel": "MDN: Intl.DateTimeFormat.prototype.formatToParts()",
   "url": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/formatToParts"
  },
  {
   "titel": "schema.org: OpeningHoursSpecification",
   "url": "https://schema.org/OpeningHoursSpecification"
  }
 ],
 "kombinierbar_mit": [
  "live-uhr-und-standort",
  "mobile-bottom-navigation",
  "tabellenziffern",
  "native-popover-dropdowns",
  "termin-buchung-zwei-klick",
  "karte-zwei-klick",
  "studio-visitenkarte-footer"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/sektionen/oeffnungszeiten-status/",
  "meta": "https://cecodesign.de/lab/fundus/sektionen/oeffnungszeiten-status/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/sektionen/oeffnungszeiten-status/demo"
 },
 "herkunft": {
  "quelldateien": [
   "DEF-Recherche 01.11.2026"
  ],
  "pruefnotizen": [
   "Apple Store Hannover per WebFetch am 01.11.2026 gelesen (Statuszeile, 7-Tage-Tabelle, Sternchen für geänderte Zeiten).",
   "Feiertage sind Ländersache (Allerheiligen gilt z. B. in Baden-Württemberg, nicht in Hessen); Liste je Standort pflegen und vom Kunden prüfen lassen."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "„Jetzt geöffnet, schließt in 40 Min.“ aus echten Zeiten mit Mittagspause, Feiertagen und Sonderzeiten, gerechnet in Europe/Berlin, ohne Layout-Sprung.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "cubic-bezier(0.2, 0, 0.38, 0.9) (token-tech-praezise, Rezept praxis-gesundheit-ruhig)",
   "dauer_ms": 200,
   "dauer_ms_hinweis": "Statuspunkt-Farbe, Jetzt-Strich der Tagesleiste, Popover der Kopfzeile, Knöpfe",
   "schwellen": "Countdown ab 60 Min. vor Ende („schließt in 40 Min.“), Zustand „Schließt bald“ ab 30 Min., „Öffnet gleich“ ab 60 Min. vor Beginn, Pause = Lücke unter 240 Min. zwischen zwei Zeiträumen am selben Tag",
   "zeitzone": "Intl.DateTimeFormat('de-DE', { timeZone: 'Europe/Berlin', hourCycle: 'h23', … }).formatToParts(); Datumsrechnung immer auf UTC-Mittag",
   "intervalle": "gestern bis heute + 21 Tage als absolute Minuten ab heute 0 Uhr; Ende ≤ Beginn → + 1440 (über Mitternacht)",
   "aktualisierung": "setTimeout bis zur nächsten vollen Minute (60000 − Date.now() % 60000 + 50 ms) und bei visibilitychange",
   "reserviert": "Statusbox min-height 7.5rem (Telefon 8rem): Kopf Hedvig Letters Serif clamp(2rem, 1.3rem + 2vw, 2.9rem)/1.1, Text 1.1875rem/1.5, tabular-nums",
   "statusfarben": "geöffnet #0f7a5c mit Ring 0 0 0 6px rgba(15,122,92,.14); schließt bald #ffc776; Mittagspause Ring ohne Füllung; geschlossen #8a9494",
   "tagesleiste": "Achse 7 bis 20 Uhr, Raster je Stunde, Zeiträume #e3eeec mit Rand rgba(0,84,80,.35), aktueller Zeitraum #005450",
   "farben": "Grund #f5f7f7, Karten #ffffff, Fläche #e2e0de, Marke #005450, Text #363b3b, leise #596666, Akzent #ffc776",
   "schrift": "Hedvig Letters Serif (opsz 24) für Überschriften, Google Sans Flex für Text ab 1.0625rem/1.6",
   "vorfuehrung_runde_ms": 18400
  },
  "ausloeser": "dauer",
  "touch": "Kopfzeilen-Variante: der Status steht in einer festen unteren Leiste mit Kurztext („Offen bis 12.00“, „Zu · Mo 8.00“), Anruf-Knopf und Termin; Tippen öffnet die Woche als Blatt über der Leiste. Karten-Variante: eine Spalte, Knopf „Anrufen“ statt Nummer, Achse der Tagesleiste nur jede zweite Stunde.",
  "reduziert": "Keine Bewegung im Muster außer Farbwechseln; mit .reduziert springen Statuspunkt, Jetzt-Strich und Popover ohne Übergang. Kein Pulsieren des Punkts.",
  "korrekturen": {
   "umsetzung": "Daten nach schema.org-Logik: WOCHE je Wochentag (0 = Sonntag) als Liste von Zeiträumen ['08:00','12:00'], Mittagspause = zwei Zeiträume; SONDER als Liste { von, bis?, grund, zeiten } für Feiertage, Urlaub und Aktionen, die den Tag ganz überschreiben. Ortszeit: Intl.DateTimeFormat('de-DE', { timeZone: 'Europe/Berlin', hourCycle: 'h23', year, month, day, hour, minute, weekday }).formatToParts(new Date()). Daraus eine Liste absoluter Intervalle in Minuten ab heute 0 Uhr (gestern bis + 21 Tage; Ende ≤ Beginn → + 1440 für Zeiten über Mitternacht). Zustand: aktuelles Intervall → geöffnet (ab 60 Min. Countdown, ab 30 Min. „schließt bald“); vorheriges und nächstes Intervall heute → Mittagspause; sonst nächster Beginn (heute, morgen, Wochentag, ab 7 Tagen mit Datum). Takt: setTimeout auf die nächste volle Minute und bei visibilitychange. Ohne Layout-Sprung: Die Statusbox hat eine feste Mindesthöhe; der Server schreibt einen neutralen Text mit den regulären Zeiten hinein, JS ersetzt nur den Inhalt. Die Wochentabelle kommt fertig vom Server, JS markiert nur den heutigen Tag und hängt geänderte Zeiten an. Zeitzone des Besuchers: Status bleibt Ortszeit; weicht die Zone ab, zeigt eine reservierte Zeile die Uhrzeit beim Besucher. In der Demo ersetzt das Pult die Uhr (Tag, Uhrzeit, Echtzeit) und schaltet den Server-Text ein.",
   "barrierefreiheit": "Status nie nur über Farbe: Kopfzeile sagt immer „geöffnet“, „Mittagspause“ oder „geschlossen“. Die minütliche Aktualisierung ist still; nur ein Zustandswechsel wird über eine eigene aria-live=polite-Region angesagt. Tabelle mit scope=row und scope=col, der heutige Tag zusätzlich mit dem Wort „heute“ markiert. Notfallnummern 116 117 und 112 als tel:-Links immer sichtbar. Text ab 17 px, Kontrast leiser Text #596666 auf Weiß 5,97:1. Feiertage sind Ländersache: Liste je Standort pflegen und vom Kunden prüfen lassen.",
   "mobil": "Eine Spalte. In der Kopfzeilen-Variante steht der Status in der unteren Leiste neben Anrufen und Termin; Tippen öffnet die Woche als Blatt. Kurztexte statt ganzer Sätze.",
   "varianten": [
    "Sprechzeiten-Karte: Status, Tagesleiste mit Mittagspause, Wochentabelle und Sonderzeiten",
    "Kopfzeile kompakt: Status als Pille im Kopf, Woche im Popover",
    "Termin nach Vereinbarung (Kanzlei, Architekturbüro): Status nur fürs Telefon, „Telefon erreichbar bis 17 Uhr“",
    "Auslastung jetzt (Museum, Sauna, Studio) aus echten Zählwerten mit dem üblichen Tagesverlauf; ohne frischen Zählwert entfällt der Block",
    "Gastronomie über Mitternacht (18 bis 1 Uhr) und Küche schließt früher als die Bar",
    "Mehrere Standorte mit eigenem Status in einer Liste",
    "Hinweisleiste über dem Kopf aus denselben Sonderzeiten (Betriebsferien, Sonderöffnung): im ersten HTML, schließbar mit Merken der Meldungs-id, klebt nicht"
   ]
  },
  "geprueft": "03.11.2026",
  "notiz": "Welt: Rezept praxis-gesundheit-ruhig, erfundene Hausarztpraxis am Ammerbogen in Tübingen-Lustnau (Dr. Ruth Kienle, Jonas Ebinger), Petrol #005450, Hedvig Letters Serif und Google Sans Flex. Sprechzeiten Mo, Di 8–12 und 14–18, Mi 8–12, Do bis 19, Fr 8–13; Sonderzeiten Allerheiligen, Grippe-Impfsamstag, Fortbildung, Praxisurlaub mit Vertretung, Heilige Drei Könige. Startet in Echtzeit (Europe/Berlin); das Pult hat eine simulierte Uhr (Tag mit Sonderzeiten, Uhrzeit in 5-Minuten-Schritten), die Zeitzone des Besuchers (Berlin, New York, Tokio), die Variante (?v=karte|kompakt) und „Ohne JS“ mit dem Server-Text. Vorführung: die Uhr läuft durch Öffnet gleich, Countdown zur Mittagspause, Pause, Schließt bald, Mittwochnachmittag, Freitag 13 Uhr, Impfsamstag und Allerheiligen. Illustration des Wartezimmers als eigenes SVG. Logik per Node gegen elf Zeitpunkte geprüft. Referenzen: apple.com/de/retail (Statuszeile, Sternchen für geänderte Zeiten), schema.org (OpeningHoursSpecification), npmjs.com (opening-hours). AD-Review 02.11.2026: Note 4. Demo-Pult in der Kopfzeilen-Variante entzerrt (Tagesauswahl 12.5em mit Auslassung, Beschriftungen ohne Umbruch). Zugang 02.11.2026: vergangene Sonderzeiten grau (--leise) und durchgestrichen statt Deckkraft .45 (vorher 1,96:1), Spalte rechts minmax(0, 1fr), Wochentabelle und Zeitblöcke der Tagesleiste unter 400 px umbrechend (kein Querscrollen bei 320 px). Korrektur 02.11.2026: zwei Varianten. „Termin nach Vereinbarung“ (termin, Kanzlei Weidemann & Thiel in kanzlei-beratung-souveraen): Status nur fürs Telefon („Telefon erreichbar bis 17 Uhr“), Telefonzeiten, Weg zum Termin, Fristhinweis. „Auslastung jetzt“ (auslastung, Kunsthalle Warnowkai in kultur-programm-haltung): Zählwert als Meter mit Wort, Vergleich mit dem Üblichen, Säulen des üblichen Tagesverlaufs; ohne frischen Zählwert entfällt der Block (Pult „Zählung aus“, Vorführung zeigt es); Werte als „Beispielwerte“ markiert. Gleiche Zeitlogik (Intervalle, Sonderzeiten, simulierte Uhr) mit eigenen Daten je Variante; Variantenregel in CSS jetzt [data-nur~=…]. Geprüft: pruef.sh --v termin/auslastung, zugang regeln/breite320 ohne Befund. Varianten 03.11.2026: „Hinweisleiste“ (?v=hinweisleiste) in der Praxis-Welt, darunter die Sprechzeiten-Karte, damit Leiste, Status und Sonderzeiten-Liste sichtbar aus derselben Quelle kommen. Beleg GOV.UK Notification banner (sparsam, höchstens einer, Region mit Namen); CLS: Verschiebungen bis 500 ms nach einer Eingabe zählen nicht (web.dev), darum Schließen ohne Wertung, Einblenden per JS aber vermeiden. Selbsturteil 4.",
  "varianten": [
   {
    "id": "karte",
    "name": "Sprechzeiten-Karte",
    "wann": "Praxis, Therapie, Amt, Werkstatt: eigene Sektion „Sprechzeiten“ mit Status, Tagesleiste, Wochentabelle, Feiertagen und Notfallnummern.",
    "werte": {
     "layout": "Status-Karte 7fr, Woche und Sonderzeiten 5fr",
     "status": "Kopf in Hedvig Letters Serif, Countdown, Grund als Badge #ffc776",
     "tagesleiste": "7–20 Uhr mit Jetzt-Strich",
     "notdienst": "immer sichtbar, bei geschlossen/Pause Fläche #fff4e0"
    },
    "knopf": "Karte"
   },
   {
    "id": "kompakt",
    "name": "Kopfzeile kompakt",
    "wann": "Restaurant, Café, Laden oder Praxis, deren Startseite etwas anderes erzählt: Status als Pille im Kopf, Woche im Popover, auf dem Telefon in der unteren Leiste.",
    "werte": {
     "pille": "Höhe 40px, min-width 15.5em, Punkt 10px, Text „Geöffnet · bis 12.00 Uhr“",
     "popover": "popover=auto, anchor --pille, top: anchor(bottom), 8px Abstand, Breite min(380px, 100vw − 24px), opacity und translate 0 −6px in 200 ms",
     "telefon": "untere Leiste fest, Kurztext, Popover als Blatt 76px über dem Rand"
    },
    "knopf": "Kopfzeile"
   },
   {
    "id": "termin",
    "name": "Termin nach Vereinbarung",
    "knopf": "Termin",
    "wann": "Architekturbüro, Kanzlei, Steuerberatung, Agentur, Gutachter: kein Publikumsverkehr, Besprechungen nur mit Termin. Der Live-Status gilt nur dem Telefon („Telefon erreichbar bis 17 Uhr“), die Überschrift sagt „Termine nach Vereinbarung“. Welt des Rezepts kanzlei-beratung-souveraen.",
    "werte": {
     "rezept": "kanzlei-beratung-souveraen (Weidemann & Thiel, Steuerberatung Lüneburg)",
     "schrift": "Newsreader 400 für Titel clamp(2.25rem, 1.3rem + 2.6vw, 3.5rem)/1.1 und Status clamp(1.5rem, 1.2rem + 1vw, 2rem); Schibsted Grotesk für Text; Ziffern lining-nums (tnum setzt bei Schibsted auch den Punkt breit)",
     "farben": "#f9f8f8 Grund, #efebeb Hinweisfläche, #d2cdc7 Linien, #212529 Text, #5e5248 leise, #1e1e50 Nachtblau (Titel, Knöpfe, heute-Zeile #e8e7f0), Status-Punkt #0f7a5c erreichbar, #8e7c6d nicht besetzt",
     "kurve": "cubic-bezier(0.25, 1, 0.5, 1), UI 250 ms (token-swiss-knackig)",
     "status": "drei Zustände: „Telefon erreichbar bis 17 Uhr“ (letzte 15 Min. mit Restzeit), Mittagspause „Telefon ab 13.30 Uhr wieder besetzt“, sonst „Telefon gerade nicht besetzt“ mit nächstem Termin; Sonderzeit als Badge",
     "daten": "Telefonzeiten Mo–Do 8.30–12.30 und 13.30–17.00, Fr 8.30–13.00; Besprechungen nach Vereinbarung 7.30–20 Uhr; Sonderzeiten Teamtag, Weihnachten, zwischen den Jahren, Neujahr",
     "dazu": "Hinweis „Frist läuft ab?“ mit Postfach außerhalb der Telefonzeiten; drei Schritte zum Termin"
    }
   },
   {
    "id": "auslastung",
    "name": "Auslastung jetzt",
    "knopf": "Auslastung",
    "wann": "Museum, Kunsthalle, Sauna, Schwimmbad, Fitnessstudio oder Werkstatt-Wartezeit, aber nur mit echten Zählwerten (Einlasszählung, Kassensystem, Sensor). Ist der Zählwert alt oder fehlt er, entfällt der Block ganz, es wird nichts geschätzt. Die Demo zeigt sichtbar gekennzeichnete Beispielwerte. Welt des Rezepts kultur-programm-haltung.",
    "werte": {
     "rezept": "kultur-programm-haltung (Kunsthalle Warnowkai, Rostock)",
     "schrift": "Schibsted Grotesk 800 (Titel clamp(2.75rem, 1.4rem + 4.6vw, 5.5rem)/1, Status clamp(1.75rem, 1.3rem + 1.4vw, 2.5rem)); Atkinson Hyperlegible Next 1.125rem Text; IBM Plex Mono 500 0.8125rem für Labels, Stand und Achse",
     "farben": "#efede9 Grund, #f8f7f4 Karte, #0b0b0b Text und Balken, #57534c leise, #e4e1db Spur, #c4421a Markierung „üblich um diese Zeit“, #2f7d4a Punkt geöffnet",
     "kurve": "cubic-bezier(0.25, 1, 0.5, 1); Balken und Säulen 300 ms, UI 250 ms",
     "auslastung": "role=\"meter\" mit aria-valuenow/-valuetext; Stufen unter 35 % „Ruhig“, unter 65 % „Gut besucht“, sonst „Voll“ (Wort, nicht nur Farbe); Vergleich mit dem Üblichen (±3 Prozentpunkte = „so viel wie üblich“); „Stand hh.mm Uhr · Einlasszählung, alle 5 Min.“",
     "verlauf": "Säulen je Öffnungsstunde, Höhe = übliche Auslastung (Mittel der letzten acht Wochen), aktuelle Stunde schwarz mit Live-Strich; ruhige Stunden (< 25 %) im Text",
     "ohne_zaehlung": "Pult „Zählung aus“: Block „Auslastung jetzt“ entfällt, Öffnungsstatus und üblicher Verlauf bleiben",
     "kapazitaet": "350 Personen (Beispiel)"
    }
   },
   {
    "id": "hinweisleiste",
    "name": "Hinweisleiste über dem Kopf",
    "knopf": "Hinweisleiste",
    "wann": "Betriebsferien, Praxisurlaub, Sonderöffnung, geänderte Lieferzeiten oder Notdienst über Feiertage: eine seitenweite Leiste aus derselben Liste SONDER. Höchstens eine Leiste pro Seite, kein Laufband, sie klebt nicht.",
    "werte": {
     "daten": "SONDER-Eintrag mit zusätzlichem Feld leiste: { ab, art: zu|info, titel, vertretung?, text? }; aktiv von leiste.ab bis bis (bzw. von); bei mehreren gewinnt art zu",
     "texte": "vorher „Praxisurlaub vom 16. bis 20. November.“ plus Vertretung als tel:-Link und „Rezepte bitte bis Freitag, 13. November bestellen.“; während „Heute geschlossen: Praxisurlaub bis Freitag, 20. November.“ plus erster Öffnungstag; Sonderöffnung „Samstag, 28. November: Samstagssprechstunde, 9 bis 12 Uhr.“",
     "aufbau": "div role=region aria-labelledby auf den fetten Titel, im ersten HTML vor dem header (kein Layoutsprung), position static (klebt nicht, verdeckt bei 200 % Zoom nichts)",
     "schliessen": "Knopf 44 × 44 px „Hinweis schließen“; speichert die Meldungs-id in localStorage (Schlüssel praxis-hinweis-zu, in try/catch); ein Inline-Skript direkt nach der Leiste blendet eine schon geschlossene Meldung vor dem ersten Zeichnen aus; neue Meldung = neue id = erscheint wieder; Fokus danach auf den ersten Link im Kopf",
     "zuklappen": "grid-template-rows 1fr → 0fr in 150 ms cubic-bezier(0.2, 0, 0.38, 0.9), danach hidden; reduziert sofort",
     "farben": "art zu: Petrol #005450 mit Weiß (9 : 1), Symbol #ffc776, Fokus 3px #ffc776; art info: #e3eeec mit #363b3b",
     "schrift": "Google Sans Flex .9375rem/1.45, Titel 620",
     "demo": "Urlaub und Samstagssprechstunde liegen relativ zu heute (Montag in einer Woche bzw. Samstag danach), damit immer eine Meldung aktiv ist; Pult „Leiste zurücksetzen“ löscht den Schlüssel",
     "vorfuehrung": "heute (Ankündigung) → im Urlaub → Besucher schließt → gleiche Meldung bleibt zu → neue Meldung erscheint → am Samstag → vorbei; schließen speichert in der Vorführung nicht",
     "rezept": "praxis-gesundheit-ruhig (Praxis am Ammerbogen, Tübingen-Lustnau)"
    }
   }
  ]
 }
}
