{"id":20270,"date":"2026-05-06T07:27:43","date_gmt":"2026-05-06T05:27:43","guid":{"rendered":"https:\/\/management-kolloquium.de\/"},"modified":"2026-05-06T10:54:46","modified_gmt":"2026-05-06T08:54:46","slug":"fotos-mmk-friedrichshafen","status":"publish","type":"page","link":"https:\/\/management-kolloquium.de\/en\/fotos-mmk-friedrichshafen\/","title":{"rendered":"Fotos MMK Friedrichshafen"},"content":{"rendered":"\n    <section  class=\"w-full max-w-boxed mx-auto md:p-wb-xxs grid grid-cols-12 justify-center items-start md:!pt-[50px] overflow-hidden \">\n\n\n        <div class=\"w-[calc(100%-20px)] ml-[10px] md:ml-0 mt-[-80px] md:mt-0 md:w-full col-span-12 md:col-span-7 bg-dunkelblau rounded-sm px-wb-s py-wb-m md:p-wb-m flex flex-col items-start gap-wb-xs relative z-10 order-last md:order-first\">\n\n            <svg class=\"absolute top-[-20px]  right-[-30px]\" width=\"205\" height=\"56\" viewBox=\"0 0 205 56\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                <path class=\"horizontal-reveal\" d=\"M135.833 27.6406L113.434 6.89515L90.9905 27.637L68.4922 6.8916L46.0673 27.637L23.6204 6.91645L3.60119 25.9727L0 22.4312L23.5654 0.00012207L46.0637 20.7668L68.4849 0.0249626L90.9868 20.7704L113.437 0.021414L135.837 20.7668L158.284 0.0249626L180.73 20.7704L201.457 1.66089L205 5.25568L180.727 27.637L158.284 6.8916L135.833 27.6406Z\" fill=\"#eaff6e\" \/>\n                <path class=\"horizontal-reveal\" d=\"M135.833 55.2811L113.434 34.5357L90.9905 55.2775L68.4922 34.5321L46.0673 55.2775L23.6204 34.5569L3.60119 53.6132L0 50.0717L23.5654 27.6406L46.0637 48.4073L68.4849 27.6655L90.9868 48.4109L113.437 27.6619L135.837 48.4073L158.284 27.6655L180.73 48.4109L201.457 29.3014L205 32.8962L180.727 55.2775L158.284 34.5321L135.833 55.2811Z\" fill=\"#eaff6e\" \/>\n            <\/svg>\n\n\n            <h2 class=\"text-weiss h4-tag\">MMK Friedrichshafen &#8211; Your MMK Moments to Share<\/h2>\n            <div class=\"text-weiss flex flex-col items-start gap-wb-xxs mt-wb-xxs\">\n\n                <p data-start=\"109\" data-end=\"299\">All photos are available for free download. Important: please use the download function \u2014 it\u2019s the only way to keep the image quality intact. We\u2019re happy if you tag the MMK on <span style=\"text-decoration: underline;\"><a href=\"https:\/\/www.linkedin.com\/feed\/\" target=\"_blank\" rel=\"noopener\">LinkedIn<\/a><\/span> and <a href=\"https:\/\/www.instagram.com\/mmk.muenchen\/\" target=\"_blank\" rel=\"noopener\"><span style=\"text-decoration: underline;\">Instagram<\/span><\/a> when sharing.<br \/>\nThanks for making your MMK Moments visible!<\/p>\n            <\/div>\n\n            \n\n        <\/div>\n\n\n        <div class=\"col-span-12 md:col-span-5 md:mt-[-50px]  md:ml-[-250px]\">\n\n            <img decoding=\"async\" class=\"w-full h-[300px] md:h-[450px] object-cover rounded-[500px] \" src=\"https:\/\/management-kolloquium.de\/wp-content\/uploads\/2025\/08\/MMK25_web_176-scaled.jpg\" alt=\"Audience at MMK25\" \/>\n        <\/div>\n\n\n    <\/section>\n\n\n\n\n\n\n    <div class=\"max-w-[1166px] mx-auto spacer-block block s \"><\/div>\n\n\n\n\n\n\n<section\n    class=\" w-full max-w-boxed mx-auto px-wb-xs flex items-start space-between gap-[20px] flex-wrap\"\n  data-gallery-block=\"gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf\"\n  data-folder=\"MMK-F\"\n>\n  <style>\n\t  \n\t  .gallery-load-more {\n\t\t  justify-self: center;\n\t  }\n    \/* Block-lokal: hidden immer zuverl\u00e4ssig *\/\n    [data-gallery-block=\"gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf\"] .hidden { display: none !important; }\n\n    \/* Spinner Loader *\/\n    [data-gallery-block=\"gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf\"] .gallery-loader {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      padding: 40px 0;\n    }\n    [data-gallery-block=\"gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf\"] .gallery-spinner {\n      width: 48px;\n      height: 48px;\n      border: 4px solid rgba(0,0,0,0.12);\n      border-top-color: #152644;\n      border-radius: 50%;\n      animation: gallery-spin 0.9s linear infinite;\n    }\n    @keyframes gallery-spin { to { transform: rotate(360deg); } }\n  <\/style>\n\n  <div class=\"w-full md:w-[250px] max-w-full bg-gelb text-dunkelblau rounded-sm p-wb-ss flex flex-col items-start gap-[20px]\">\n\n    <input\n      type=\"text\"\n      placeholder=\"Search...\"\n      class=\"speaker-search-input gallery-search-input w-full px-2 py-wb-xxs rounded-sm\"\n    \/>\n\n    <h3 class=\"h6-tag\">Filter<\/h3>\n\n          <div>\n        <p class=\"font-semibold text-left\">Filter<\/p>\n        <ul class=\"flex flex-col items-start gap-wb-xxxs list-none p-0 mt-[5px]\">\n          <li class=\"relative nobefore\">\n            <label class=\"font-medium\">\n              <input\n                type=\"radio\"\n                name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                value=\"\"\n                checked\n              >\n              All            <\/label>\n          <\/li>\n\n                      <li class=\"relative nobefore\">\n              <label class=\"font-medium\">\n                <input\n                  type=\"radio\"\n                  name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                  class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                  value=\"Speakers Dinner\"\n                >\n                Speakers Dinner              <\/label>\n            <\/li>\n                      <li class=\"relative nobefore\">\n              <label class=\"font-medium\">\n                <input\n                  type=\"radio\"\n                  name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                  class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                  value=\"Aula\"\n                >\n                Aula              <\/label>\n            <\/li>\n                      <li class=\"relative nobefore\">\n              <label class=\"font-medium\">\n                <input\n                  type=\"radio\"\n                  name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                  class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                  value=\"Speakers Corner\"\n                >\n                Speakers Corner              <\/label>\n            <\/li>\n                      <li class=\"relative nobefore\">\n              <label class=\"font-medium\">\n                <input\n                  type=\"radio\"\n                  name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                  class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                  value=\"Campus\"\n                >\n                Campus              <\/label>\n            <\/li>\n                      <li class=\"relative nobefore\">\n              <label class=\"font-medium\">\n                <input\n                  type=\"radio\"\n                  name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                  class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                  value=\"Academy\"\n                >\n                Academy              <\/label>\n            <\/li>\n                      <li class=\"relative nobefore\">\n              <label class=\"font-medium\">\n                <input\n                  type=\"radio\"\n                  name=\"filter-group-gallery-block-block_1beef8f0022b54c7c50cd9d8c26fdcaf-0\"\n                  class=\"filter-radio text-[16px] font-semibold appearance-none\"\n                  value=\"Hangar\"\n                >\n                Hangar              <\/label>\n            <\/li>\n                  <\/ul>\n      <\/div>\n    \n  <\/div>\n\n  <div class=\"flex-1\">\n\n    <div class=\"gallery-grid columns-2 md:columns-3 gap-wb-xs space-y-wb-xs\"><\/div>\n\n    <button\n      type=\"button\"\n      class=\"gallery-load-more main-button mt-wb-ss hidden load-more-images-button\"\n    >\n      <svg class=\"zacken-button\" width=\"77\" height=\"10\" viewBox=\"0 0 77 10\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n        <path d=\"M51.0202 10L42.6068 2.49454L34.1769 9.99872L25.7264 2.49326L17.3033 9.99872L8.87206 2.50225L1.35264 9.39659L0 8.11529L8.8514 0L17.302 7.51316L25.7236 0.00898703L34.1755 7.51444L42.6082 0.00770317L51.0216 7.51316L59.4529 0.00898703L67.8841 7.51444L75.6694 0.600847L77 1.9014L67.8828 9.99872L59.4529 2.49326L51.0202 10Z\" fill=\"#152644\"><\/path>\n      <\/svg>\n      <span class=\"main-button-text\">\n        load more      <\/span>\n    <\/button>\n\n    <!-- Loader -->\n    <div class=\"gallery-loader hidden\" aria-hidden=\"true\">\n      <div class=\"gallery-spinner\"><\/div>\n    <\/div>\n\n    <div class=\"gallery-no-results hidden text-center text-dunkelblau font-semibold rounded-sm bg-lila p-wb-s\">\n      <p class=\"text-weiss\">Nothing found&#8230;<\/p>\n    <\/div>\n\n  <\/div>\n<\/section>\n\n<script>\ndocument.addEventListener('DOMContentLoaded', () => {\n  const blocks = document.querySelectorAll('[data-gallery-block]');\n\n  blocks.forEach(block => {\n    const grid        = block.querySelector('.gallery-grid');\n    const loader      = block.querySelector('.gallery-loader');\n    const radios      = block.querySelectorAll('.filter-radio');\n    const searchInput = block.querySelector('.gallery-search-input');\n    const noResults   = block.querySelector('.gallery-no-results');\n    const loadMoreBtn = block.querySelector('.gallery-load-more');\n    const folder      = block.dataset.folder;\n\n    if (!grid || !searchInput || !folder) return;\n\n    \/\/ Safety: Loader beim Init garantiert verstecken\n    if (loader) loader.classList.add('hidden');\n\n    const LIMIT_INITIAL = 30; \/\/ best-of\n    const LIMIT_FULL    = 60; \/\/ full \/ filter \/ search\n    const MAX_PAGES_SEARCH = 30; \/\/ safety\n\n    const state = {\n      loading: false,\n      mode: 'initial',       \/\/ initial | full\n      queryType: 'browse',   \/\/ browse | filter | search\n      cursorFull: null,\n      fullStarted: false,\n      seen: new Set(),\n      debounce: null\n    };\n\n    function setLoading(on) {\n      if (!loader) return;\n      loader.classList.toggle('hidden', !on);\n    }\n    function showNoResults(show) {\n      if (!noResults) return;\n      noResults.classList.toggle('hidden', !show);\n    }\n    function showLoadMore(show) {\n      if (!loadMoreBtn) return;\n      loadMoreBtn.classList.toggle('hidden', !show);\n    }\n\n    \/\/ Button soll beim Laden weg sein\n    function beginLoading() {\n      setLoading(true);\n      showLoadMore(false);\n    }\n    \/\/ Nach dem Laden entscheidet shouldShowLoadMore, ob Button zur\u00fcckkommt\n    function endLoading(shouldShowLoadMore) {\n      setLoading(false);\n      showLoadMore(!!shouldShowLoadMore);\n    }\n\n    function resetFiltersToAll() {\n      const groups = new Map();\n      radios.forEach(r => {\n        if (!groups.has(r.name)) groups.set(r.name, []);\n        groups.get(r.name).push(r);\n      });\n      groups.forEach(rbs => {\n        const all = rbs.find(x => x.value === '');\n        if (all) all.checked = true;\n      });\n    }\n\n    function getActiveTags() {\n      const selected = {};\n      radios.forEach(rb => {\n        if (rb.checked && rb.value !== '') selected[rb.name] = rb.value;\n      });\n      return Object.values(selected);\n    }\n\n    function matchesSearch(img, term) {\n      if (!term) return true;\n      const s = term.toLowerCase();\n      const inId = (img.public_id || '').toLowerCase().includes(s);\n      const inTags = Array.isArray(img.tags) && img.tags.some(t => (t || '').toLowerCase().includes(s));\n      return inId || inTags;\n    }\n\n    function render(images, { append = false, searchTerm = '' } = {}) {\n      if (!append) grid.innerHTML = '';\n\n      let added = 0;\n\n      images.forEach(img => {\n        if (!img || !img.public_id) return;\n\n        if (state.queryType === 'search' && !matchesSearch(img, searchTerm)) return;\n\n        if (state.seen.has(img.public_id)) return;\n        state.seen.add(img.public_id);\n\n        const div = document.createElement('div');\n        div.classList.add('card');\n        div.innerHTML = `\n          <div class=\"relative group bg-neutral-200 animate-pulse overflow-hidden rounded-sm\">\n            <a href=\"${img.full_url}\" data-fancybox=\"${img.public_id}\">\n              <img decoding=\"async\"\n                src=\"${img.thumb_url}\"\n                alt=\"\"\n                class=\"w-full h-auto opacity-0 transition-opacity duration-300 rounded-sm\"\n                loading=\"lazy\"\n                onload=\"this.style.opacity='1'; this.closest('.group').classList.remove('animate-pulse');\"\n              \/>\n            <\/a>\n            <a\n              href=\"${img.download_url}\"\n              target=\"_blank\"\n              class=\"absolute top-2 right-2 bg-gelb text-dunkelblau font-semibold text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition\"\n            >Download<\/a>\n          <\/div>\n        `;\n        grid.appendChild(div);\n        added++;\n      });\n\n      if (typeof Fancybox !== 'undefined') {\n        Fancybox.bind(\"[data-fancybox]\", {\n  infinite: false,\n  dragToClose: true,\n  Carousel: { infinite: false },\n  Thumbs: false,\n  Toolbar: {\n    display: {\n      left: [],\n      middle: [],\n      right: [\"close\"],\n    },\n  },\n});\n\n      }\n      return added;\n    }\n\n    async function fetchPage({ mode, cursor, limit, tags }) {\n      const res = await fetch('https:\/\/management-kolloquium.de\/wp-admin\/admin-ajax.php?action=get_gallery_images', {\n        method: 'POST',\n        headers: { 'Content-Type': 'application\/json' },\n        body: JSON.stringify({ folder, mode, cursor, limit, tags })\n      });\n\n      const json = await res.json();\n      if (!json.success) throw (json.data || json);\n\n      return {\n        images: json.data.images || [],\n        nextCursor: json.data.next_cursor || null\n      };\n    }\n\n    \/\/ ---------- Loads ----------\n\n    async function loadInitial() {\n      if (state.loading) return;\n      state.loading = true;\n\n      state.mode = 'initial';\n      state.queryType = 'browse';\n      state.fullStarted = false;\n      state.cursorFull = null;\n      state.seen = new Set();\n\n      beginLoading();\n      showNoResults(false);\n\n      try {\n        const { images } = await fetchPage({ mode: 'initial', cursor: null, limit: LIMIT_INITIAL, tags: [] });\n        render(images, { append: false });\n\n        if (grid.children.length === 0) showNoResults(true);\n\n        \/\/ initial: Button IMMER zur\u00fcck (Start f\u00fcr full)\n        endLoading(true);\n      } catch (e) {\n        console.error('API error:', e);\n        showNoResults(true);\n        endLoading(false);\n      } finally {\n        state.loading = false;\n      }\n    }\n\n    async function loadMoreBrowseOrFilter() {\n      if (state.loading) return;\n      state.loading = true;\n\n      beginLoading();\n      showNoResults(false);\n\n      try {\n        const tags = (state.queryType === 'filter') ? getActiveTags() : [];\n\n        const { images, nextCursor } = await fetchPage({\n          mode: 'full',\n          cursor: state.cursorFull,\n          limit: LIMIT_FULL,\n          tags\n        });\n\n        render(images, { append: true });\n\n        state.mode = 'full';\n        state.fullStarted = true;\n        state.cursorFull = nextCursor;\n\n        if (grid.children.length === 0) showNoResults(true);\n\n        \/\/ Button nur zur\u00fcck, wenn noch Seiten existieren\n        endLoading(!!state.cursorFull);\n      } catch (e) {\n        console.error('API error:', e);\n        if (grid.children.length === 0) showNoResults(true);\n        endLoading(false);\n      } finally {\n        state.loading = false;\n      }\n    }\n\n    \/\/ Suche l\u00e4dt alle Treffer, kein Load more\n    async function loadSearchAll() {\n      if (state.loading) return;\n      state.loading = true;\n\n      const term = searchInput.value.trim();\n      state.queryType = 'search';\n      state.mode = 'full';\n      state.fullStarted = true;\n\n      beginLoading();\n      showNoResults(false);\n\n      \/\/ Suche immer ohne Filter\n      resetFiltersToAll();\n\n      \/\/ Reset Grid\n      grid.innerHTML = '';\n      state.seen = new Set();\n\n      \/\/ Suche hat NIE Load more\n      \/\/ (beginLoading blendet es eh aus, aber das hier ist die klare Regel)\n      showLoadMore(false);\n\n      try {\n        let cursor = null;\n        let page = 0;\n        let totalAdded = 0;\n\n        while (page < MAX_PAGES_SEARCH) {\n          const { images, nextCursor } = await fetchPage({\n            mode: 'full',\n            cursor,\n            limit: LIMIT_FULL,\n            tags: []\n          });\n\n          totalAdded += render(images, { append: true, searchTerm: term });\n\n          cursor = nextCursor;\n          page++;\n\n          if (!cursor) break;\n        }\n\n        if (totalAdded === 0) showNoResults(true);\n\n        endLoading(false);\n      } catch (e) {\n        console.error('API error:', e);\n        showNoResults(true);\n        endLoading(false);\n      } finally {\n        state.loading = false;\n      }\n    }\n\n    \/\/ ---------- Events ----------\n\n    \/\/ Filter \u00e4ndert: Suche l\u00f6schen, dann filter oder \"alle\" (=browse)\n    radios.forEach(rb => rb.addEventListener('change', () => {\n      \/\/ Suche immer zur\u00fccksetzen (exklusiv)\n      searchInput.value = '';\n\n      const activeTags = getActiveTags();\n\n      \/\/ Reset Grid & State\n      grid.innerHTML = '';\n      state.seen = new Set();\n      state.cursorFull = null;\n      state.fullStarted = true;\n\n      state.mode = 'full';\n      state.queryType = activeTags.length ? 'filter' : 'browse';\n\n      \/\/ Erste Seite im full Modus laden\n      loadMoreBrowseOrFilter();\n    }));\n\n    \/\/ Suche: Filter reset + alle Treffer ohne Pagination\/Button\n    searchInput.addEventListener('input', () => {\n      clearTimeout(state.debounce);\n      state.debounce = setTimeout(() => {\n        const term = searchInput.value.trim();\n\n        if (term) {\n          loadSearchAll();\n        } else {\n          resetFiltersToAll();\n          loadInitial();\n        }\n      }, 300);\n    });\n\n    \/\/ Load more:\n    \/\/ - initial: startet full browse\n    \/\/ - filter\/browse: paginiert\n    \/\/ - search: ignoriert (Button ist hidden)\n    loadMoreBtn && loadMoreBtn.addEventListener('click', () => {\n      if (state.queryType === 'search') return;\n\n      \/\/ Wenn wir noch im initial best-of sind: starte full browse\n      if (!state.fullStarted) {\n        state.queryType = 'browse';\n        state.mode = 'full';\n        state.cursorFull = null;\n        state.fullStarted = true;\n      }\n\n      loadMoreBrowseOrFilter();\n    });\n\n    \/\/ ---------- Init ----------\n    loadInitial();\n  });\n});\n<\/script>\n\n\n\n\n\n    <div class=\"max-w-[1166px] mx-auto spacer-block block l \"><\/div>\n\n\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":19,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-20270","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/pages\/20270","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/users\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/comments?post=20270"}],"version-history":[{"count":5,"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/pages\/20270\/revisions"}],"predecessor-version":[{"id":21739,"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/pages\/20270\/revisions\/21739"}],"wp:attachment":[{"href":"https:\/\/management-kolloquium.de\/en\/wp-json\/wp\/v2\/media?parent=20270"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}