{"id":46963,"date":"2025-11-01T17:30:09","date_gmt":"2025-11-01T16:30:09","guid":{"rendered":"https:\/\/blickpunkt-lokalsport.de\/?page_id=46963"},"modified":"2026-04-09T12:02:59","modified_gmt":"2026-04-09T10:02:59","slug":"fototermin-uebersicht","status":"publish","type":"page","link":"https:\/\/blickpunkt-lokalsport.de\/english\/fototermin-uebersicht\/","title":{"rendered":"Fototermin \u00dcbersicht"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"46963\" class=\"elementor elementor-46963\" data-elementor-settings=\"{&quot;element_pack_global_tooltip_width&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;element_pack_global_tooltip_width_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;element_pack_global_tooltip_width_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;element_pack_global_tooltip_padding&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_padding_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_padding_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_border_radius&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_border_radius_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true},&quot;element_pack_global_tooltip_border_radius_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;top&quot;:&quot;&quot;,&quot;right&quot;:&quot;&quot;,&quot;bottom&quot;:&quot;&quot;,&quot;left&quot;:&quot;&quot;,&quot;isLinked&quot;:true}}\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5af5c87c e-con-full e-flex e-con e-parent\" data-id=\"5af5c87c\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-619960e6 elementor-widget elementor-widget-bdt-advanced-heading\" data-id=\"619960e6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"bdt-advanced-heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"619960e6\" class=\"bdt-ep-advanced-heading\" data-settings=\"{&quot;titleMultiColor&quot;:&quot;no&quot;}\"><div class=\"bdt-ep-advanced-heading-content bdt-visible@m\"><div class=\"bdt-transform-origin-top-left\">Fototermine<\/div><\/div><div class=\"bdt-ep-advanced-heading-sub-title\"><div class=\"bdt-ep-advanced-heading-sub-title-content\">Alles im Blick<\/div><\/div><h2 class=\"bdt-ep-advanced-heading-title\"><span class=\"bdt-ep-advanced-heading-main-title\"><span class=\"bdt-ep-advanced-heading-main-title-inner\">Fototermin-\u00dcbersicht<\/span><\/span><\/h2><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a56d64f e-con-full e-flex e-con e-parent\" data-id=\"a56d64f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e97f0c1 elementor-widget elementor-widget-spacer\" data-id=\"e97f0c1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b9928c6 e-con-full e-flex e-con e-parent\" data-id=\"b9928c6\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-14d3143 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"14d3143\" 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<!DOCTYPE html>\r\n<html lang=\"de\">\r\n<head>\r\n  <meta charset=\"UTF-8\" \/>\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\r\n  <title>Fototermine<\/title>\r\n  <style>\r\n    :root {\r\n      --color-primary: #023859;\r\n      --color-secondary: #800000;\r\n      --color-accent: #32b8c6;\r\n      --color-bg: #f8f8f8;\r\n      --color-surface: #f8f8f8;\r\n      --color-text: #1f2121;\r\n      --color-text-secondary: #626c71;\r\n      --color-border: #d0d0d0;\r\n      --color-border-bg: rgba(208,208,208,0.25);\r\n      --color-success: #1e7f3b;\r\n      --color-warning: #e68900;\r\n      --color-planned: #1a67c7;\r\n      --radius-sm: 8px;\r\n      --radius-md: 12px;\r\n      --radius-lg: 16px;\r\n      --shadow-sm: 0 1px 3px rgba(0,0,0,0.06);\r\n      --shadow-md: 0 4px 14px rgba(0,0,0,0.1);\r\n      box-sizing: border-box;\r\n      margin: 0;\r\n      padding: 0;\r\n    }\r\n\r\n    *, *::before, *::after {\r\n      box-sizing: inherit;\r\n    }\r\n\r\n    body {\r\n      font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\r\n      background: var(--color-bg);\r\n      color: var(--color-text);\r\n      padding: 2rem 1rem;\r\n      line-height: 1.5;\r\n      min-height: 100vh;\r\n      overflow-x: hidden;\r\n    }\r\n\r\n    .container {\r\n      max-width: 100%;\r\n      margin: 0 auto;\r\n    }\r\n\r\n    .header {\r\n      background: linear-gradient(135deg, #ffffff, #f0f2f5);\r\n      border-radius: var(--radius-lg);\r\n      padding: 1.6rem 2rem;\r\n      margin-bottom: 2rem;\r\n      display: flex;\r\n      flex-direction: column;\r\n      gap: 0.75rem;\r\n      color: var(--color-text);\r\n      box-shadow: var(--shadow-md);\r\n      border: 1px solid rgba(94,82,64,0.16);\r\n    }\r\n\r\n    .header-content {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: flex-start;\r\n      gap: 1rem;\r\n      flex-wrap: wrap;\r\n    }\r\n\r\n    .header-left {\r\n      display: flex;\r\n      flex-direction: column;\r\n      gap: 0.25rem;\r\n      max-width: 40rem;\r\n    }\r\n\r\n    .header-label {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      gap: 0.4rem;\r\n      font-size: 0.78rem;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.12em;\r\n      color: var(--color-text-secondary);\r\n      padding: 0.2rem 0.75rem;\r\n      border-radius: 999px;\r\n      background: rgba(2,56,89,0.06);\r\n      border: 1px solid rgba(2,56,89,0.16);\r\n    }\r\n\r\n    .header-label-dot {\r\n      width: 8px;\r\n      height: 8px;\r\n      border-radius: 999px;\r\n      background: var(--color-secondary);\r\n    }\r\n\r\n    .header-subline {\r\n      margin-top: 0.35rem;\r\n      font-size: 0.9rem;\r\n      color: var(--color-text-secondary);\r\n      max-width: 40rem;\r\n    }\r\n\r\n    .status-badge-modern {\r\n      display: inline-flex;\r\n      align-items: flex-start;\r\n      gap: 0.8rem;\r\n      padding: 0.4rem 0.7rem;\r\n      border-radius: 14px;\r\n      background: linear-gradient(135deg, rgba(2,56,89,0.05), rgba(2,56,89,0.01));\r\n      border: 1px solid rgba(2,56,89,0.14);\r\n      box-shadow: 0 2px 8px rgba(0,0,0,0.05);\r\n      max-width: 100%;\r\n    }\r\n\r\n    .status-main {\r\n      display: inline-flex;\r\n      flex-direction: column;\r\n      gap: 0.35rem;\r\n      align-items: flex-start;\r\n    }\r\n\r\n    .status-title {\r\n      font-size: 0.75rem;\r\n      font-weight: 600;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.11em;\r\n      color: var(--color-text-secondary);\r\n    }\r\n\r\n    .status-right {\r\n      display: flex;\r\n      flex-direction: column;\r\n      align-items: flex-end;\r\n      gap: 0.35rem;\r\n    }\r\n\r\n    .status-meta {\r\n      display: flex;\r\n      flex-direction: column;\r\n      min-width: 0;\r\n      align-items: flex-end;\r\n      text-align: right;\r\n    }\r\n\r\n    .status-text-main {\r\n      font-size: 0.78rem;\r\n      font-weight: 600;\r\n      color: var(--color-primary);\r\n      line-height: 1.25;\r\n      margin-bottom: 0.05rem;\r\n    }\r\n\r\n    .status-text-sub {\r\n      font-size: 0.7rem;\r\n      color: var(--color-text-secondary);\r\n      line-height: 1.2;\r\n    }\r\n\r\n    .status-progress {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      gap: 0.4rem;\r\n    }\r\n\r\n    .status-progress-bar {\r\n      width: 90px;\r\n      height: 4px;\r\n      border-radius: 999px;\r\n      background: rgba(2,56,89,0.15);\r\n      overflow: hidden;\r\n    }\r\n\r\n    .status-progress-inner {\r\n      height: 100%;\r\n      width: 0%;\r\n      border-radius: 999px;\r\n      background: linear-gradient(90deg, #32b8c6, #027a88);\r\n      transition: width 0.25s ease-out;\r\n    }\r\n\r\n    .status-progress-text {\r\n      font-size: 0.7rem;\r\n      color: var(--color-text-secondary);\r\n      min-width: 2.6rem;\r\n      text-align: right;\r\n    }\r\n\r\n    .status-reload-btn {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      gap: 0.25rem;\r\n      padding: 0.3rem 0.65rem;\r\n      border-radius: 999px;\r\n      border: none;\r\n      background: linear-gradient(135deg, #800000, #b01616);\r\n      color: #ffffff;\r\n      font-size: 0.75rem;\r\n      font-weight: 600;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.06em;\r\n      box-shadow: 0 3px 8px rgba(128,0,0,0.22);\r\n      cursor: pointer;\r\n      white-space: nowrap;\r\n      transition: transform 0.1s ease, box-shadow 0.1s ease, background 0.2s ease;\r\n    }\r\n\r\n    .status-reload-btn:hover {\r\n      background: linear-gradient(135deg, #b01616, #d22020);\r\n      transform: translateY(-1px);\r\n      box-shadow: 0 4px 10px rgba(128,0,0,0.28);\r\n    }\r\n\r\n    .status-reload-btn:active {\r\n      transform: translateY(0);\r\n      box-shadow: 0 2px 6px rgba(128,0,0,0.22);\r\n    }\r\n\r\n    .status-reload-icon {\r\n      font-size: 0.85rem;\r\n    }\r\n\r\n    @media (max-width: 600px) {\r\n      .status-badge-modern {\r\n        padding: 0.35rem 0.5rem;\r\n        gap: 0.45rem;\r\n        flex-wrap: wrap;\r\n      }\r\n      .status-right {\r\n        width: 100%;\r\n        align-items: flex-start;\r\n      }\r\n      .status-meta {\r\n        align-items: flex-start;\r\n        text-align: left;\r\n      }\r\n      .status-progress {\r\n        width: 100%;\r\n      }\r\n      .status-progress-bar {\r\n        flex: 1 1 auto;\r\n      }\r\n    }\r\n\r\n    .farblegende {\r\n      display: flex;\r\n      gap: 1.2rem;\r\n      margin-bottom: 1.5rem;\r\n      font-size: 0.9rem;\r\n      flex-wrap: wrap;\r\n    }\r\n\r\n    .farbitem {\r\n      display: flex;\r\n      align-items: center;\r\n      gap: 0.5rem;\r\n      color: var(--color-text-secondary);\r\n    }\r\n\r\n    .farbicon {\r\n      border-radius: 6px;\r\n      display: inline-block;\r\n      height: 16px;\r\n      width: 24px;\r\n      box-shadow: 0 0 0 1px rgba(0,0,0,0.18);\r\n    }\r\n\r\n    .farbicon.bestellt { background: linear-gradient(135deg, #2ecc71, #1e7f3b); }\r\n    .farbicon.vorgemerkt { background: linear-gradient(135deg, #ffb347, #e68900); }\r\n    .farbicon.neue-anfrage { background: linear-gradient(135deg, #ff8ac6, #e64b9b); }\r\n    .farbicon.geplant { background: linear-gradient(135deg, #4fa3ff, #1a67c7); }\r\n\r\n    .card {\r\n      background-color: var(--color-surface);\r\n      border-radius: var(--radius-lg);\r\n      box-shadow: var(--shadow-sm);\r\n      padding: 1.6rem 1.4rem;\r\n      border: 1px solid var(--color-border);\r\n      margin-bottom: 2rem;\r\n    }\r\n\r\n    .card-header {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      border-bottom: 2px solid var(--color-border);\r\n      margin-bottom: 1.5rem;\r\n      padding-bottom: 1rem;\r\n      align-items: center;\r\n      gap: 1rem;\r\n      flex-wrap: wrap;\r\n    }\r\n\r\n    .card-title {\r\n      display: flex;\r\n      gap: 0.75rem;\r\n      font-weight: 800;\r\n      font-size: 1.5rem;\r\n      color: var(--color-primary);\r\n      align-items: center;\r\n      flex-wrap: wrap;\r\n    }\r\n\r\n    .card-title::before {\r\n      content: \"\";\r\n      display: inline-block;\r\n      width: 4px;\r\n      height: 22px;\r\n      background-color: var(--color-secondary);\r\n      border-radius: 2px;\r\n    }\r\n\r\n    .vorschlag-counter-badge {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      padding: 0.2rem;\r\n      border-radius: 999px;\r\n      background: rgba(2,56,89,0.08);\r\n      border: 1px solid rgba(2,56,89,0.35);\r\n    }\r\n\r\n    .vorschlag-counter-number {\r\n      min-width: 1.4rem;\r\n      height: 1.4rem;\r\n      border-radius: 999px;\r\n      background: rgba(2,56,89,0.15);\r\n      border: 1px solid rgba(2,56,89,0.4);\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      font-size: 0.78rem;\r\n      font-weight: 700;\r\n      color: var(--color-primary);\r\n    }\r\n\r\n    .filters {\r\n      display: grid;\r\n      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\r\n      gap: 1rem;\r\n      margin-bottom: 1.5rem;\r\n    }\r\n\r\n    .filter-group {\r\n      display: flex;\r\n      flex-direction: column;\r\n      gap: 0.4rem;\r\n    }\r\n\r\n    .filter-label {\r\n      font-weight: 600;\r\n      color: var(--color-text-secondary);\r\n      font-size: 0.8rem;\r\n      letter-spacing: 0.06em;\r\n      text-transform: uppercase;\r\n    }\r\n\r\n    select,\r\n    input[type=\"date\"],\r\n    button {\r\n      border-radius: var(--radius-sm);\r\n      font-size: 0.95rem;\r\n      font-family: inherit;\r\n      padding: 0.6rem 0.9rem;\r\n      border: 1px solid var(--color-border);\r\n      background-color: #ffffff;\r\n      color: #1f2121;\r\n      cursor: pointer;\r\n      transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease, transform 0.1s ease;\r\n      width: 100%;\r\n    }\r\n\r\n    select:hover,\r\n    input[type=\"date\"]:hover {\r\n      border-color: var(--color-accent);\r\n    }\r\n\r\n    select:focus,\r\n    input[type=\"date\"]:focus {\r\n      border-color: var(--color-primary);\r\n      box-shadow: 0 0 0 2px rgba(2,56,89,0.16);\r\n      outline: none;\r\n    }\r\n\r\n    button {\r\n      font-weight: 700;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.08em;\r\n      border: none;\r\n      background: linear-gradient(135deg, #800000, #b01616);\r\n      color: #ffffff;\r\n      box-shadow: var(--shadow-sm);\r\n    }\r\n\r\n    button:hover:not(:disabled) {\r\n      background: linear-gradient(135deg, #b01616, #d22020);\r\n      box-shadow: var(--shadow-md);\r\n      transform: translateY(-1px);\r\n    }\r\n\r\n    button:active:not(:disabled) { transform: translateY(0); }\r\n\r\n    button:disabled {\r\n      cursor: not-allowed;\r\n      background-color: #e0e0e0;\r\n      color: #999999;\r\n      box-shadow: none;\r\n    }\r\n\r\n    .btn-compact {\r\n      font-size: 0.8rem;\r\n      padding: 0.45rem 0.7rem;\r\n      letter-spacing: 0.05em;\r\n    }\r\n\r\n    .table-mobile {\r\n      display: grid;\r\n      gap: 0.8rem;\r\n      margin-top: 0.5rem;\r\n      grid-template-columns: 1fr;\r\n    }\r\n\r\n    .mobile-card {\r\n      border-radius: var(--radius-md);\r\n      border: 1px solid var(--color-border);\r\n      background: var(--color-border-bg);\r\n      padding: 0.85rem 0.9rem;\r\n      box-shadow: var(--shadow-sm);\r\n      display: flex;\r\n      flex-direction: column;\r\n      gap: 0.4rem;\r\n      font-size: 0.9rem;\r\n      transition: background-color 0.2s ease, box-shadow 0.2s ease, transform 0.1s ease;\r\n      position: relative;\r\n      overflow: hidden;\r\n    }\r\n\r\n    .mobile-card:hover {\r\n      box-shadow: var(--shadow-md);\r\n      transform: translateY(-1px);\r\n    }\r\n\r\n    .mobile-card.status-gebucht      { background: rgba(46,204,113,0.10); }\r\n    .mobile-card.status-geplant      { background: rgba(79,163,255,0.10); }\r\n    .mobile-card.status-neue-anfrage {\r\n      background: rgba(255,138,198,0.08);\r\n      box-shadow: 0 0 0 1px rgba(230,75,155,0.85);\r\n    }\r\n\r\n    .mobile-card-header-line {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      gap: 0.5rem;\r\n      font-weight: 600;\r\n      color: var(--color-primary);\r\n      align-items: center;\r\n      flex-wrap: wrap;\r\n      width: 100%;\r\n    }\r\n\r\n    .mobile-card-header-main {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      gap: 0.4rem;\r\n    }\r\n\r\n    .mobile-card-index {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      min-width: 1.6rem;\r\n      height: 1.6rem;\r\n      padding: 0 0.4rem;\r\n      border-radius: 999px;\r\n      background: rgba(2,56,89,0.12);\r\n      color: var(--color-primary);\r\n      font-size: 0.8rem;\r\n      font-weight: 700;\r\n    }\r\n\r\n    .mobile-card-meta {\r\n      display: flex;\r\n      justify-content: flex-start;\r\n      gap: 1rem;\r\n      color: var(--color-text-secondary);\r\n      font-size: 0.8rem;\r\n      flex-wrap: wrap;\r\n    }\r\n\r\n    .mobile-chip {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      border-radius: 999px;\r\n      padding: 0.1rem 0.6rem;\r\n      font-size: 0.75rem;\r\n      font-weight: 600;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.06em;\r\n      color: #ffffff;\r\n      white-space: nowrap;\r\n      max-width: 100%;\r\n    }\r\n\r\n    .mobile-chip.success { background: linear-gradient(135deg, #2ecc71, #1e7f3b); }\r\n    .mobile-chip.warning { background: linear-gradient(135deg, #ffb347, #e68900); }\r\n    .mobile-chip.planned { background: linear-gradient(135deg, #4fa3ff, #1a67c7); }\r\n    .mobile-chip.request {\r\n      background: linear-gradient(135deg, #ff8ac6, #e64b9b);\r\n      color: #ffffff;\r\n    }\r\n\r\n    .mobile-label {\r\n      font-size: 0.78rem;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.06em;\r\n      color: var(--color-text-secondary);\r\n    }\r\n\r\n    .mobile-value {\r\n      font-weight: 600;\r\n      word-break: break-word;\r\n    }\r\n\r\n    .spiel-details-mobile {\r\n      margin-top: 0.35rem;\r\n      font-size: 0.82rem;\r\n      color: var(--color-text-secondary);\r\n      border-radius: 8px;\r\n      background: linear-gradient(90deg, rgba(2,56,89,0.03) 0%, rgba(50,184,198,0.06) 40%, rgba(255,255,255,0.9) 100%);\r\n      border-top: 1px dashed rgba(2,56,89,0.18);\r\n      padding: 0.35rem 0.45rem 0.45rem;\r\n      position: relative;\r\n    }\r\n\r\n    .spiel-details-mobile::before {\r\n      content: \"\";\r\n      position: absolute;\r\n      left: 0;\r\n      top: 0.4rem;\r\n      bottom: 0.45rem;\r\n      width: 3px;\r\n      border-radius: 999px;\r\n      background: linear-gradient(180deg, var(--color-accent), rgba(2,56,89,0.5));\r\n      opacity: 0.85;\r\n    }\r\n\r\n    .spiel-details-mobile > summary {\r\n      cursor: pointer;\r\n      list-style: none;\r\n      font-weight: 600;\r\n      color: #800000;\r\n      display: flex;\r\n      align-items: center;\r\n      gap: 0.4rem;\r\n      padding-left: 0.35rem;\r\n    }\r\n\r\n    .spiel-details-mobile > summary::before {\r\n      content: \"\u25b8\";\r\n      font-size: 0.75rem;\r\n    }\r\n\r\n    .spiel-details-mobile[open] > summary::before { content: \"\u25be\"; }\r\n\r\n    .spiel-details-label {\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.08em;\r\n      font-size: 0.73rem;\r\n      color: #023859;\r\n    }\r\n\r\n    .details-grid {\r\n      display: grid;\r\n      grid-template-columns: repeat(auto-fit,minmax(160px,1fr));\r\n      gap: 0.25rem 0.75rem;\r\n      margin-bottom: 0.3rem;\r\n    }\r\n\r\n    .details-label {\r\n      font-size: 0.78rem;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.06em;\r\n      color: var(--color-text-secondary);\r\n    }\r\n\r\n    .details-value {\r\n      font-size: 0.9rem;\r\n      font-weight: 600;\r\n      color: var(--color-text);\r\n    }\r\n\r\n    .spiel-details-text {\r\n      white-space: pre-wrap;\r\n      line-height: 1.5;\r\n      font-size: 0.86rem;\r\n      color: var(--color-text);\r\n      background: rgba(255,255,255,0.7);\r\n      border-radius: 6px;\r\n      padding: 0.35rem 0.5rem;\r\n      border: 1px solid rgba(2,56,89,0.08);\r\n    }\r\n\r\n    .comment-from {\r\n      font-weight: 700;\r\n      color: #000000;\r\n    }\r\n\r\n    .comment-text-main {\r\n      font-weight: 700;\r\n      color: #c00000;\r\n    }\r\n\r\n    .comment-badge-inline {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      gap: 0.35rem;\r\n      font-size: 0.75rem;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.08em;\r\n      color: #800000;\r\n    }\r\n\r\n    .comment-badge-dot {\r\n      width: 8px;\r\n      height: 8px;\r\n      border-radius: 999px;\r\n      background: #800000;\r\n    }\r\n\r\n    .filter-toggle-btn {\r\n      display: none;\r\n      margin-bottom: 0.75rem;\r\n      font-size: 0.85rem;\r\n    }\r\n\r\n    .filters-wrapper {\r\n      width: 100%;\r\n    }\r\n\r\n    .marker-badge {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      margin-left: 0.3rem;\r\n      width: 18px;\r\n      height: 18px;\r\n      border-radius: 999px;\r\n      border: none;\r\n      background: radial-gradient(circle at 30% 20%,\r\n                  rgba(255,255,255,0.98),\r\n                  rgba(255,255,255,0.8) 45%,\r\n                  rgba(255,255,255,0.45) 100%);\r\n      color: rgba(160, 0, 0, 0.95);\r\n      font-size: 0.8rem;\r\n      font-weight: 700;\r\n      box-shadow: 0 1px 4px rgba(0,0,0,0.18);\r\n    }\r\n\r\n    .mobile-meta-lastfoto {\r\n      font-size: 0.78rem;\r\n      color: rgba(31,33,33,0.8);\r\n      font-style: italic;\r\n      padding: 0.15rem 0.5rem;\r\n      border-radius: 999px;\r\n      background: rgba(2, 56, 89, 0.06);\r\n      border: 1px solid rgba(2, 56, 89, 0.12);\r\n    }\r\n\r\n    .vorschlag-button-row {\r\n      margin-bottom: 1rem;\r\n      display: flex;\r\n      justify-content: flex-end;\r\n    }\r\n\r\n    #spieltagWochentag {\r\n      font-size: 0.8rem;\r\n      color: var(--color-text-secondary);\r\n    }\r\n\r\n    .mobile-card.has-comment {\r\n      background: rgba(255,245,245,0.95);\r\n      border-color: rgba(128,0,0,0.3);\r\n    }\r\n\r\n    .mobile-card.has-comment::before {\r\n      content: \"Kommentar\";\r\n      position: absolute;\r\n      inset: 0;\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      font-size: 2.4rem;\r\n      font-weight: 700;\r\n      letter-spacing: 0.35em;\r\n      text-transform: uppercase;\r\n      color: rgba(128,0,0,0.07);\r\n      pointer-events: none;\r\n      z-index: 0;\r\n    }\r\n\r\n    .mobile-card.has-comment * {\r\n      position: relative;\r\n      z-index: 1;\r\n    }\r\n\r\n    @media (max-width: 768px) {\r\n      body {\r\n        padding: 0;\r\n      }\r\n\r\n      .container {\r\n        max-width: 100%;\r\n        display: flex;\r\n        flex-direction: column;\r\n      }\r\n\r\n      .header {\r\n        padding: 1.3rem 1rem;\r\n        border-radius: 0;\r\n        margin-bottom: 1rem;\r\n      }\r\n\r\n      .header-subline {\r\n        font-size: 0.8rem;\r\n        max-height: 3.2em;\r\n        overflow: hidden;\r\n      }\r\n\r\n      .header-content {\r\n        flex-direction: column;\r\n        align-items: flex-start;\r\n      }\r\n\r\n      .card {\r\n        padding: 1.4rem 1rem;\r\n        border-radius: 0;\r\n        margin-bottom: 1.2rem;\r\n      }\r\n\r\n      .card-title {\r\n        font-size: 1.3rem;\r\n      }\r\n\r\n      .filters {\r\n        grid-template-columns: 1fr;\r\n      }\r\n\r\n      .farblegende {\r\n        flex-direction: column;\r\n        align-items: flex-start;\r\n        gap: 0.4rem;\r\n      }\r\n\r\n      .farbitem {\r\n        width: 100%;\r\n        justify-content: flex-start;\r\n      }\r\n\r\n      .mobile-card-header-line {\r\n        flex-direction: column;\r\n        align-items: flex-start;\r\n        gap: 0.25rem;\r\n      }\r\n\r\n      .mobile-card-header-main {\r\n        width: 100%;\r\n        justify-content: space-between;\r\n      }\r\n\r\n      .vorschlag-button-row {\r\n        justify-content: center;\r\n      }\r\n\r\n      #vorschlagButtonTop {\r\n        width: 100%;\r\n      }\r\n\r\n      .status-badge-modern {\r\n        width: 100%;\r\n        margin-top: 0.75rem;\r\n      }\r\n    }\r\n\r\n    @media (max-width: 480px) {\r\n      .mobile-card {\r\n        font-size: 0.84rem;\r\n        padding: 0.6rem 0.7rem;\r\n        gap: 0.3rem;\r\n      }\r\n\r\n      .mobile-card-header-line {\r\n        flex-direction: row;\r\n        align-items: center;\r\n        justify-content: space-between;\r\n        gap: 0.4rem;\r\n      }\r\n\r\n      .mobile-card-header-main {\r\n        gap: 0.3rem;\r\n      }\r\n\r\n      .mobile-card-index {\r\n        min-width: 1.4rem;\r\n        height: 1.4rem;\r\n        font-size: 0.75rem;\r\n      }\r\n\r\n      .mobile-card-meta { font-size: 0.75rem; }\r\n\r\n      .spiel-details-mobile {\r\n        padding: 0.25rem 0.4rem 0.3rem;\r\n        margin-top: 0.25rem;\r\n      }\r\n\r\n      .details-grid {\r\n        gap: 0.2rem 0.4rem;\r\n      }\r\n    }\r\n\r\n    @media (max-width: 360px) {\r\n      .mobile-card.has-comment::before {\r\n        font-size: 1.8rem;\r\n        letter-spacing: 0.25em;\r\n        width: 220%;\r\n        height: 220%;\r\n        top: -60%;\r\n        left: -60%;\r\n        transform: rotate(-35deg);\r\n        display: flex;\r\n        align-items: center;\r\n        justify-content: center;\r\n      }\r\n    }\r\n\r\n    @media (max-width: 767px) {\r\n      .filter-toggle-btn {\r\n        display: inline-flex;\r\n        align-items: center;\r\n        justify-content: center;\r\n      }\r\n\r\n      .filters-wrapper.collapsed .filters {\r\n        display: none;\r\n      }\r\n    }\r\n\r\n    @media (min-width: 768px) {\r\n      .filters {\r\n        display: grid;\r\n      }\r\n      .filters-wrapper.collapsed .filters {\r\n        display: grid;\r\n      }\r\n    }\r\n  <\/style>\r\n<\/head>\r\n<body>\r\n<div class=\"container\">\r\n  <header class=\"header\">\r\n    <div class=\"header-content\">\r\n      <div class=\"header-left\">\r\n        <div class=\"header-label\">\r\n          <span class=\"header-label-dot\"><\/span>\r\n          <span>Fototermine & Spiel\u00fcbersicht<\/span>\r\n        <\/div>\r\n        <p class=\"header-subline\">\r\n          Hier ist euer \u00dcberblick \u00fcber alle Eintr\u00e4ge im Kalender. Nutzt bitte die Filterm\u00f6glichkeiten und achtet auf Kommentare von uns!\r\n        <\/p>\r\n      <\/div>\r\n\r\n      <div class=\"status-badge-modern\" id=\"statusUpdate\">\r\n        <div class=\"status-main\">\r\n          <span class=\"status-title\">Datenstatus<\/span>\r\n        <\/div>\r\n        <div class=\"status-right\">\r\n          <div class=\"status-meta\">\r\n            <span class=\"status-text-main\">Daten werden geladen \u2026<\/span>\r\n            <span class=\"status-text-sub\">\u2026 aus dem Buchungskalender<\/span>\r\n          <\/div>\r\n          <div class=\"status-progress\">\r\n            <div class=\"status-progress-bar\">\r\n              <div class=\"status-progress-inner\" id=\"statusProgressInner\"><\/div>\r\n            <\/div>\r\n            <span class=\"status-progress-text\" id=\"statusProgressText\">0 %<\/span>\r\n          <\/div>\r\n          <button id=\"reloadButton\" class=\"status-reload-btn\" type=\"button\">\r\n            <span class=\"status-reload-icon\">\u27f3<\/span>\r\n            <span class=\"status-reload-text\">Aktualisieren<\/span>\r\n          <\/button>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/header>\r\n\r\n  <div class=\"farblegende\" aria-label=\"Legende der Statusfarben\">\r\n    <div class=\"farbitem\">\r\n      <span class=\"farbicon bestellt\" aria-hidden=\"true\"><\/span>\r\n      <span>Termin best\u00e4tigt<\/span>\r\n    <\/div>\r\n    <div class=\"farbitem\">\r\n      <span class=\"farbicon vorgemerkt\" aria-hidden=\"true\"><\/span>\r\n      <span>Eure Vorschl\u00e4ge<\/span>\r\n    <\/div>\r\n    <div class=\"farbitem\">\r\n      <span class=\"farbicon neue-anfrage\" aria-hidden=\"true\"><\/span>\r\n      <span>Neue Fotoanfrage<\/span>\r\n    <\/div>\r\n    <div class=\"farbitem\">\r\n      <span class=\"farbicon geplant\" aria-hidden=\"true\"><\/span>\r\n      <span>Geplant<\/span>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"card\">\r\n    <div class=\"card-header\">\r\n      <h2 class=\"card-title\">\r\n        Aktuelle Spielvorschl\u00e4ge\r\n        <span id=\"vorschlagCounter\" class=\"vorschlag-counter-badge\">\r\n          <span class=\"vorschlag-counter-number\">0<\/span>\r\n        <\/span>\r\n      <\/h2>\r\n    <\/div>\r\n\r\n    <button class=\"filter-toggle-btn\" id=\"filterToggleBtn\" type=\"button\">\r\n      Filter anzeigen\r\n    <\/button>\r\n\r\n    <div class=\"filters-wrapper\" id=\"filtersWrapper\">\r\n      <div class=\"filters\" role=\"search\" aria-label=\"Filter f\u00fcr aktuelle Spiele\">\r\n        <div class=\"filter-group\">\r\n          <label for=\"mannschaftFilter\" class=\"filter-label\">Verein<\/label>\r\n          <select id=\"mannschaftFilter\" aria-controls=\"aktuelleSpieleMobile\">\r\n            <option value=\"alle\">Alle Vereine<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div class=\"filter-group\">\r\n          <label for=\"altersklasseFilter\" class=\"filter-label\">Altersklasse<\/label>\r\n          <select id=\"altersklasseFilter\" aria-controls=\"aktuelleSpieleMobile\">\r\n            <option value=\"alle\">Alle Altersklassen<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div class=\"filter-group\">\r\n          <label for=\"aktuelleSpieleDatumFilter\" class=\"filter-label\">Spieltag<\/label>\r\n          <input type=\"date\" id=\"aktuelleSpieleDatumFilter\" aria-controls=\"aktuelleSpieleMobile\" \/>\r\n          <small id=\"spieltagWochentag\"><\/small>\r\n        <\/div>\r\n        <div class=\"filter-group\">\r\n          <label for=\"aktuelleSpieleZeitraumFilter\" class=\"filter-label\">Zeitraum<\/label>\r\n          <select id=\"aktuelleSpieleZeitraumFilter\" aria-controls=\"aktuelleSpieleMobile\">\r\n            <option value=\"alle\" selected>Alle<\/option>\r\n            <option value=\"7\">7 Tage<\/option>\r\n            <option value=\"14\">14 Tage<\/option>\r\n            <option value=\"30\">30 Tage<\/option>\r\n            <option value=\"60\">60 Tage<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div class=\"filter-group\">\r\n          <label for=\"statusFilterAktuelle\" class=\"filter-label\">Status<\/label>\r\n          <select id=\"statusFilterAktuelle\" aria-controls=\"aktuelleSpieleMobile\">\r\n            <option value=\"alle\" selected>Alle Termine<\/option>\r\n            <option value=\"gebucht\">Termin best\u00e4tigt<\/option>\r\n            <option value=\"vorgemerkt\">Vorgemerkt<\/option>\r\n            <option value=\"neue-anfrage\">Neue Fotoanfrage<\/option>\r\n            <option value=\"geplant\">Geplant<\/option>\r\n            <option value=\"markiert\">Markierte Spiele<\/option>\r\n            <option value=\"kommentar\">Mit Kommentar<\/option>\r\n          <\/select>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"vorschlag-button-row\">\r\n      <button id=\"vorschlagButtonTop\" class=\"btn-compact\" type=\"button\" aria-label=\"Fototermin direkt vorschlagen\">\r\n        Fototermin vorschlagen\r\n      <\/button>\r\n    <\/div>\r\n\r\n    <div id=\"aktuelleSpieleMobile\" class=\"table-mobile\" aria-live=\"polite\"><\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\ndocument.addEventListener(\"DOMContentLoaded\", function () {\r\n  const CORS_PROXIES = [\r\n    { name: \"AllOrigins\", url: (icsUrl) => \"https:\/\/api.allorigins.win\/raw?url=\" + encodeURIComponent(icsUrl) },\r\n    { name: \"Cors.sh\", url: (icsUrl) => \"https:\/\/cors.sh\/\" + icsUrl },\r\n    { name: \"CorsProxy.io\", url: (icsUrl) => \"https:\/\/corsproxy.io\/?\" + encodeURIComponent(icsUrl) },\r\n    { name: \"ThingProxy\", url: (icsUrl) => \"https:\/\/thingproxy.freeboard.io\/fetch\/\" + icsUrl },\r\n    { name: \"CORS.lol\", url: (icsUrl) => \"https:\/\/api.cors.lol\/?url=\" + encodeURIComponent(icsUrl) },\r\n    { name: \"Cloudflare-CORS-Anywhere\", url: (icsUrl) => \"https:\/\/cloudflare-cors-anywhere.herokuapp.com\/\" + icsUrl },\r\n    { name: \"Codetabs\", url: (icsUrl) => \"https:\/\/api.codetabs.com\/v1\/proxy?quest=\" + encodeURIComponent(icsUrl) },\r\n    { name: \"CORS-Anywhere\", url: (icsUrl) => \"https:\/\/cors-anywhere.herokuapp.com\/\" + icsUrl }\r\n  ];\r\n\r\n  const CACHE_KEY = \"fototermineCache_v1\";\r\n  let lastProxyFailureTime = null;\r\n  let daten = [];\r\n  let lastFotoByClub = {};\r\n  const FOTO_INTERVAL_TAGE = 56;\r\n\r\n  function setProgress(p) {\r\n    const bar = document.getElementById(\"statusProgressInner\");\r\n    const text = document.getElementById(\"statusProgressText\");\r\n    if (!bar || !text) return;\r\n    const clamped = Math.max(0, Math.min(100, Math.round(p)));\r\n    bar.style.width = clamped + \"%\";\r\n    text.textContent = clamped + \" %\";\r\n  }\r\n\r\n  function canUseLocalStorage() {\r\n    try {\r\n      const testKey = \"__test_fototermine__\";\r\n      localStorage.setItem(testKey, \"1\");\r\n      localStorage.removeItem(testKey);\r\n      return true;\r\n    } catch (e) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  function saveDataToCache() {\r\n    if (!canUseLocalStorage()) return;\r\n    try {\r\n      const payload = {\r\n        timestamp: Date.now(),\r\n        daten: daten.map(d => ({\r\n          datum: d.datum.toISOString(),\r\n          mannschaft: d.mannschaft,\r\n          altersklasse: d.altersklasse,\r\n          partie: d.partie,\r\n          beschreibung: d.beschreibung,\r\n          vorgemerkt: d.vorgemerkt,\r\n          bestellt: d.bestellt,\r\n          geplant: d.geplant,\r\n          abgesagt: d.abgesagt,\r\n          spielausfall: d.spielausfall\r\n        }))\r\n      };\r\n      localStorage.setItem(CACHE_KEY, JSON.stringify(payload));\r\n    } catch (e) {}\r\n  }\r\n\r\n  function loadCachedData() {\r\n    if (!canUseLocalStorage()) return false;\r\n    try {\r\n      const raw = localStorage.getItem(CACHE_KEY);\r\n      if (!raw) return false;\r\n      const payload = JSON.parse(raw);\r\n      if (!payload || !Array.isArray(payload.daten)) return false;\r\n\r\n      daten = payload.daten.map(d => ({\r\n        datum: new Date(d.datum),\r\n        mannschaft: d.mannschaft,\r\n        altersklasse: d.altersklasse,\r\n        partie: d.partie,\r\n        beschreibung: d.beschreibung || \"\",\r\n        vorgemerkt: !!d.vorgemerkt,\r\n        bestellt: !!d.bestellt,\r\n        geplant: !!d.geplant,\r\n        abgesagt: !!d.abgesagt,\r\n        spielausfall: !!d.spielausfall\r\n      }));\r\n\r\n      berechneLetzteFototermine();\r\n      updateFilter();\r\n      filterUndZeige();\r\n\r\n      const statusUpdate = document.getElementById(\"statusUpdate\");\r\n      if (statusUpdate) {\r\n        const mainEl = statusUpdate.querySelector(\".status-text-main\");\r\n        const subEl  = statusUpdate.querySelector(\".status-text-sub\");\r\n        if (mainEl && subEl) {\r\n          const dt = new Date(payload.timestamp);\r\n          mainEl.textContent = \"Gespeicherter Stand geladen\";\r\n          subEl.textContent =\r\n            \"Stand vom \" + dt.toLocaleDateString(\"de-DE\") + \", \" + formatTime(dt) + \" Uhr \u2013 aktualisiere \u2026\";\r\n        }\r\n      }\r\n      setProgress(100);\r\n      return true;\r\n    } catch (e) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  async function fetchWithProxies(icsUrl) {\r\n    let lastError = null;\r\n    for (const proxy of CORS_PROXIES) {\r\n      try {\r\n        const response = await fetch(proxy.url(icsUrl));\r\n        if (response.ok) return await response.text();\r\n      } catch (error) {\r\n        lastError = error;\r\n      }\r\n    }\r\n    lastProxyFailureTime = Date.now();\r\n    throw new Error(\"Alle Proxies fehlgeschlagen. Letzter Fehler: \" + (lastError ? lastError.message : \"\"));\r\n  }\r\n\r\n  const ICS_URL_FESTE      = \"https:\/\/export.kalender.digital\/ics\/4615281\/b40e8d17b4be6185fe64\/fototerminbesttigt.ics?past_months=36&future_months=36\";\r\n  const ICS_URL_VORGEMERKT = \"https:\/\/export.kalender.digital\/ics\/4863317\/b40e8d17b4be6185fe64\/vorgemerktnochkeinefestebuchung.ics?past_months=3&future_months=36\";\r\n  const ICS_URL_GEPLANT    = \"https:\/\/export.kalender.digital\/ics\/4863324\/b40e8d17b4be6185fe64\/inplanung.ics?past_months=3&future_months=36\";\r\n\r\n  const vereineListe = [\r\n    \"Altenhagen\",\"Teutonia Alstadt\",\"TsV Amshausen\",\"SC Babenhausen\",\"SV Baumheide\",\"KSC Bosna Bielefeld\",\r\n    \"DSC Arminia Bielefeld\",\"SC Bosporus\",\"SV Brackwede\",\"TuS Brake\",\"NK Kroatia Bielefeld\",\"TuS Dornberg\",\r\n    \"TuS Eintracht Bielefeld\",\"SV Gadderbaum\",\"GSV Kosmos\",\"SV H\u00e4ger\",\"SC Halle\",\"TuS J\u00f6llenbeck\",\"SV Heepen\",\r\n    \"SC Hellas\",\"SG Hesseln\",\"SC Hicret\",\"FC Hilar Spor\",\"TuS Einigkeit Hillegossen\",\"TuS Hoberge Uerentrup\",\r\n    \"Turngemeinde Herste\",\"SV Jako\",\"SV Kako Bielefeld\",\"KF Kosova\",\"KuS Beli Orlovi Bielefeld\",\r\n    \"TuS Langenheide\",\"TV Friesen Milse\",\"SG Oesterweg\",\"VfL Oldentrup\",\"TuS Ost Bielefeld\",\"SC Peckeloh\",\r\n    \"TuS Quelle\",\"TuS Solbad Ravensberg\",\"SV Roj\",\"SC Bielefeld\",\"SCE Rot-Wei\u00df Bielefeld\",\"VfL Schildesche\",\r\n    \"TuS 08 Senne 1\",\"Kickers Sennestadt\",\"Sportfreunde Sennestadt\",\"TG Sennestadt\",\"Spvg Steinhagen\",\r\n    \"Spvg Heepen\",\"FC T\u00fcrkspor Steinhagen\",\"SuK Canlar Bielefeld\",\"VfL Theesen\",\"FC T\u00fcrkspor Bielefeld\",\"TuRa 06\",\r\n    \"SV Ubbedissen 09\",\"VfL Ummeln\",\"TuS Union Bielefeld\",\"SPVG Versmold\",\"VfB Fichte Bielefeld\",\r\n    \"TuS Union Vilsendorf\",\"VfR Wellensiek\",\"BV Werther\",\"TFC Werther\",\"Fortuna Windfl\u00f6te\",\"BSW West\",\r\n    \"SV Yekspor\",\"Werl-Aspe\",\"DJK Mastbruch\",\"JSG Schildesche \/ Hilal Spor\",\"TuS Schloss Holte\",\r\n    \"TuS Hesseln\",\"TuS Oesterweg\",\"SV Brake II\",\"TuS Langenheide II\",\"SG Bielefeld\",\r\n    \"FC Arminia\",\"TuS Lank\",\"SC Ubbedissen\",\"SV Bockhorst\",\"TuS Auetal\",\"VfB Fichte II\",\r\n    \"TG Gehrke Schildesche\",\"SV Brakkee\",\"TuS Rielasingen\",\"SV Brackwede II\",\"TuS Brake II\"\r\n  ];\r\n\r\n  const vereinsMapping = {};\r\n\r\n  function normalizeClubName(name) {\r\n    const prefixes = [\"TUS\",\"TSV\",\"SC\",\"SV\",\"VFL\",\"VFR\",\"DSC\",\"KF\",\"KUS\",\"FC\",\"TG\",\"SPVG\",\"SCE\",\"VFB\",\"TV\",\"SG\",\"NK\",\"BSW\",\"BV\",\"TFC\",\"KSC\",\"GSV\",\"SUK\",\"HASENPATT\",\"TURNGEMEINDE\",\"KICKERS\",\"SPORTFREUNDE\",\"FORTUNA\",\"JSG\",\"DJK\"];\r\n    let n = (name || \"\").toUpperCase().trim();\r\n\r\n    if (n.includes(\":\")) n = n.split(\":\")[1].trim();\r\n    if (n.includes(\"HASENPATT\") && n.includes(\"J\u00d6LLENBECK\")) n = n.replace(\/HASENPATT\\s*J\u00d6LLENBECK\/gi, \"TUS J\u00d6LLENBECK\");\r\n    n = n.replace(\/J\u00d6LLENEBECK\/gi, \"J\u00d6LLENBECK\");\r\n    n = n.replace(\/JOLLENBECK\/gi, \"J\u00d6LLENBECK\");\r\n    n = n.replace(\/SCHLOSS-HOLTE\/gi, \"SCHLOSS HOLTE\");\r\n    n = n.replace(\/\\bSCB\\b\/g, \"SC BIELEFELD\");\r\n    n = n.replace(\/\\bHGER\\b\/g, \"H\u00c4GER\");\r\n    n = n.replace(\/\\bH\u00d6GER\\b\/g, \"H\u00c4GER\");\r\n    n = n.replace(\/\\b(BUCHUNG|BOOKING|TERMIN)\\b\/g, \"\").trim();\r\n    n = n.replace(\/\\bU\\s*\\d+\\b\/gi, \"\").trim();\r\n    n = n.replace(\/\\b\\d{2}\\\/\\d{2}\\b\/g, \"\").trim();\r\n    n = n.replace(\/\\b(I{1,3}|IV|V|VI{0,3}|IX|X)\\b$\/g, \"\").trim();\r\n    n = n.replace(\/\\b\\d+\\b$\/g, \"\").trim();\r\n\r\n    const cityNames = [\"BIELEFELD\",\"STEINHAGEN\",\"WERTHER\",\"VERSMOLD\",\"HILLEGOSSEN\"];\r\n    for (const city of cityNames) {\r\n      if (n.endsWith(\" \" + city)) {\r\n        n = n.substring(0, n.length - city.length - 1).trim();\r\n        break;\r\n      }\r\n    }\r\n\r\n    if (n.startsWith(\"JSG \")) {\r\n      n = n.slice(4).trim();\r\n      const parts = n.split(\/[\\\/,]\/);\r\n      if (parts.length > 0) n = parts[0].trim();\r\n    }\r\n\r\n    for (const prefix of prefixes) {\r\n      if (n.startsWith(prefix + \" \")) {\r\n        n = n.substring(prefix.length + 1).trim();\r\n        break;\r\n      }\r\n    }\r\n\r\n    return n;\r\n  }\r\n\r\n  function initVereinMapping() {\r\n    vereineListe.forEach((verein) => {\r\n      let hauptVerein = normalizeClubName(verein);\r\n      if (hauptVerein.includes(\"HASENPATT\") && hauptVerein.includes(\"J\u00d6LLENBECK\")) hauptVerein = \"TUS J\u00d6LLENBECK\";\r\n      const normalisiert = hauptVerein.toLowerCase();\r\n      vereinsMapping[normalisiert] = normalisiert;\r\n    });\r\n  }\r\n\r\n  function getHauptVerein(mannschaftName) {\r\n    const normalized = normalizeClubName(mannschaftName).toLowerCase();\r\n    return vereinsMapping[normalized] || normalized;\r\n  }\r\n\r\n  function istGueltigerVerein(name) {\r\n    const up = (name || \"\").toUpperCase();\r\n    if (up === \"BUCHUNG: SPIELTAGSFOTOS FUSSBALL\") return true;\r\n    if (up.includes(\"BOOKING\") || up.includes(\"TERMIN\")) return false;\r\n    return normalizeClubName(name).length > 2;\r\n  }\r\n\r\n  function extractAltersklasse(text) {\r\n    const t = (text || \"\").trim();\r\n\r\n    let m = t.match(\/\\bU\\s*[-\\\/]?\\s*(\\d{1,2})\\b\/i);\r\n    if (m) return \"U\" + m[1];\r\n\r\n    m = t.match(\/\\b(Herren|Damen)\\s*(II|III|IV|\\d+)?\\b\/i);\r\n    if (m) {\r\n      const basis = m[1].charAt(0).toUpperCase() + m[1].slice(1).toLowerCase();\r\n      const zusatz = m[2] ? (\" \" + m[2].toString().toUpperCase()) : \"\";\r\n      return basis + zusatz;\r\n    }\r\n\r\n    m = t.match(\/\\b(Senioren|Alte Herren|Altherren|A\\-Junioren|B\\-Junioren|C\\-Junioren)\\b\/i);\r\n    if (m) {\r\n      return m[1]\r\n        .replace(\/junioren\/i, \"Junioren\")\r\n        .replace(\/Alte Herren\/i, \"Alte Herren\")\r\n        .replace(\/Altherren\/i, \"Altherren\");\r\n    }\r\n    return \"\";\r\n  }\r\n\r\n  function extractMannschaften(text) {\r\n    if (!text) return [];\r\n    return text.includes(\" - \") ? text.split(\" - \").map((e) => e.trim()) : [text];\r\n  }\r\n\r\n  function simplifyTeamName(name) {\r\n    const t = (name || \"\").split(\" \");\r\n    if (t[0] && t[0].toUpperCase().startsWith(\"U\") && t.length > 1) return t.slice(1).join(\" \");\r\n    return name;\r\n  }\r\n\r\n  function parseICS(text, statusTyp = \"bestellt\") {\r\n    const lines = (text || \"\").split(\/\\r?\\n\/);\r\n    let event = null;\r\n    let lastKey = null;\r\n\r\n    lines.forEach((line) => {\r\n      if (line === \"BEGIN:VEVENT\") {\r\n        event = {};\r\n        lastKey = null;\r\n      } else if (line === \"END:VEVENT\") {\r\n        if (event && event.datum && event.mannschaften) {\r\n          event.mannschaften.forEach((m) => {\r\n            if (statusTyp === \"geplant\" || istGueltigerVerein(m)) {\r\n              daten.push({\r\n                datum: new Date(event.datum),\r\n                mannschaft: m,\r\n                altersklasse: event.altersklasse || \"\",\r\n                partie: event.partie || \"\",\r\n                beschreibung: event.beschreibung || \"\",\r\n                vorgemerkt: statusTyp === \"vorgemerkt\",\r\n                bestellt: statusTyp === \"bestellt\",\r\n                geplant: statusTyp === \"geplant\",\r\n                abgesagt: false,\r\n                spielausfall: false\r\n              });\r\n            }\r\n          });\r\n        }\r\n        event = null;\r\n        lastKey = null;\r\n      } else if (event) {\r\n        if (\/^\\s\/.test(line) && lastKey === \"DESCRIPTION\") {\r\n          event.beschreibung = (event.beschreibung || \"\") + line.trim();\r\n        } else if (line.startsWith(\"DTSTART;VALUE=DATE:\")) {\r\n          const d = line.substr(19);\r\n          event.datum = new Date(d.slice(0, 4) + \"-\" + d.slice(4, 6) + \"-\" + d.slice(6));\r\n          lastKey = \"DTSTART\";\r\n        } else if (line.startsWith(\"DTSTART:\")) {\r\n          const d = line.substr(8);\r\n          const year   = Number(d.slice(0, 4));\r\n          const month  = Number(d.slice(4, 6)) - 1;\r\n          const day    = Number(d.slice(6, 8));\r\n          const hour   = Number(d.slice(9, 11) || \"0\");\r\n          const minute = Number(d.slice(11, 13) || \"0\");\r\n          const second = Number(d.slice(13, 15) || \"0\");\r\n          const utcMillis = Date.UTC(year, month, day, hour, minute, second);\r\n          event.datum = new Date(utcMillis);\r\n          lastKey = \"DTSTART\";\r\n        } else if (line.startsWith(\"SUMMARY:\")) {\r\n          event.partie = line.substr(8);\r\n          event.altersklasse = extractAltersklasse(event.partie);\r\n          event.mannschaften = extractMannschaften(event.partie).map(simplifyTeamName);\r\n          lastKey = \"SUMMARY\";\r\n        } else if (line.startsWith(\"DESCRIPTION:\")) {\r\n          event.beschreibung = line.substr(12);\r\n          lastKey = \"DESCRIPTION\";\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  function formatBeschreibung(raw) {\r\n    if (!raw) return \"\";\r\n    let t = raw\r\n      .replace(\/\\\\n\/gi, \"\\n\")\r\n      .replace(\/\\\\N\/g, \"\\n\")\r\n      .replace(\/\\\\\\\\\/g, \"\\\\\")\r\n      .replace(\/\\\\,\/g, \",\")\r\n      .replace(\/\\\\;\/g, \";\");\r\n\r\n    t = t.replace(\/\\r\\n\/g, \"\\n\");\r\n    t = t.replace(\/\\r\/g, \"\\n\");\r\n    t = t.replace(\/\\n{2,}\/g, \"\\n\\n\");\r\n    return t.trim();\r\n  }\r\n\r\n  function berechneLetzteFototermine() {\r\n    lastFotoByClub = {};\r\n    const feste = daten.filter(d => d.bestellt && !d.abgesagt && !d.spielausfall);\r\n\r\n    feste.forEach(d => {\r\n      let heim = \"\", gast = \"\";\r\n      if (d.partie && d.partie.includes(\" - \")) {\r\n        const t = d.partie.split(\" - \");\r\n        heim = t[0].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n        gast = t[1].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n      } else {\r\n        heim = d.mannschaft;\r\n      }\r\n\r\n      [heim, gast].forEach(teamName => {\r\n        if (!teamName) return;\r\n        const clubKey = getHauptVerein(teamName).toLowerCase();\r\n        if (!clubKey) return;\r\n        const alt = lastFotoByClub[clubKey];\r\n        if (!alt || d.datum > alt) {\r\n          lastFotoByClub[clubKey] = d.datum;\r\n        }\r\n      });\r\n    });\r\n  }\r\n\r\n  function getLetztesFotoInfo(heimName, gastName) {\r\n    const teams = [heimName, gastName].filter(Boolean);\r\n    let bestDate = null;\r\n    let bestMatch = \"\";\r\n\r\n    const feste = daten.filter(d => d.bestellt && !d.abgesagt && !d.spielausfall);\r\n\r\n    feste.forEach((d) => {\r\n      let heim = \"\", gast = \"\";\r\n      if (d.partie && d.partie.includes(\" - \")) {\r\n        const t = d.partie.split(\" - \");\r\n        heim = t[0].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n        gast = t[1].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n      } else {\r\n        heim = d.mannschaft;\r\n      }\r\n\r\n      [heim, gast].forEach((teamName) => {\r\n        if (!teamName) return;\r\n        const clubKey = getHauptVerein(teamName).toLowerCase();\r\n\r\n        const isRelevant = teams.some((tName) => {\r\n          const tk = getHauptVerein(tName).toLowerCase();\r\n          return tk === clubKey;\r\n        });\r\n\r\n        if (!isRelevant) return;\r\n\r\n        if (!bestDate || d.datum > bestDate) {\r\n          bestDate = d.datum;\r\n          bestMatch = d.partie || (heim + (gast ? \" - \" + gast : \"\"));\r\n        }\r\n      });\r\n    });\r\n\r\n    return bestDate ? { datum: bestDate, partie: bestMatch } : null;\r\n  }\r\n\r\n  function brauchtFotoMarkierung(spielDatum, heimName, gastName) {\r\n    const grenze = new Date(spielDatum);\r\n    grenze.setDate(grenze.getDate() - FOTO_INTERVAL_TAGE);\r\n\r\n    const teams = [heimName, gastName].filter(Boolean);\r\n\r\n    for (const t of teams) {\r\n      const clubKey = getHauptVerein(t).toLowerCase();\r\n      const last = lastFotoByClub[clubKey];\r\n      if (last && last >= grenze) return false;\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  function renderAktuelleSpieleMobile(spiele) {\r\n    const container = document.getElementById(\"aktuelleSpieleMobile\");\r\n    if (!container) return;\r\n    container.innerHTML = \"\";\r\n    const unique = new Set();\r\n    const spieleUnique = [];\r\n\r\n    spiele.sort((a, b) => a.datum - b.datum).forEach((d) => {\r\n      let heim = \"\", gast = \"\";\r\n      if (d.partie && d.partie.includes(\" - \")) {\r\n        const t = d.partie.split(\" - \");\r\n        heim = t[0].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n        gast = t[1].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n      } else {\r\n        heim = d.mannschaft;\r\n      }\r\n\r\n      heim = heim.replace(\/\\bVorschlag:\\s*\/i, \"\").replace(\/\\bVorschlag\\b\/i, \"\");\r\n\r\n      const key = d.datum.toISOString().slice(0, 10) + \"|\" + heim + \"|\" + gast + \"|\" + (d.partie || \"\");\r\n      if (!unique.has(key)) {\r\n        unique.add(key);\r\n        spieleUnique.push({\r\n          ...d,\r\n          heimOverride: heim,\r\n          gastOverride: gast\r\n        });\r\n      }\r\n    });\r\n\r\n    spieleUnique.forEach((d, index) => {\r\n      const card = document.createElement(\"div\");\r\n      card.className = \"mobile-card\";\r\n\r\n      const uhrzeit = d.datum.toLocaleTimeString(\"de-DE\", {\r\n        hour: \"2-digit\",\r\n        minute: \"2-digit\",\r\n      });\r\n\r\n      const heim = d.heimOverride ?? d.mannschaft;\r\n      const gast = d.gastOverride ?? \"\";\r\n\r\n      const istGebucht = d.bestellt && !d.vorgemerkt && !d.geplant;\r\n      const istBuchungNur = (d.partie || \"\").toLowerCase().includes(\"buchung\") && !istGebucht;\r\n\r\n      if (d.abgesagt || d.spielausfall) return;\r\n\r\n      let statusText;\r\n      let chipClass;\r\n\r\n      if (istGebucht) {\r\n        statusText = \"Termin best\u00e4tigt\";\r\n        chipClass = \"success\";\r\n      } else if (istBuchungNur) {\r\n        statusText = \"Neue Fotoanfrage\";\r\n        chipClass = \"request\";\r\n      } else if (d.vorgemerkt) {\r\n        statusText = \"Euer Vorschlag\";\r\n        chipClass = \"warning\";\r\n      } else {\r\n        statusText = \"Geplant\";\r\n        chipClass = \"planned\";\r\n      }\r\n\r\n      if (istGebucht) {\r\n        card.style.boxShadow = \"0 0 0 1px rgba(30,127,59,0.75)\";\r\n        card.classList.add(\"status-gebucht\");\r\n      } else if (istBuchungNur) {\r\n        card.classList.add(\"status-neue-anfrage\");\r\n      } else if (chipClass === \"planned\") {\r\n        card.classList.add(\"status-geplant\");\r\n      }\r\n\r\n      const beschrFormatted = formatBeschreibung(d.beschreibung || d.partie || \"\");\r\n\r\n      let buchungsTextBereinigt = beschrFormatted\r\n        .replace(\/Vorschlag:\\s*Blau wei\u00df G\u00fctersloh.*$\/gmi, \"\")\r\n        .replace(\/Vorschlag:\\s*Blau wei\u00df G\u00fctersloh\/gi, \"\");\r\n\r\n      \/\/ Kommentar-Auswertung nur f\u00fcr Darstellung, nicht f\u00fcr Filter\r\n      const kommentarMarker = \"Kommentar Blickpunkt Lokalsport:\";\r\n      const hatKommentarMarker =\r\n        buchungsTextBereinigt && buchungsTextBereinigt.includes(kommentarMarker);\r\n      const kommentarHTML = hatKommentarMarker\r\n        ? formatKommentarHTML(buchungsTextBereinigt, kommentarMarker)\r\n        : \"\";\r\n\r\n      if (hatKommentarMarker) {\r\n        buchungsTextBereinigt = buchungsTextBereinigt.split(kommentarMarker)[0].trim();\r\n      }\r\n\r\n      const brauchtMarker = brauchtFotoMarkierung(d.datum, heim, gast);\r\n      const markerHTML = brauchtMarker\r\n        ? '<span class=\"marker-badge\" title=\"Seit mindestens 8 Wochen keine der beiden Mannschaften fotografiert\">!<\/span>'\r\n        : \"\";\r\n\r\n      const letztesFotoInfo = getLetztesFotoInfo(heim, gast);\r\n      let letztesFotoText = \"\";\r\n\r\n      if (!letztesFotoInfo) {\r\n        letztesFotoText = \"Noch kein Fototermin\";\r\n      } else {\r\n        const diffMs = d.datum - letztesFotoInfo.datum;\r\n        const diffTage = diffMs \/ (1000 * 60 * 60 * 24);\r\n\r\n        if (diffTage >= FOTO_INTERVAL_TAGE) {\r\n          letztesFotoText =\r\n            \"Letztes Foto: \" +\r\n            letztesFotoInfo.datum.toLocaleDateString(\"de-DE\") +\r\n            \" \u2013 \" +\r\n            (letztesFotoInfo.partie || \"\");\r\n        }\r\n      }\r\n\r\n      if (kommentarHTML) {\r\n        card.classList.add(\"has-comment\");\r\n      }\r\n\r\n      card.innerHTML =\r\n        '<div class=\"mobile-card-header-line\">' +\r\n          '<span class=\"mobile-card-header-main\">' +\r\n            '<span class=\"mobile-card-index\">' + (index + 1) + \"<\/span>\" +\r\n            \"<span>\" + d.datum.toLocaleDateString(\"de-DE\") + \" \u2022 \" + uhrzeit + \"<\/span>\" +\r\n          \"<\/span>\" +\r\n          '<span class=\"mobile-chip ' + chipClass + '\">' + statusText + markerHTML + \"<\/span>\" +\r\n        \"<\/div>\" +\r\n        (letztesFotoText\r\n          ? '<div class=\"mobile-card-meta\">' +\r\n              '<span class=\"mobile-meta-lastfoto\">' + letztesFotoText + \"<\/span>\" +\r\n            \"<\/div>\"\r\n          : \"\") +\r\n        '<div><span class=\"mobile-label\">Heim<\/span> <span class=\"mobile-value\">' + heim + \"<\/span><\/div>\" +\r\n        '<div><span class=\"mobile-label\">Gast<\/span> <span class=\"mobile-value\">' + gast + \"<\/span><\/div>\" +\r\n        '<div class=\"mobile-card-meta\">' +\r\n          \"<span>AK: <strong>\" + (d.altersklasse || \"-\") + \"<\/strong><\/span>\" +\r\n          (kommentarHTML\r\n            ? '<span class=\"comment-badge-inline\"><span class=\"comment-badge-dot\"><\/span>Neuer Kommentar<\/span>'\r\n            : \"\") +\r\n        \"<\/div>\" +\r\n        '<details class=\"spiel-details-mobile\">' +\r\n          \"<summary>\" +\r\n            '<span class=\"spiel-details-label\">Buchungsdetails<\/span>' +\r\n          \"<\/summary>\" +\r\n          '<div class=\"spiel-details-content\">' +\r\n            '<div class=\"details-grid\">' +\r\n              \"<div>\" +\r\n                '<div class=\"details-label\">Datum & Uhrzeit<\/div>' +\r\n                '<div class=\"details-value\">' + d.datum.toLocaleDateString(\"de-DE\") +\r\n                  \" \u2022 \" + uhrzeit + \"<\/div>\" +\r\n              \"<\/div>\" +\r\n              \"<div>\" +\r\n                '<div class=\"details-label\">Partie<\/div>' +\r\n                '<div class=\"details-value\">' + (d.partie || \"-\") + \"<\/div>\" +\r\n              \"<\/div>\" +\r\n            \"<\/div>\" +\r\n            '<p class=\"spiel-details-label\" style=\"margin-top:0.3rem;\">Buchungs-Hinweis<\/p>' +\r\n            (buchungsTextBereinigt\r\n              ? '<div class=\"spiel-details-text\">' +\r\n                  buchungsTextBereinigt.replace(\/\\n\/g, \"<br>\") +\r\n                \"<\/div>\"\r\n              : \"\") +\r\n            (kommentarHTML\r\n              ? '<div class=\"spiel-details-text\">' +\r\n                  kommentarHTML.replace(\/\\n\/g, \"<br>\") +\r\n                \"<\/div>\"\r\n              : \"\") +\r\n          \"<\/div>\" +\r\n        \"<\/details>\";\r\n\r\n      container.appendChild(card);\r\n    });\r\n\r\n    const counterEl = document.getElementById(\"vorschlagCounter\");\r\n    if (counterEl) {\r\n      const numberEl = counterEl.querySelector(\".vorschlag-counter-number\");\r\n      if (numberEl) numberEl.textContent = spieleUnique.length;\r\n    }\r\n  }\r\n\r\n  \/\/ Kommentar-HTML-Helfer mit Marker-Argument\r\n  function formatKommentarHTML(text, marker) {\r\n    const m = text.match(new RegExp(\"^(\" + marker.replace(\/[.*+?^${}()|[\\]\\\\]\/g, \"\\\\$&\") + \"[ \\\\t]*)([\\\\s\\\\S]*)$\", \"i\"));\r\n    if (!m) return \"\";\r\n    const prefix = m[1];\r\n    const rest = m[2] || \"\";\r\n    const parts = rest.split(\/\\r?\\n\/);\r\n    const ersteZeile = parts.shift() || \"\";\r\n    const restText = parts.join(\"\\n\");\r\n    let html = \"\";\r\n    html += '<span class=\"comment-from\">' + prefix + \"<\/span>\";\r\n    html += '<span class=\"comment-text-main\">' + ersteZeile + \"<\/span>\";\r\n    if (restText.trim() !== \"\") {\r\n      html += \"\\n\" + restText;\r\n    }\r\n    return html;\r\n  }\r\n\r\n  function renderAktuelleSpiele(spiele) {\r\n    renderAktuelleSpieleMobile(spiele);\r\n  }\r\n\r\n  function filterUndZeige() {\r\n    const selectM = document.getElementById(\"mannschaftFilter\");\r\n    const selectA = document.getElementById(\"altersklasseFilter\");\r\n    const inputD = document.getElementById(\"aktuelleSpieleDatumFilter\");\r\n    const selectZ = document.getElementById(\"aktuelleSpieleZeitraumFilter\");\r\n    const selectStatus = document.getElementById(\"statusFilterAktuelle\");\r\n\r\n    const manns = (selectM && selectM.value ? selectM.value.toLowerCase() : \"alle\");\r\n    const alt = (selectA && selectA.value ? selectA.value.toLowerCase() : \"alle\");\r\n    const heute = new Date(); heute.setHours(0, 0, 0, 0);\r\n    const stat = (selectStatus && selectStatus.value) || \"alle\";\r\n    const zeitraum = (selectZ && selectZ.value) || \"alle\";\r\n\r\n    const hatSpieltag = !!(inputD && inputD.value);\r\n    const spieltag = hatSpieltag ? new Date(inputD.value) : null;\r\n    if (spieltag) spieltag.setHours(0, 0, 0, 0);\r\n\r\n    let gefiltert;\r\n\r\n    if (hatSpieltag) {\r\n      gefiltert = daten.filter((d) => {\r\n        const dTag = new Date(d.datum);\r\n        dTag.setHours(0, 0, 0, 0);\r\n        return dTag.getTime() === spieltag.getTime();\r\n      });\r\n    } else {\r\n      const abDatum = new Date(heute);\r\n      gefiltert = daten.filter((d) => d.datum >= abDatum);\r\n\r\n      if (zeitraum !== \"alle\") {\r\n        const days = parseInt(zeitraum, 10);\r\n        const maxDate = new Date(abDatum);\r\n        maxDate.setDate(maxDate.getDate() + days);\r\n        gefiltert = gefiltert.filter((d) => d.datum <= maxDate);\r\n      }\r\n    }\r\n\r\n    gefiltert = gefiltert.filter((d) => {\r\n      const v = getHauptVerein(d.mannschaft).toLowerCase();\r\n      const vereinCheck = manns === \"alle\" || v === manns || v.includes(manns) || manns.includes(v);\r\n      const altCheck = alt === \"alle\" || d.altersklasse.toLowerCase() === alt;\r\n      if (!vereinCheck || !altCheck) return false;\r\n\r\n      const isBuchungNur = String(d.partie || \"\").toLowerCase().includes(\"buchung\") &&\r\n                           !(d.bestellt && !d.vorgemerkt && !d.geplant);\r\n\r\n      let heim = \"\", gast = \"\";\r\n      if (d.partie && d.partie.includes(\" - \")) {\r\n        const t = d.partie.split(\" - \");\r\n        heim = t[0].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n        gast = t[1].replace(\/^U\\s*\\d+\\s+\/i, \"\").trim();\r\n      } else {\r\n        heim = d.mannschaft;\r\n      }\r\n      heim = heim.replace(\/\\bVorschlag:\\s*\/i, \"\").replace(\/\\bVorschlag\\b\/i, \"\");\r\n\r\n      const marked = brauchtFotoMarkierung(d.datum, heim, gast);\r\n\r\n      if (stat !== \"alle\") {\r\n        if (stat === \"gebucht\" &&\r\n            !(d.bestellt && !d.vorgemerkt && !d.geplant && !d.abgesagt && !d.spielausfall)) return false;\r\n        if (stat === \"vorgemerkt\" && !d.vorgemerkt) return false;\r\n        if (stat === \"neue-anfrage\" && !isBuchungNur) return false;\r\n        if (stat === \"geplant\" && !d.geplant) return false;\r\n        if (stat === \"markiert\" && !marked) return false;\r\n        \/\/ Kommentar-Filter greift erst nach dem Rendern \u00fcber DOM\r\n      }\r\n      return true;\r\n    });\r\n\r\n    renderAktuelleSpiele(gefiltert);\r\n\r\n    \/\/ DOM-basiertes Herausfiltern von Cards ohne \"Neuer Kommentar\"\r\n    const statusFilter = document.getElementById(\"statusFilterAktuelle\");\r\n    const container = document.getElementById(\"aktuelleSpieleMobile\");\r\n    if (statusFilter && container && statusFilter.value === \"kommentar\") {\r\n      const cards = Array.from(container.querySelectorAll(\".mobile-card\"));\r\n      cards.forEach(card => {\r\n        const hasCommentBadge = card.textContent.includes(\"Neuer Kommentar\");\r\n        card.style.display = hasCommentBadge ? \"\" : \"none\";\r\n      });\r\n    }\r\n  }\r\n\r\n  async function ladeDaten() {\r\n    const statusUpdate = document.getElementById(\"statusUpdate\");\r\n    try {\r\n      if (statusUpdate) {\r\n        const mainEl = statusUpdate.querySelector(\".status-text-main\");\r\n        const subEl  = statusUpdate.querySelector(\".status-text-sub\");\r\n        if (mainEl && subEl) {\r\n          mainEl.textContent = \"Daten werden geladen \u2026\";\r\n          subEl.textContent = \"\u2026 aus dem Buchungskalender\";\r\n        }\r\n      }\r\n      setProgress(0);\r\n\r\n      const textFeste      = await fetchWithProxies(ICS_URL_FESTE);\r\n      setProgress(33);\r\n      const textVorgemerkt = await fetchWithProxies(ICS_URL_VORGEMERKT);\r\n      setProgress(66);\r\n      const textGeplant    = await fetchWithProxies(ICS_URL_GEPLANT);\r\n      setProgress(90);\r\n\r\n      daten = [];\r\n      parseICS(textFeste, \"bestellt\");\r\n      parseICS(textVorgemerkt, \"vorgemerkt\");\r\n      parseICS(textGeplant, \"geplant\");\r\n\r\n      const abAugust = new Date(2025, 7, 1);\r\n\r\n      daten = daten.filter((e) => {\r\n        if (e.datum < abAugust) return false;\r\n\r\n        const partieLower = String(e.partie || \"\").toLowerCase();\r\n        if (\r\n          partieLower.startsWith(\"buchung: tus quelle - tus j\u00f6llenbeck u16\") ||\r\n          partieLower === \"buchung: tus quelle - tus j\u00f6llenbeck u16\"\r\n        ) {\r\n          return false;\r\n        }\r\n\r\n        return true;\r\n      });\r\n\r\n      berechneLetzteFototermine();\r\n      updateFilter();\r\n      filterUndZeige();\r\n      saveDataToCache();\r\n\r\n      setProgress(100);\r\n\r\n      if (statusUpdate) {\r\n        const mainEl = statusUpdate.querySelector(\".status-text-main\");\r\n        const subEl  = statusUpdate.querySelector(\".status-text-sub\");\r\n        if (mainEl && subEl) {\r\n          mainEl.textContent = \"Daten aktualisiert\";\r\n          subEl.textContent =\r\n            \"Letzte Aktualisierung: \" + formatTime(new Date()) + \" Uhr\";\r\n        }\r\n      }\r\n      lastProxyFailureTime = null;\r\n    } catch (e) {\r\n      setProgress(0);\r\n      if (statusUpdate) {\r\n        const mainEl = statusUpdate.querySelector(\".status-text-main\");\r\n        const subEl  = statusUpdate.querySelector(\".status-text-sub\");\r\n        if (mainEl && subEl) {\r\n          mainEl.textContent = \"Fehler beim Laden der Daten\";\r\n          subEl.textContent =\r\n            \"Zeige zuletzt gespeicherten Stand (falls vorhanden)\";\r\n        }\r\n      }\r\n      if (!daten.length && loadCachedData()) {}\r\n      if (lastProxyFailureTime) {\r\n        setTimeout(() => {\r\n          ladeDaten().catch(console.error);\r\n        }, 30000);\r\n      }\r\n    }\r\n  }\r\n\r\n  function updateFilter() {\r\n    const uniqueNormalized = new Map();\r\n    vereineListe.forEach((v) => {\r\n      const n = normalizeClubName(v);\r\n      const key = n.toLowerCase();\r\n      if (!uniqueNormalized.has(key)) uniqueNormalized.set(key, v);\r\n    });\r\n    const clubs = Array.from(uniqueNormalized.entries()).sort((a, b) => a[1].localeCompare(b[1]));\r\n    const selectM = document.getElementById(\"mannschaftFilter\");\r\n    if (selectM) {\r\n      selectM.innerHTML = '<option value=\"alle\">Alle Vereine<\/option>';\r\n      clubs.forEach(([n, o]) => {\r\n        const opt = document.createElement(\"option\");\r\n        opt.value = n.toLowerCase();\r\n        opt.textContent = o;\r\n        selectM.appendChild(opt);\r\n      });\r\n    }\r\n    const altersSet = new Set();\r\n    daten.forEach((d) => {\r\n      if (d.altersklasse) altersSet.add(d.altersklasse);\r\n    });\r\n    const altersArr = Array.from(altersSet).sort();\r\n    const selectA = document.getElementById(\"altersklasseFilter\");\r\n    if (selectA) {\r\n      selectA.innerHTML = '<option value=\"alle\">Alle Altersklassen<\/option>';\r\n      altersArr.forEach((ak) => {\r\n        const opt = document.createElement(\"option\");\r\n        opt.value = ak.toLowerCase();\r\n        opt.textContent = ak;\r\n        selectA.appendChild(opt);\r\n      });\r\n    }\r\n    const selectStatus = document.getElementById(\"statusFilterAktuelle\");\r\n    if (selectStatus) selectStatus.value = \"alle\";\r\n  }\r\n\r\n  function formatTime(date) {\r\n    return String(date.getHours()).padStart(2, \"0\") + \":\" + String(date.getMinutes()).padStart(2, \"0\");\r\n  }\r\n\r\n  document.getElementById(\"reloadButton\")?.addEventListener(\"click\", ladeDaten);\r\n  [\"mannschaftFilter\",\"altersklasseFilter\",\"aktuelleSpieleZeitraumFilter\",\"aktuelleSpieleDatumFilter\",\"statusFilterAktuelle\"].forEach((id) => {\r\n    const el = document.getElementById(id);\r\n    if (el) el.addEventListener(\"change\", filterUndZeige);\r\n  });\r\n\r\n  document.getElementById(\"vorschlagButtonTop\")?.addEventListener(\"click\", () => {\r\n    window.open(\"https:\/\/kalender.digital\/b\/1fdef775bc72a60e\/961\", \"_blank\");\r\n  });\r\n\r\n  const aktuelleSpieleDatum = document.getElementById(\"aktuelleSpieleDatumFilter\");\r\n  if (aktuelleSpieleDatum) aktuelleSpieleDatum.value = \"\";\r\n\r\n  const spieltagWochentag = document.getElementById(\"spieltagWochentag\");\r\n  if (spieltagWochentag && aktuelleSpieleDatum) {\r\n    const updateWochentag = () => {\r\n      if (!aktuelleSpieleDatum.value) {\r\n        spieltagWochentag.textContent = \"\";\r\n        return;\r\n      }\r\n      const d = aktuelleSpieleDatum.valueAsDate;\r\n      if (!d) {\r\n        spieltagWochentag.textContent = \"\";\r\n        return;\r\n      }\r\n      spieltagWochentag.textContent = d.toLocaleDateString(\"de-DE\", {\r\n        weekday: \"long\",\r\n        day: \"2-digit\",\r\n        month: \"2-digit\",\r\n        year: \"numeric\"\r\n      });\r\n    };\r\n    aktuelleSpieleDatum.addEventListener(\"change\", updateWochentag);\r\n  }\r\n\r\n  initVereinMapping();\r\n\r\n  const hatteCache = loadCachedData();\r\n  if (!hatteCache) {\r\n    const statusUpdate = document.getElementById(\"statusUpdate\");\r\n    if (statusUpdate) {\r\n      const mainEl = statusUpdate.querySelector(\".status-text-main\");\r\n      const subEl  = statusUpdate.querySelector(\".status-text-sub\");\r\n      if (mainEl && subEl) {\r\n        mainEl.textContent = \"Daten werden geladen \u2026\";\r\n        subEl.textContent = \"\u2026 aus dem Buchungskalender\";\r\n      }\r\n    }\r\n  }\r\n\r\n  const filtersWrapper = document.getElementById(\"filtersWrapper\");\r\n  const filterToggleBtn = document.getElementById(\"filterToggleBtn\");\r\n  if (filtersWrapper && filterToggleBtn) {\r\n    const isMobile = window.matchMedia(\"(max-width: 767px)\").matches;\r\n\r\n    if (isMobile) {\r\n      filtersWrapper.classList.add(\"collapsed\");\r\n      filterToggleBtn.textContent = \"Filter anzeigen\";\r\n    } else {\r\n      filtersWrapper.classList.remove(\"collapsed\");\r\n      filterToggleBtn.textContent = \"\";\r\n    }\r\n\r\n    filterToggleBtn.addEventListener(\"click\", () => {\r\n      const isCollapsed = filtersWrapper.classList.toggle(\"collapsed\");\r\n      filterToggleBtn.textContent = isCollapsed ? \"Filter anzeigen\" : \"Filter ausblenden\";\r\n    });\r\n  }\r\n\r\n  ladeDaten();\r\n  setInterval(() => {\r\n    ladeDaten().catch(console.error);\r\n  }, 15 * 60 * 1000);\r\n});\r\n<\/script>\r\n<\/body>\r\n<\/html>\r\n\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>FototermineAlles im Blick Fototermin-\u00dcbersicht Fototermine Fototermine &#038; Spiel\u00fcbersicht Hier ist euer \u00dcberblick \u00fcber alle Eintr\u00e4ge im Kalender. Nutzt bitte die Filterm\u00f6glichkeiten und achtet auf Kommentare von uns! Datenstatus Daten werden geladen \u2026 \u2026 aus dem Buchungskalender 0 % \u27f3 Aktualisieren Termin best\u00e4tigt Eure Vorschl\u00e4ge Neue Fotoanfrage Geplant Aktuelle Spielvorschl\u00e4ge 0 Filter anzeigen Verein Alle Vereine &#8230; <a title=\"Fototermin \u00dcbersicht\" class=\"read-more\" href=\"https:\/\/blickpunkt-lokalsport.de\/english\/fototermin-uebersicht\/\" aria-label=\"Read more about Fototermin \u00dcbersicht\">Read more<\/a><\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-46963","page","type-page","status-publish"],"acf":[],"_links":{"self":[{"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/pages\/46963","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/comments?post=46963"}],"version-history":[{"count":10,"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/pages\/46963\/revisions"}],"predecessor-version":[{"id":52336,"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/pages\/46963\/revisions\/52336"}],"wp:attachment":[{"href":"https:\/\/blickpunkt-lokalsport.de\/english\/wp-json\/wp\/v2\/media?parent=46963"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}