{"id":1885,"date":"2025-06-02T16:19:58","date_gmt":"2025-06-02T14:19:58","guid":{"rendered":"https:\/\/regpit.com\/?page_id=1885"},"modified":"2026-04-17T10:40:23","modified_gmt":"2026-04-17T08:40:23","slug":"blog","status":"publish","type":"page","link":"https:\/\/regpit.com\/eng\/blog\/","title":{"rendered":"Blog"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1885\" class=\"elementor elementor-1885\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-697dc44 e-con-full e-flex e-con e-parent\" data-id=\"697dc44\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7ab76f6 elementor-widget elementor-widget-html\" data-id=\"7ab76f6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!--\n  REGPIT Blog-\u00dcbersichtsseite v2\n  ================================\n  Einf\u00fcgen als: Elementor HTML-Widget (volle Breite)\n  Zieht Inhalte aus drei Custom Post Types:\n    - \/wp\/v2\/news       (News)\n    - \/wp\/v2\/blogartikel (Wissen)\n    - \/wp\/v2\/presse      (Presse)\n-->\n\n<style>\n  \/* ========== RESET & BASE ========== *\/\n  .rp-blog * { margin: 0; padding: 0; box-sizing: border-box; }\n\n  .rp-blog {\n    --rp-blue: #0052FF;\n    --rp-blue-light: #e8f0ff;\n    --rp-blue-dark: #0041cc;\n    --rp-dark: #0a0f1e;\n    --rp-gray-900: #111827;\n    --rp-gray-700: #374151;\n    --rp-gray-500: #6b7280;\n    --rp-gray-300: #d1d5db;\n    --rp-gray-100: #f3f4f6;\n    --rp-white: #ffffff;\n    --rp-radius: 12px;\n    --rp-shadow: 0 1px 3px rgba(0,0,0,.06), 0 4px 16px rgba(0,0,0,.04);\n    --rp-shadow-hover: 0 4px 12px rgba(0,0,0,.08), 0 12px 32px rgba(0,0,0,.08);\n    --rp-transition: .3s cubic-bezier(.4,0,.2,1);\n    font-family: inherit;\n    color: var(--rp-gray-900);\n    line-height: 1.6;\n    max-width: 1280px;\n    margin: 0 auto;\n    padding: 0 24px;\n  }\n\n  \/* ========== HEADER ========== *\/\n  .rp-blog__header { text-align: center; padding: 64px 0 48px; }\n\n  .rp-blog__badge {\n    display: inline-flex; align-items: center; gap: 6px;\n    background: var(--rp-blue-light); color: var(--rp-blue);\n    font-size: 13px; font-weight: 600; letter-spacing: .04em;\n    text-transform: uppercase; padding: 6px 16px; border-radius: 100px; margin-bottom: 20px;\n  }\n  .rp-blog__badge::before {\n    content: ''; width: 6px; height: 6px; border-radius: 50%;\n    background: var(--rp-blue); animation: rp-pulse 2s ease-in-out infinite;\n  }\n  @keyframes rp-pulse { 0%,100%{opacity:.4} 50%{opacity:1} }\n\n  .rp-blog__title {\n    font-size: clamp(32px,5vw,52px) !important; font-weight: 800 !important;\n    color: var(--rp-dark) !important; line-height: 1.15 !important;\n    letter-spacing: -.02em; margin-bottom: 16px !important;\n  }\n  .rp-blog__subtitle { font-size: 18px; color: var(--rp-gray-500); max-width: 560px; margin: 0 auto; }\n\n  \/* ========== CONTROLS ========== *\/\n  .rp-blog__controls {\n    display: flex; align-items: center; justify-content: space-between; gap: 20px;\n    flex-wrap: wrap; padding-bottom: 40px; border-bottom: 1px solid var(--rp-gray-100); margin-bottom: 48px;\n  }\n  .rp-blog__filters { display: flex; gap: 4px; background: var(--rp-gray-100); padding: 4px; border-radius: 10px; }\n  .rp-blog__filter-btn {\n    background: transparent !important; border: none !important;\n    padding: 10px 20px !important; font-size: 14px !important; font-weight: 500 !important;\n    color: var(--rp-gray-500) !important; cursor: pointer; border-radius: 8px;\n    transition: var(--rp-transition); white-space: nowrap; font-family: inherit; line-height: 1.4;\n  }\n  .rp-blog__filter-btn:hover { color: var(--rp-gray-700) !important; }\n  .rp-blog__filter-btn.rp-active {\n    background: var(--rp-white) !important; color: var(--rp-dark) !important;\n    font-weight: 600 !important; box-shadow: 0 1px 4px rgba(0,0,0,.08);\n  }\n\n  .rp-blog__search { position: relative; min-width: 260px; }\n  .rp-blog__search-icon {\n    position: absolute; left: 14px; top: 50%; transform: translateY(-50%);\n    width: 18px; height: 18px; color: var(--rp-gray-500); pointer-events: none;\n  }\n  .rp-blog__search-input {\n    width: 100% !important; padding: 11px 16px 11px 42px !important;\n    border: 1.5px solid var(--rp-gray-300) !important; border-radius: 10px !important;\n    font-size: 14px !important; font-family: inherit; color: var(--rp-gray-900) !important;\n    background: var(--rp-white) !important; transition: var(--rp-transition); outline: none;\n  }\n  .rp-blog__search-input:focus { border-color: var(--rp-blue) !important; box-shadow: 0 0 0 3px rgba(0,82,255,.1) !important; }\n  .rp-blog__search-input::placeholder { color: var(--rp-gray-500); }\n\n  \/* ========== FEATURED POST ========== *\/\n  .rp-blog__featured {\n    display: grid; grid-template-columns: 1.15fr 1fr; gap: 0;\n    margin-bottom: 56px; background: var(--rp-gray-100);\n    border-radius: var(--rp-radius); overflow: hidden; transition: var(--rp-transition);\n  }\n  .rp-blog__featured:hover { box-shadow: var(--rp-shadow-hover); }\n  .rp-blog__featured-img { width: 100%; height: 100%; min-height: 360px; object-fit: cover; display: block; }\n  .rp-blog__featured-body { display: flex; flex-direction: column; justify-content: center; padding: 48px; }\n  .rp-blog__featured-cat {\n    display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: .06em;\n    text-transform: uppercase; color: var(--rp-blue); margin-bottom: 16px;\n  }\n  .rp-blog__featured-title {\n    font-size: clamp(22px,3vw,32px) !important; font-weight: 700 !important;\n    color: var(--rp-dark) !important; line-height: 1.25 !important;\n    margin-bottom: 16px !important; letter-spacing: -.01em;\n  }\n  .rp-blog__featured-title a { color: inherit !important; text-decoration: none !important; transition: var(--rp-transition); }\n  .rp-blog__featured-title a:hover { color: var(--rp-blue) !important; }\n  .rp-blog__featured-excerpt {\n    font-size: 16px; color: var(--rp-gray-500); line-height: 1.7; margin-bottom: 24px;\n    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;\n  }\n  .rp-blog__featured-meta { display: flex; align-items: center; gap: 16px; font-size: 13px; color: var(--rp-gray-500); }\n  .rp-blog__featured-date { display: flex; align-items: center; gap: 6px; }\n  .rp-blog__read-link {\n    color: var(--rp-blue) !important; font-weight: 600; text-decoration: none !important;\n    display: inline-flex; align-items: center; gap: 6px; transition: var(--rp-transition);\n  }\n  .rp-blog__read-link:hover { gap: 10px; }\n\n  \/* ========== CARD GRID ========== *\/\n  .rp-blog__grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 28px; }\n  .rp-blog__card {\n    background: var(--rp-white); border-radius: var(--rp-radius); overflow: hidden;\n    border: 1px solid var(--rp-gray-100); transition: var(--rp-transition);\n    display: flex; flex-direction: column;\n    opacity: 0; transform: translateY(20px); animation: rp-fadeUp .5s ease forwards;\n  }\n  @keyframes rp-fadeUp { to { opacity:1; transform:translateY(0); } }\n  .rp-blog__card:hover { box-shadow: var(--rp-shadow-hover); transform: translateY(-4px); border-color: transparent; }\n\n  .rp-blog__card-img-wrap { position: relative; overflow: hidden; aspect-ratio: 16\/10; }\n  .rp-blog__card-img { width:100%; height:100%; object-fit:cover; display:block; transition: transform .5s ease; }\n  .rp-blog__card:hover .rp-blog__card-img { transform: scale(1.05); }\n  .rp-blog__card-cat {\n    position: absolute; top: 14px; left: 14px;\n    background: var(--rp-white); color: var(--rp-blue);\n    font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;\n    padding: 5px 12px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,.1);\n  }\n\n  .rp-blog__card-body { padding: 24px; display: flex; flex-direction: column; flex: 1; }\n  .rp-blog__card-title { font-size: 18px !important; font-weight: 700 !important; color: var(--rp-dark) !important; line-height: 1.35 !important; margin-bottom: 10px !important; }\n  .rp-blog__card-title a { color: inherit !important; text-decoration: none !important; transition: var(--rp-transition); }\n  .rp-blog__card-title a:hover { color: var(--rp-blue) !important; }\n  .rp-blog__card-excerpt {\n    font-size: 14px; color: var(--rp-gray-500); line-height: 1.65; margin-bottom: 20px; flex: 1;\n    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;\n  }\n  .rp-blog__card-footer {\n    display: flex; align-items: center; justify-content: space-between;\n    padding-top: 16px; border-top: 1px solid var(--rp-gray-100);\n  }\n  .rp-blog__card-date { font-size: 13px; color: var(--rp-gray-500); }\n  .rp-blog__card-arrow {\n    width: 32px; height: 32px; border-radius: 50%; background: var(--rp-gray-100);\n    display: flex; align-items: center; justify-content: center;\n    transition: var(--rp-transition); flex-shrink: 0;\n  }\n  .rp-blog__card:hover .rp-blog__card-arrow { background: var(--rp-blue); }\n  .rp-blog__card-arrow svg { width:14px; height:14px; color: var(--rp-gray-500); transition: var(--rp-transition); }\n  .rp-blog__card:hover .rp-blog__card-arrow svg { color: var(--rp-white); }\n\n  \/* ========== LOAD MORE ========== *\/\n  .rp-blog__load-more-wrap { text-align: center; padding: 56px 0 72px; }\n  .rp-blog__load-more {\n    display: inline-flex !important; align-items: center !important; gap: 8px !important;\n    background: var(--rp-dark) !important; color: var(--rp-white) !important;\n    border: none !important; padding: 14px 36px !important; border-radius: 10px !important;\n    font-size: 15px !important; font-weight: 600 !important; font-family: inherit; cursor: pointer;\n    transition: var(--rp-transition);\n  }\n  .rp-blog__load-more:hover { background: var(--rp-blue) !important; transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,82,255,.25); }\n  .rp-blog__load-more:disabled { opacity:.5; cursor:default; transform:none !important; box-shadow:none !important; }\n  .rp-blog__load-more-spinner { display:none; width:18px; height:18px; border:2px solid rgba(255,255,255,.3); border-top-color:#fff; border-radius:50%; animation:rp-spin .6s linear infinite; }\n  @keyframes rp-spin { to{transform:rotate(360deg)} }\n\n  \/* ========== EMPTY STATE ========== *\/\n  .rp-blog__empty { text-align: center; padding: 80px 20px; color: var(--rp-gray-500); }\n  .rp-blog__empty-icon { width:56px; height:56px; margin:0 auto 16px; color: var(--rp-gray-300); }\n  .rp-blog__empty h3 { font-size:20px !important; font-weight:600 !important; color:var(--rp-gray-700) !important; margin-bottom:8px !important; }\n\n  \/* ========== SKELETON ========== *\/\n  .rp-blog__skeleton { border-radius: var(--rp-radius); overflow: hidden; border: 1px solid var(--rp-gray-100); }\n  .rp-skel { background: linear-gradient(90deg,var(--rp-gray-100) 25%,#e9ecf1 50%,var(--rp-gray-100) 75%); background-size:200% 100%; animation:rp-shimmer 1.5s ease-in-out infinite; border-radius:6px; }\n  @keyframes rp-shimmer { to{background-position:-200% 0} }\n  .rp-skel-img { aspect-ratio:16\/10; border-radius:0; }\n  .rp-skel-title { height:22px; width:80%; margin:24px 24px 12px; }\n  .rp-skel-text { height:14px; width:95%; margin:0 24px 8px; }\n  .rp-skel-text2 { height:14px; width:60%; margin:0 24px 24px; }\n\n  \/* ========== RESPONSIVE ========== *\/\n  @media (max-width:960px) {\n    .rp-blog__grid { grid-template-columns: repeat(2,1fr); }\n    .rp-blog__featured { grid-template-columns: 1fr; }\n    .rp-blog__featured-body { padding: 32px; }\n    .rp-blog__featured-img { min-height: 260px; }\n  }\n  @media (max-width:640px) {\n    .rp-blog { padding: 0 16px; }\n    .rp-blog__header { padding: 40px 0 32px; }\n    .rp-blog__grid { grid-template-columns: 1fr; }\n    .rp-blog__controls { flex-direction: column; align-items: stretch; }\n    .rp-blog__search { min-width: unset; }\n    .rp-blog__filters { overflow-x: auto; -webkit-overflow-scrolling: touch; }\n    .rp-blog__featured-body { padding: 24px; }\n  }\n<\/style>\n\n<div class=\"rp-blog\">\n  <div class=\"rp-blog__header\">\n    <div class=\"rp-blog__badge\">Blog<\/div>\n    <h1 class=\"rp-blog__title\">Insights & Neuigkeiten<\/h1>\n    <p class=\"rp-blog__subtitle\">Aktuelles zu AML-Compliance, Regulatorik und Regpit \u2014 kompakt und praxisnah.<\/p>\n  <\/div>\n\n  <div class=\"rp-blog__controls\">\n    <div class=\"rp-blog__filters\" id=\"rpFilters\">\n      <button class=\"rp-blog__filter-btn rp-active\" data-type=\"all\">Alle<\/button>\n      <button class=\"rp-blog__filter-btn\" data-type=\"news\">News<\/button>\n      <button class=\"rp-blog__filter-btn\" data-type=\"blogartikel\">Wissen<\/button>\n      <button class=\"rp-blog__filter-btn\" data-type=\"presse\">Presse<\/button>\n    <\/div>\n    <div class=\"rp-blog__search\">\n      <svg class=\"rp-blog__search-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\"\/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"\/><\/svg>\n      <input type=\"text\" class=\"rp-blog__search-input\" id=\"rpSearch\" placeholder=\"Beitr\u00e4ge durchsuchen\u2026\">\n    <\/div>\n  <\/div>\n\n  <div class=\"rp-blog__featured\" id=\"rpFeatured\" style=\"display:none;\"><\/div>\n  <div class=\"rp-blog__grid\" id=\"rpGrid\"><\/div>\n\n  <div class=\"rp-blog__empty\" id=\"rpEmpty\" style=\"display:none;\">\n    <svg class=\"rp-blog__empty-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"><path d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"\/><\/svg>\n    <h3>Keine Beitr\u00e4ge gefunden<\/h3>\n    <p>Versuchen Sie eine andere Kategorie oder einen anderen Suchbegriff.<\/p>\n  <\/div>\n\n  <div class=\"rp-blog__load-more-wrap\" id=\"rpLoadMoreWrap\" style=\"display:none;\">\n    <button class=\"rp-blog__load-more\" id=\"rpLoadMore\">\n      Weitere Beitr\u00e4ge laden\n      <span class=\"rp-blog__load-more-spinner\" id=\"rpSpinner\"><\/span>\n    <\/button>\n  <\/div>\n<\/div>\n\n<script>\n(function() {\n  'use strict';\n\n  \/* ======================================================\n     KONFIGURATION\n     ====================================================== *\/\n  const CONFIG = {\n    apiBase: window.location.origin + '\/wp-json\/wp\/v2',\n    perPage: 9,\n    \/\/ Eure drei Custom Post Types mit ihren REST-Endpunkten und Labels\n    postTypes: {\n      news:         { endpoint: 'news',         label: 'News' },\n      blogartikel:  { endpoint: 'blogartikel',  label: 'Wissen' },\n      presse:       { endpoint: 'presse',       label: 'Presse' }\n    },\n    fallbackImage: 'data:image\/svg+xml,' + encodeURIComponent(\n      '<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"800\" height=\"500\" fill=\"%23f3f4f6\">' +\n      '<rect width=\"800\" height=\"500\"\/>' +\n      '<text x=\"400\" y=\"260\" text-anchor=\"middle\" fill=\"%23d1d5db\" font-size=\"18\" font-family=\"sans-serif\">Kein Bild<\/text><\/svg>'\n    )\n  };\n\n  \/* ======================================================\n     STATE\n     ====================================================== *\/\n  let state = {\n    activeType: 'all',\n    searchTerm: '',\n    \/\/ Pro Post-Type eigene Pagination\n    pages: { news: 1, blogartikel: 1, presse: 1 },\n    totalPages: { news: 1, blogartikel: 1, presse: 1 },\n    allPosts: [],       \/\/ Aktuell angezeigte Posts (gemerged + sortiert)\n    displayedCount: 0,  \/\/ Wie viele schon angezeigt\n    loading: false\n  };\n\n  \/* ======================================================\n     DOM\n     ====================================================== *\/\n  const $ = (sel) => document.querySelector(sel);\n  const grid      = $('#rpGrid');\n  const featured  = $('#rpFeatured');\n  const emptyEl   = $('#rpEmpty');\n  const loadWrap  = $('#rpLoadMoreWrap');\n  const loadBtn   = $('#rpLoadMore');\n  const spinner   = $('#rpSpinner');\n  const searchIn  = $('#rpSearch');\n  const filters   = $('#rpFilters');\n\n  \/* ======================================================\n     HELPERS\n     ====================================================== *\/\n  function stripHTML(html) {\n    const tmp = document.createElement('div');\n    tmp.innerHTML = html || '';\n    return tmp.textContent || tmp.innerText || '';\n  }\n\n  function formatDate(dateStr) {\n    return new Date(dateStr).toLocaleDateString('de-DE', {\n      day: 'numeric', month: 'long', year: 'numeric'\n    });\n  }\n\n  function getFeaturedImage(post) {\n    try {\n      const media = post._embedded?.['wp:featuredmedia']?.[0];\n      \/\/ Debug: zeigt in der Konsole was geladen wird\n      console.log('[Regpit Blog] Bild f\u00fcr \"' + stripHTML(post.title?.rendered) + '\":', \n        media ? (media.source_url || 'media vorhanden aber keine source_url') : 'kein _embedded media',\n        '| featured_media ID:', post.featured_media);\n      if (media && media.source_url) {\n        return media.media_details?.sizes?.medium_large?.source_url\n            || media.media_details?.sizes?.large?.source_url\n            || media.source_url;\n      }\n    } catch(e) { console.error('[Regpit Blog] Bild-Fehler:', e); }\n    return CONFIG.fallbackImage;\n  }\n\n  function hasImage(post) {\n    try {\n      return post.featured_media > 0\n          && post._embedded?.['wp:featuredmedia']?.[0]?.source_url;\n    } catch(e) { return false; }\n  }\n\n  \/\/ onerror-Handler: Fallback-Bild bei gebrochenem Bild\n  const IMG_ONERROR = `onerror=\"this.onerror=null;this.src='${CONFIG.fallbackImage}'\"`;\n\n  function getExcerpt(post, maxLen) {\n    maxLen = maxLen || 150;\n    \/\/ Versuche erst excerpt, dann content\n    let text = stripHTML(post.excerpt?.rendered || '');\n    if (!text) text = stripHTML(post.content?.rendered || '');\n    if (text.length > maxLen) text = text.substring(0, maxLen).trim() + '\u2026';\n    return text;\n  }\n\n  function getTypeLabel(post) {\n    \/\/ _rpType wird beim Fetchen gesetzt\n    const pt = CONFIG.postTypes[post._rpType];\n    return pt ? pt.label : 'Beitrag';\n  }\n\n  \/* ======================================================\n     SKELETON\n     ====================================================== *\/\n  function showSkeletons(count) {\n    grid.innerHTML = Array.from({ length: count || 9 }, () => `\n      <div class=\"rp-blog__skeleton\">\n        <div class=\"rp-skel rp-skel-img\"><\/div>\n        <div class=\"rp-skel rp-skel-title\"><\/div>\n        <div class=\"rp-skel rp-skel-text\"><\/div>\n        <div class=\"rp-skel rp-skel-text2\"><\/div>\n      <\/div>\n    `).join('');\n  }\n\n  \/* ======================================================\n     RENDER\n     ====================================================== *\/\n  function renderFeatured(post) {\n    if (!post) { featured.style.display = 'none'; return; }\n    const img = getFeaturedImage(post);\n    const label = getTypeLabel(post);\n    featured.style.display = 'grid';\n    featured.innerHTML = `\n      <img decoding=\"async\" class=\"rp-blog__featured-img\" src=\"${img}\" alt=\"${stripHTML(post.title.rendered)}\" loading=\"eager\" ${IMG_ONERROR}>\n      <div class=\"rp-blog__featured-body\">\n        <span class=\"rp-blog__featured-cat\">${label}<\/span>\n        <h2 class=\"rp-blog__featured-title\"><a href=\"${post.link}\">${post.title.rendered}<\/a><\/h2>\n        <p class=\"rp-blog__featured-excerpt\">${getExcerpt(post, 220)}<\/p>\n        <div class=\"rp-blog__featured-meta\">\n          <span class=\"rp-blog__featured-date\">\n            <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"\/><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"\/><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"\/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"\/><\/svg>\n            ${formatDate(post.date)}\n          <\/span>\n          <a href=\"${post.link}\" class=\"rp-blog__read-link\">Weiterlesen <span>\u2192<\/span><\/a>\n        <\/div>\n      <\/div>`;\n  }\n\n  function renderCard(post, index) {\n    const img = getFeaturedImage(post);\n    const label = getTypeLabel(post);\n    return `\n      <article class=\"rp-blog__card\" style=\"animation-delay:${index * .07}s\">\n        <a href=\"${post.link}\" style=\"text-decoration:none;color:inherit;display:flex;flex-direction:column;flex:1;\">\n          <div class=\"rp-blog__card-img-wrap\">\n            <img decoding=\"async\" class=\"rp-blog__card-img\" src=\"${img}\" alt=\"${stripHTML(post.title.rendered)}\" loading=\"lazy\" ${IMG_ONERROR}>\n            <span class=\"rp-blog__card-cat\">${label}<\/span>\n          <\/div>\n          <div class=\"rp-blog__card-body\">\n            <h3 class=\"rp-blog__card-title\">${post.title.rendered}<\/h3>\n            <p class=\"rp-blog__card-excerpt\">${getExcerpt(post)}<\/p>\n            <div class=\"rp-blog__card-footer\">\n              <span class=\"rp-blog__card-date\">${formatDate(post.date)}<\/span>\n              <span class=\"rp-blog__card-arrow\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"\/><polyline points=\"12 5 19 12 12 19\"\/><\/svg>\n              <\/span>\n            <\/div>\n          <\/div>\n        <\/a>\n      <\/article>`;\n  }\n\n  function renderAll() {\n    const posts = state.allPosts;\n    const isFirstLoad = state.displayedCount === 0;\n    const showFeatured = isFirstLoad && !state.searchTerm && state.activeType === 'all';\n\n    if (posts.length === 0) {\n      grid.innerHTML = '';\n      featured.style.display = 'none';\n      emptyEl.style.display = 'block';\n      loadWrap.style.display = 'none';\n      return;\n    }\n\n    emptyEl.style.display = 'none';\n\n    let gridPosts = posts;\n    if (showFeatured) {\n      \/\/ Finde den ersten Post MIT Bild f\u00fcr den Featured-Platz\n      const featIdx = posts.findIndex(p => hasImage(p));\n      if (featIdx !== -1) {\n        renderFeatured(posts[featIdx]);\n        gridPosts = posts.filter((_, i) => i !== featIdx);\n      } else {\n        \/\/ Kein Post mit Bild \u2192 Featured \u00fcberspringen\n        featured.style.display = 'none';\n      }\n    } else {\n      featured.style.display = 'none';\n    }\n\n    grid.innerHTML = gridPosts.map((p, i) => renderCard(p, i)).join('');\n    state.displayedCount = posts.length;\n\n    \/\/ Gibt es noch mehr?\n    const hasMore = hasMorePosts();\n    loadWrap.style.display = hasMore ? '' : 'none';\n  }\n\n  function appendCards(newPosts) {\n    const startIdx = grid.children.length;\n    const html = newPosts.map((p, i) => renderCard(p, startIdx + i)).join('');\n    grid.insertAdjacentHTML('beforeend', html);\n    state.displayedCount = state.allPosts.length;\n\n    const hasMore = hasMorePosts();\n    loadWrap.style.display = hasMore ? '' : 'none';\n  }\n\n  \/* ======================================================\n     API - Fetch von einem oder mehreren Endpoints\n     ====================================================== *\/\n  async function fetchFromEndpoint(typeKey, page, search) {\n    const pt = CONFIG.postTypes[typeKey];\n    if (!pt) return [];\n\n    let url = `${CONFIG.apiBase}\/${pt.endpoint}?_embed=true&per_page=${CONFIG.perPage}&page=${page}`;\n    if (search) url += `&search=${encodeURIComponent(search)}`;\n\n    try {\n      const res = await fetch(url);\n      if (!res.ok) return [];\n      state.totalPages[typeKey] = parseInt(res.headers.get('X-WP-TotalPages') || '1');\n      const posts = await res.json();\n      \/\/ Markiere jeden Post mit seinem Typ\n      posts.forEach(p => p._rpType = typeKey);\n\n      \/\/ Fallback: Falls _embedded fehlt, Bilder einzeln nachladen\n      await Promise.all(posts.map(async (post) => {\n        if (post.featured_media > 0 && !post._embedded?.['wp:featuredmedia']?.[0]?.source_url) {\n          console.log('[Regpit Blog] Lade Bild separat nach f\u00fcr:', stripHTML(post.title?.rendered));\n          try {\n            const mediaRes = await fetch(`${CONFIG.apiBase}\/media\/${post.featured_media}`);\n            if (mediaRes.ok) {\n              const media = await mediaRes.json();\n              if (!post._embedded) post._embedded = {};\n              post._embedded['wp:featuredmedia'] = [media];\n            }\n          } catch(e) { \/* Bild konnte nicht geladen werden *\/ }\n        }\n      }));\n\n      return posts;\n    } catch(e) {\n      console.warn('Regpit Blog: Fehler beim Laden von ' + typeKey, e);\n      return [];\n    }\n  }\n\n  \/\/ Holt Posts von allen relevanten Endpunkten\n  async function fetchPosts(isLoadMore) {\n    if (state.loading) return;\n    state.loading = true;\n    loadBtn.disabled = true;\n    spinner.style.display = 'inline-block';\n\n    if (!isLoadMore) {\n      showSkeletons();\n      \/\/ Reset Pagination\n      Object.keys(state.pages).forEach(k => state.pages[k] = 1);\n      state.allPosts = [];\n      state.displayedCount = 0;\n    }\n\n    const search = state.searchTerm;\n    const activeType = state.activeType;\n\n    \/\/ Bestimme welche Endpoints abgefragt werden\n    const typesToFetch = activeType === 'all'\n      ? Object.keys(CONFIG.postTypes)\n      : [activeType];\n\n    \/\/ Parallel fetchen\n    const promises = typesToFetch.map(typeKey => {\n      const page = isLoadMore ? state.pages[typeKey] + 1 : 1;\n      \/\/ Nur fetchen wenn noch Seiten \u00fcbrig\n      if (isLoadMore && state.pages[typeKey] >= state.totalPages[typeKey]) {\n        return Promise.resolve([]);\n      }\n      return fetchFromEndpoint(typeKey, page, search).then(posts => {\n        if (posts.length > 0) {\n          state.pages[typeKey] = isLoadMore ? state.pages[typeKey] + 1 : 1;\n        }\n        return posts;\n      });\n    });\n\n    const results = await Promise.all(promises);\n    const newPosts = results.flat();\n\n    \/\/ Nach Datum sortieren (neueste zuerst)\n    newPosts.sort((a, b) => new Date(b.date) - new Date(a.date));\n\n    if (isLoadMore) {\n      state.allPosts = state.allPosts.concat(newPosts);\n      appendCards(newPosts);\n    } else {\n      state.allPosts = newPosts;\n      renderAll();\n    }\n\n    state.loading = false;\n    loadBtn.disabled = false;\n    spinner.style.display = 'none';\n  }\n\n  function hasMorePosts() {\n    const typesToCheck = state.activeType === 'all'\n      ? Object.keys(CONFIG.postTypes)\n      : [state.activeType];\n\n    return typesToCheck.some(t => state.pages[t] < state.totalPages[t]);\n  }\n\n  \/* ======================================================\n     EVENTS\n     ====================================================== *\/\n  filters.addEventListener('click', (e) => {\n    const btn = e.target.closest('.rp-blog__filter-btn');\n    if (!btn) return;\n    filters.querySelectorAll('.rp-blog__filter-btn').forEach(b => b.classList.remove('rp-active'));\n    btn.classList.add('rp-active');\n    state.activeType = btn.dataset.type;\n    fetchPosts(false);\n  });\n\n  let searchTimeout;\n  searchIn.addEventListener('input', () => {\n    clearTimeout(searchTimeout);\n    searchTimeout = setTimeout(() => {\n      state.searchTerm = searchIn.value.trim();\n      fetchPosts(false);\n    }, 400);\n  });\n\n  loadBtn.addEventListener('click', () => fetchPosts(true));\n\n  \/* ======================================================\n     INIT\n     ====================================================== *\/\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => fetchPosts(false));\n  } else {\n    fetchPosts(false);\n  }\n\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Blog Insights &#038; Neuigkeiten Aktuelles zu AML-Compliance, Regulatorik und Regpit \u2014 kompakt und praxisnah. Alle News Wissen Presse Keine Beitr\u00e4ge gefunden Versuchen Sie eine andere Kategorie oder einen anderen Suchbegriff. Weitere Beitr\u00e4ge laden<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"class_list":["post-1885","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/pages\/1885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/comments?post=1885"}],"version-history":[{"count":25,"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/pages\/1885\/revisions"}],"predecessor-version":[{"id":9237,"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/pages\/1885\/revisions\/9237"}],"wp:attachment":[{"href":"https:\/\/regpit.com\/eng\/wp-json\/wp\/v2\/media?parent=1885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}