new-term-radar
Daily radar for new AI terms: names of new models, products and repos, caught on X, Hugging Face, GitHub and sitemaps before keyword tools list them.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Interaktives Vertriebstool für ppedv, um im Kundengespräch live ein individuelles Kompetenzmodell zusammenzustellen — als Grundlage für Schulungskonzept und Angebot. Live (für das ganze Team, dieser Link): https://jasminannii.github.io/ppedv-kompetenzmatrix/ Quelle: index.html (einzelne, eigenständige HTML-Datei — kein Build nötig, einfach im Browser öffnen)查看完整 README ↗
Interaktives Vertriebstool für ppedv, um im Kundengespräch live ein individuelles Kompetenzmodell zusammenzustellen — als Grundlage für Schulungskonzept und Angebot.
Live (für das ganze Team, dieser Link): https://jasminannii.github.io/ppedv-kompetenzmatrix/
Quelle: index.html (einzelne, eigenständige HTML-Datei — kein Build nötig, einfach im Browser öffnen)
Gehostet über GitHub Pages (Deploy from branch main, Ordner /root — Einstellung
unter Settings → Pages). Das Repo muss dafür öffentlich bleiben (kostenlos; bei privaten
Repos verlangt GitHub Pages einen bezahlten Plan). Kein sensibler Code ist darin enthalten.
Der alte Weg über einen Claude-Artifact-Link (claude.ai/code/artifact/...) wird nicht
mehr verwendet: Der Artifact-Sandkasten blockiert bei öffentlich geteilten Links sowohl
Datei-Downloads als auch die serverseitige Kartei-Speicherung — das ließ sich nicht
zuverlässig reparieren (siehe „Drucken und PDF" unten). GitHub Pages hat keinen solchen
Sandkasten.
Die fünf Reiter folgen dem Termin. Jeder Schritt endet mit „Weiter: …“.
Die Kartei speichert alles; sie lässt sich später nachbearbeiten.
| Einheit | Bedeutung | Beispiel | |
|---|---|---|---|
| 1 | Kompetenzwelt | Sechs feste Themenfelder. Der Außenring. | Daten besser nutzen |
| 2 | Skill | Was der Kunde nennt, in seinen Worten. Der Innenring. | „Drei Abteilungen, drei Umsatzzahlen" |
| 3 | Team | Wem er fehlt, mit Kopfzahl. Mehrere je Skill. | Controlling · 5 |
Nichts im Innenring ist vorgegeben: er ist leer, wenn das Gespräch beginnt, und wächst mit jeder Zeile. Welten ohne Skill zeigen ein gestricheltes, blasses Segment — ein Klick darauf legt dort einen Skill an.
Die Kernkompetenzen von ppedv (drei je Welt) sind kein Eingabefeld mehr. Sie stehen im Panel unter „Woran ppedv dabei denkt" als Anhalt fürs Curriculum und speisen weiter den Matcher.
Mitarbeiterzahlen werden nicht addiert, sondern je Team maximiert. Wenn dem Innendienst (12 Personen) drei Skills fehlen, sind das nicht 36 Menschen. Je Team zählt die größte Nennung, die Gesamtzahl ist deren Summe.
Eine reine Schau-Seite: der Katalog, wie er ohne Kundendaten aussieht. Der vollständige Ring mit sechs Kompetenzwelten und ihren 18 Kernkompetenzen, darunter je Welt eine Karte mit den Kernkompetenzen samt Beschreibung, den typischen Sätzen aus Kundengesprächen, den Zielgruppen, den Kursen und dem Beleg aus der Studienlage.
Ein Klick auf ein Ringsegment hebt die zugehörige Karte hervor und springt hin. Die Seite ändert nichts am Kundendatensatz und hat einen eigenen Ring mit eigenen Element-IDs — der Arbeitsring in Schritt 2 bleibt unberührt.
Übernehmen. Neben jeder Kernkompetenz und jedem typischen Thema steht „+ übernehmen": ein Klick legt daraus einen Skill in der Kompetenzwelt des Kunden an, mit der richtigen Welt schon gesetzt. Team und Anzahl ergänzen Sie danach in Schritt 1. Bereits übernommene Punkte sind orange als „✓ übernommen" markiert und gesperrt — der Abgleich läuft über den Wortlaut, damit nichts doppelt in der Matrix landet.
Sie ist bewusst nicht Teil des PDF: das PDF ist die Angebotsgrundlage für
den Kunden, der Katalog würde seinen Umfang verdoppeln. Soll er mit hinein,
genügt es, die Zeile #s4{display:none!important} aus dem @media print-Block
zu löschen.
Die Kurse je Kompetenzwelt (bau in WORLDS) stammen aus der ppedv-Kursübersicht
(https://ppedv.de/Schulung/MicrosoftTraining, Stand 12.10.2026), mit Titel und Dauer.
Jeder Kurs steht in genau einer Welt. Ändert sich die Kursübersicht, wird nur diese
Liste gepflegt.
Kurse hängen an den Skills. Jeder Skill trägt seine Kurse (ku, je Kurs on = dabei).
Vorschläge kommen automatisch und ausgewählt, sobald Text und Kompetenzwelt stehen.
Angeklickte Kurse (an oder aus) bleiben; nur unberührte Vorschläge (auto) werden
neu berechnet, wenn sich Text oder Welt ändern. So entstehen die Vorschläge:
ku an komp und felder).KU_VER erhöhen, wenn sich die Zuordnung ändert: unberührte Vorschläge in bestehenden
Karteien werden dann neu berechnet, angeklickte bleiben.Der Kursplan in Schritt 4 ist die Vereinigung aller Skill-Kurse plus Pflichtkurs. Das Team eines Kurses ergibt sich aus den Skills, die ihn tragen, und lässt sich überschreiben. „ד im Kursplan schaltet einen Kurs in allen Skills aus.
In der Matrix stehen keine Preise; sie kommen erst im Angebotsgenerator dazu.
PFLICHT_TEXT, ensurePflicht(), KURS_SKILL, KURS_COPILOT.Auswahl und Copilot-Häkchen werden mit der Kartei gespeichert.
Durchführung und Anreise. Im Ablauf (Schritt 4) wird die Durchführung gewählt:
Anreise und Bestandskunde werden im Angebotsgenerator eingetragen.
Kursplan: welcher Kurs, für welches Team, wann. Die Reihenfolge der Tabelle ist die Priorität, verschoben wird mit ↑ ↓. Je Kurs werden Team (aus den erfassten Teams), Woche und, bei Hybrid, der Ort festgelegt. Ohne festgelegte Woche verteilen sich die Kurse automatisch über die Phase „Schulungen“; die Zahl steht dann kursiv. Der Kursplan erscheint als eigene Zeilen in der Timeline, im PDF (Balkenplan und Kursliste) und in der Textkopie. In der Timeline lassen sich alle Balken ziehen: Phasen verschieben (Mitte) oder Beginn und Ende ändern (Kanten), Kurse in eine andere Woche.
Phasen. Vier Phasen bilden ab, was bei einer Schulungsreihe passiert:
Vorbereitung (Termine, Teilnehmende, Praxisfälle, Raum/Technik) · Schulungen (die
Kurse laut Kursplan) · Praxistransfer (parallel: anwenden, Rückfragen, Spielregeln) ·
Abschluss (Gespräch mit der Leitung, Empfehlung). Danach die Jahrespartnerschaft.
Inhalte in PHASES, Standardwochen in TLSPAN. Ältere Karteien mit fünf Phasen
starten mit den Standardwochen.
Gesamtes Team. In Schritt 1 wird die Größe des gesamten Teams einmal zentral eingetragen. Betrifft ein Skill alle, genügt je Skill ein Klick auf „Gesamtes Team“. Die Zahl gilt überall, wo dieses Team zugeordnet ist. Weil das gesamte Team die Abteilungen bereits enthält, wird nicht addiert: Gezählt wird das gesamte Team oder die Summe der Abteilungen, je nachdem, was größer ist.
Kernkompetenzen folgen dem Kursprogramm. Jede der 18 Kernkompetenzen trägt in
ku die Kurse, die sie abdecken. Sie stehen im Katalog (Schritt 4) und im Panel
„Woran ppedv dabei denkt“ unter der Beschreibung. Regel: Eine Kernkompetenz ohne
passenden Kurs gehört nicht ins Modell. Auch die Unterzeilen der Welten nennen nur
Themen, die im Kursprogramm stehen.
Zwei Seiten: 1 · Kompetenzmodell (Kopf, Ring, ggf. „Was nicht funktioniert“ und Erfolgsbild, „Ihre Themen“ je Welt mit Team) und 2 · Kursplan und Ablauf (Balkenplan mit Phasen und Kursen, Kursliste mit Team, Woche, Ort, Dauer und Agenda, Phasen in je einer Zeile, Jahrespartnerschaft). Keine Preise — die stehen im Angebot.
Agenda-Daten. AGENDA in index.html enthält je Kurs den Pfad der Kursseite und die
Modultitel des Abschnitts „Agenda“ (bzw. „Kursinhalt“) von ppedv.de, Stand 12.10.2026.
Für die beiden Workshops stehen die vier Schritte der Landingpages. Die Agenda geht mit dem Link in den Angebotsgenerator und steht als kompakte Zeile je Kurs im Kundendokument (PDF) und in der Textkopie. Ändern sich Kurse auf
ppedv.de, die Liste neu auslesen; ein Kurs ohne Agenda-Abschnitt (derzeit „Power Apps und
Power Automate Fortgeschrittene“) erscheint mit dem Verweis auf die Kursbeschreibung.
Kernkompetenzen sind Vorschläge, keine Vorgaben. Je Welt sind drei hinterlegt; im Gespräch entsteht daraus, was der Kunde braucht:
EIGENE markiert und über × wieder löschbar
(mit Sicherheitsabfrage).Timeline frei einstellbar:
Kopf personalisierbar: Kundenlogo (Klick, Drag & Drop oder Einfügen aus der Zwischenablage) und Firmenname. Das Logo erscheint auch im Zentrum des Rings.
Alle Anpassungen werden pro Kartei (Kundendatensatz, oben rechts im Header speicherbar) isoliert gespeichert — sie verändern nicht den Katalog für andere Kunden. Bestehende Karteien aus der Vorversion werden beim Laden übernommen: alte „Rollen"- und „Teilnehmende"-Angaben wandern automatisch in Teamzeilen.
Ohne KI (immer verfügbar). Der Matcher arbeitet in drei Stufen, damit Kundensprache auf Katalogsprache trifft:
Je Welt liegt zusätzlich eine Stichwortliste (WKEY) in Kundensprache —
Akzeptanz, Berührungsangst, Medienbruch, Bauchgefühl und Ähnliches.
Mit KI („Mit KI zuordnen"). Die sample-Capability ist deklariert, der
Button erscheint, sobald der Viewer sie bekommt. Voraussetzung ist ein
angemeldeter Claude-Account beim Betrachter — er bestätigt den ersten Aufruf
und trägt die Kosten. Wer den öffentlichen Link ohne Login öffnet, sieht den
Button nicht und arbeitet mit der lokalen Zuordnung oben, die dafür ausgelegt
ist, allein zu genügen.
Die Anwendung liegt auf Vercel: index.html als statische Datei, dazu eine
einzige Serverless-Funktion unter api/kartei.js.
Freie Speichermöglichkeiten auf dem Hobby-Plan, geprüft an den Vercel-Docs:
| Option | Frei enthalten | Geeignet |
|---|---|---|
| Vercel Blob | 1 GB, auf allen Plänen | ja — mit privatem Store |
| Global Config | 100.000 Lesevorgänge, 100 Schreibvorgänge | nein, jedes Speichern ist ein Schreibvorgang |
| Marketplace (Neon, Upstash, Supabase) | eigene Kontingente | ginge, verlangt aber ein zweites Anbieterkonto |
Gewählt: Vercel Blob mit privatem Store. Eine Kartei ist genau ein
JSON-Dokument unter karteien/<id>.json. „Privat" heißt: Lesen geht nur über
unsere Funktion, nie über eine Blob-URL.
Achtung, Nutzungsbedingungen. Vercel schreibt: „the Hobby plan restricts users to non-commercial, personal use only." Ein Vertriebswerkzeug für Kundengespräche ist kommerziell — formal verlangt das den Pro-Plan.
/ → Unternehmen und Passwort → Weiterleitung auf /k/<id><id> sind 12 Zeichen aus randomBytes(9) — nicht zu erratenZur Stärke dieses Schutzes: Unternehmensname + Jahr ist leicht zu erraten; wer die URL hat und den Kunden kennt, kommt hinein. Die eigentliche Hürde ist die nicht erratbare URL. Für höheren Schutz ein eigenes Passwort vergeben.
/ zeigt ohne weitere Abfrage die Liste aller Karteien — Unternehmen, letzte
Änderung, Link, nach Datum sortiert. Dazu „+ Neue Kartei".
Die Liste kommt aus einem Verzeichnis-Blob karteien/_index.json, das bei
Anlegen, Sichern und Löschen nachgeführt wird: ein Lesevorgang statt einem je
Kartei. Es enthält nur id, titel und updatedAt — keine Passwörter, keine
Kundendaten. Schlägt die Nachführung fehl, ist die Kartei trotzdem gespeichert;
der Fehler landet im Log, nicht beim Nutzer.
Die Liste ist offen — bewusst so entschieden (zuletzt bestätigt am 13.10.2026). Wer die Adresse der Anwendung kennt, sieht alle Kundennamen — auch Kunden mit Kundenzugang. Der Inhalt jeder Kartei bleibt hinter ihrem Passwort (voreingestellt Unternehmensname + Jahr) bzw. dem Kundenpasswort. Soll die Liste geschützt werden: Team-Passwort wieder einbauen (Commit 48a81f2, Umgebungsvariable
UEBERSICHT_PASSWORT).
Kunden können ihre eigene Kompetenzwelt selbst anpassen — über einen eigenen Link mit eigenem Passwort, getrennt vom internen Zugang.
/k/<id>), oben Kundenzugang klicken, Passwort bestätigen
(ein zufälliger Vorschlag ist vorbelegt, mind. 6 Zeichen). Der Link /kunde/<id> wird
kopiert; Link und Passwort getrennt an den Kunden schicken. Ist ein Zugang aktiv, steht
„Kundenzugang ✓“ und daneben dauerhaft der Kundenlink mit „Kopieren“. Erneut klicken vergibt ein neues Passwort; leer lassen entzieht ihn.Anleitung für Kunden: /anleitung/ — fünf Schritte im ppedv-Design, druckbar als PDF.
Betont, dass eigene Themen genügen und das ppedv-Modell nur Anregung ist. Verlinkt auf der
Kunden-Anmeldung („So funktioniert’s“) und in der Kundenansicht oben („Anleitung“).
Durchgesetzt wird das auf dem Server (api/kartei.js), nicht nur in der Oberfläche:
rolle: "kunde" prüft die Funktion das Kundenpasswort (kundeSalt/kundeHash),
nie das interne. Das Kundenpasswort öffnet keine andere Kartei und nicht die interne
Ansicht.oeffnen liefert dem Kunden nur name, logo, skills, gesamtN, copilotOnly.sichern übernimmt vom Kunden nur skills, gesamtN, copilotOnly; alles andere
(Name, Logo, Kursplan, Preise, Angebot, Notizen) bleibt wie gespeichert.loeschen und kundenzugang sind für Kunden gesperrt (403).Bearbeiten Kunde und ppedv gleichzeitig, gewinnt die zuletzt gespeicherte Fassung. Vor eigenen Änderungen die Kartei deshalb neu laden, wenn der Kunde gerade daran war.
localStorage kommt nicht mehr vor. Der Zustand lebt im Arbeitsspeicher der
Seite und wird 1,5 Sekunden nach der letzten Änderung zum Server geschrieben
(scheduleSave → sichern). Das Passwort bleibt ebenfalls nur im
Arbeitsspeicher: nach dem Neuladen fragt die Schleuse erneut.
index.html die Anwendung, eine Datei
api/kartei.js anlegen / oeffnen / sichern / loeschen / uebersicht, per POST
vercel.json Rewrites /k/:id und /kunde/:id → /index.html
package.json @vercel/blob
Blobs: karteien/<id>.json je Kartei, karteien/_index.json als Verzeichnis.
Lokal testen ohne Vercel-Konto: api/kartei.js lässt sich gegen eine
Speicher-Attrappe laufen lassen, da es außer @vercel/blob nichts importiert.
profile.skills[] — {id, text, welt, teams:[{name,n}], note}WORLDS[] — Katalog der 6 Kompetenzwelten; komp, felder, ziel, bau
sind nur noch Vorschläge und Suchmaterial, kein Auswahlzustand mehrprofile.gesagt — Mitschrift „Was sagt der Kunde?"profile.tlWeeks / tlSpan[] / phTitle[] — TimelineskillsFromV4() überführt Karteien älterer Fassungen.normProfile() normalisiert das Profil bei jedem Laden.Das PDF wird clientseitig selbst gebaut, kein Druckdialog nötig. Grundlage
ist jsPDF, lokal unter vendor/ (kein externes CDN).
Verlaufsnotiz (nicht mehr relevant, aber als Warnung stehen gelassen): Auf
dem alten Claude-Artifact-Link scheiterte sowohl window.print() (Sandkasten
ohne allow-modals) als auch eine PDF-Vorschau in einem <iframe src="blob:...">
— Letzteres wurde von Edge und teils Chrome als „blockiert" abgewiesen, auch
außerhalb jedes Sandkastens. Die heutige Lösung ist der Web-Standardweg: ein
programmatisch angeklickter <a download>-Link (downloadBlob()). Der
funktioniert browserübergreifend zuverlässig, ganz ohne Capability-Deklaration
oder Sandkasten-Rücksicht. zeigePDF() (iframe-Vorschau) bleibt nur als letzter
Fallback im Code, falls ein Browser auch den <a download>-Weg verweigert.
Aufbau des Dokuments (buildPDF(scope)), A4 hochkant:
Der Ring wird aus dem SVG heraus in eine Grafik verwandelt. Zwei Fallstricke stecken darin:
var() und
color-mix() überleben das Serialisieren nicht — sonst käme der Ring
schwarz heraus.xlink-Namensraum muss deklariert sein. Die Weltnamen liegen auf
textPath mit xlink:href; ohne xmlns:xlink ist die Grafik kein gültiges
XML und lädt nicht. Genau daran scheiterte der erste Versuch — stillschweigend,
das PDF kam einfach ohne Ring.Für den Druck wird kurz data-theme="light" erzwungen: ein Druckstück ist
immer hell, auch wenn der Bildschirm gerade dunkel steht. Die Farben im PDF
sind fest hinterlegt, nicht aus den CSS-Variablen gelesen.
Fällt jsPDF aus, gibt die Seite ersatzweise ein in sich geschlossenes HTML-Dokument aus, das sich beim Öffnen selbst zum Drucken anbietet.
Dateiname: Kompetenzmatrix-<Kunde>[-Modell]-<JJJJMMTT>.pdf.
Die Druckausgabe ist auf den Kunden zugeschnitten, nicht auf den Vertrieb:
Bedienhinweise (.lead, .hint, .need-hint) fallen weg, das Eckdaten-Formular
ebenso — dessen Inhalt steht schon im Streifen „Im Gespräch notiert". Ein leeres
Kundenfeld verschwindet über :placeholder-shown, statt den Platzhalter zu
drucken. Und main wird im Druck zur Flex-Spalte, damit die Reihenfolge stimmt:
Erklärung → Matrix → Ergebnis, unabhängig von der DOM-Reihenfolge der Reiter.
Gemeinsame Karteien liegen in einer Supabase-Tabelle karteien
(Spalten: id text primary key, doc jsonb, updated_at timestamptz),
angesprochen per einfachem fetch() gegen die REST-API — kein SDK, kein
Build-Schritt, passt zum Rest des Codes.
create table if not exists karteien (
id text primary key,
doc jsonb not null,
updated_at timestamptz not null default now()
);
alter table karteien enable row level security;
create policy "anon all" on karteien for all to anon using (true) with check (true);
Projekt-URL und anon-Key (Supabase-Dashboard → Project Settings → API Keys →
Tab „Legacy anon, service_role API keys" — nicht den neuen „Publishable key"
verwenden, dessen REST-Kompatibilität mit reinem fetch() ungeprüft ist) stehen
direkt im Code (SB_URL, SB_KEY in index.html). Der anon-Key ist zur
Einbettung im Frontend gedacht — Schutz kommt über die Row-Level-Security-Regel
oben, nicht über Geheimhaltung des Keys. Den service_role-Key niemals
verwenden oder committen.
Kostenloser Supabase-Plan reicht für diesen Anwendungsfall (500 MB, weit mehr als genug Text-Karteien). Einzige Besonderheit: Ein kostenloses Projekt pausiert automatisch nach 7 Tagen ganz ohne Zugriff — Daten bleiben erhalten, im Dashboard reicht ein Klick auf „Restore" zum Reaktivieren.
Vor dieser Umstellung lag jede Kartei nur im localStorage des jeweiligen
Browsers (die Claude-Artifact-db-Capability war außerhalb von Claude nie
erreichbar) — nicht teamübergreifend sichtbar. Das ist jetzt behoben.
Versionshistorie der Kartei (Punkt 7 des Ablaufs). Heute überschreibt
Store.put() den letzten Stand; frühere Fassungen sind nicht mehr abrufbar.
Geplant als eigener Schritt.
Der Angebotsgenerator ist ein eigenes Projekt: Repo jasminannii/ppedv-angebotsgenerator
(privat), live unter https://ppedv-angebotsgenerator.vercel.app. Drei Kategorien (öffentliche
Schulung, Inhouse-Workshop A/B, Kompetenzmodell), Dateiname ANG-<Kundennummer>_<Unternehmen>.
Die Matrix kennt nur seine Adresse (ANGEBOT_URL in index.html).
Übergabe aus der Matrix. Im Abschluss kopiert „Link für Angebotsgenerator“ den Link
<ANGEBOT_URL>#matrix=<Daten> und öffnet ihn in einem neuen Tab. Der Generator erstellt daraus
sofort ein Angebot der Kategorie 3 mit Firma, Kursplan (Kurs, Dauer, Woche, Ort, Team,
Teilnehmer, Agenda, Kurslink), Durchführung und vier Phasen mit Wochen. Kunden-Nr., Adresse,
Ansprechpartner, Bestandskunde und Anreise werden im Generator eingetragen. Die Daten stehen hinter dem # und gehen deshalb an keinen Server. Den Link
kann man auch in einen lokal gespeicherten Generator einfügen (Schritt 4 → „Übernehmen“).
Erzeugt wird der Link in matrixFuerAngebot() / angebotLink() (index.html), gelesen in
leseMatrix() / angebotAusMatrix() (im Generator-Repo).
/kompetenzmodell/)Öffentliche Seite für ppedv.de: Kopfbereich ohne Modell, danach drei Ebenen und das
komplette Modell als Ring (außen 6 Welten, innen 18 Kernkompetenzen, Logo in der Mitte;
Klick auf eine Welt hebt ihre Karte hervor) mit Karten je Welt inkl. Beschreibung der
Kernkompetenzen — Daten aus WORLDS der Matrix, und lässt Besucher selbst ein Modell bauen —
bewusst oberflächlich: nur die relevanten Kompetenzwelten antippen, optional Anzahl
Mitarbeitende, Teams und „Was soll besser werden?“ in eigenen Worten, dazu Kontakt. Die
Details erarbeitet ppedv anschließend gemeinsam mit dem Kunden in der Matrix. „Anfrage senden“ öffnet eine fertige E-Mail an [email protected]; Fallback
„Anfrage kopieren“. Ändern sich Welten oder Kernkompetenzen in der Matrix, die Daten in der
Seite (const WELTEN) neu übernehmen.
Einbetten auf ppedv.de (Kopf- und Fußzeile blenden sich im iframe aus, die Höhe passt sich an, „Eigenes Modell bauen“ scrollt die ppedv.de-Seite; - 80 = Höhe einer festen Kopfzeile auf ppedv.de anpassen):
<iframe id="ppedv-km" src="https://ppedv-kompetenzmatrix.vercel.app/kompetenzmodell/"
title="ppedv Kompetenzmodell" style="width:100%;border:0;min-height:900px"></iframe>
<script>
addEventListener("message", e => {
if (e.origin !== "https://ppedv-kompetenzmatrix.vercel.app" || !e.data) return;
const f = document.getElementById("ppedv-km");
if (e.data.ppedvKompetenzmodellHoehe) f.style.height = e.data.ppedvKompetenzmodellHoehe + "px";
if (e.data.ppedvKompetenzmodellScroll != null)
scrollTo({ top: f.getBoundingClientRect().top + scrollY + e.data.ppedvKompetenzmodellScroll - 80, behavior: "smooth" });
});
</script>