src/StartPlatz/Bundle/AlphaBundle/Resources/views/Startup/startups.sp-public-spring-26.html.twig line 1

Open in your IDE?
  1. {# Level-3-Template: /startups — SP Public Spring 26 #}
  2. {# Card-Pattern: Brutalist 2b (Programm-Farb-Header) #}
  3. {# Shared Pattern: doc/modernisation/b-130-sp-public-spring-26/shared-pattern-startup-card.md #}
  4. {% extends "@StartPlatzStyleBundle/base.sp-public-spring-26.html.twig" %}
  5. {% block topicColor %}blue{% endblock %}
  6. {% block title %}Startups — STARTPLATZ{% endblock %}
  7. {% block metaData %}
  8.     <meta name="description" content="{{ parentPage.metaDescription|default('Startups im STARTPLATZ Ökosystem — Köln und Düsseldorf') }}">
  9.     <link rel="canonical" href="{{ url('homepage_startups_home') }}">
  10.     <link rel="alternate" hreflang="de" href="{{ url('homepage_startups_home') }}">
  11.     <link rel="alternate" hreflang="en" href="{{ url('homepage_startups_home_english') }}">
  12. {% endblock %}
  13. {% block content %}
  14. {# ===== HERO (kompakt, Blau→Gruen Gradient) ===== #}
  15. <section class="diagonal-bottom stripe-decoration pt-28 pb-24 sm:pt-32 sm:pb-28"
  16.          style="background: linear-gradient(135deg, #0080bb 0%, #7ab800 100%);">
  17.     <div class="relative z-10 max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
  18.         <h1 class="font-display text-4xl sm:text-5xl lg:text-6xl text-white mb-4">
  19.             {{ parentPage.title|default('Unsere Startups') }}
  20.         </h1>
  21.         <p class="text-lg text-white/90 max-w-2xl mx-auto">
  22.             {{ parentPage.teaser|default('Innovative Startups aus dem STARTPLATZ Ökosystem in Köln und Düsseldorf') }}
  23.         </p>
  24.     </div>
  25. </section>
  26. {# ===== FILTER + BANDED GRID ===== #}
  27. <div x-data="startupFilter()">
  28.     {# --- Filter-Bar --- #}
  29.     <section class="py-8 sm:py-10">
  30.         <div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
  31.             <p class="text-sm text-sp-gray/60 mb-4">
  32.                 <span x-text="visibleCount"></span> von {{ total }} Startups
  33.             </p>
  34.             <div class="flex flex-wrap gap-2">
  35.                 <button @click="filter = 'alle'"
  36.                         class="px-4 py-2 rounded-lg text-sm font-semibold transition-colors"
  37.                         :class="filter === 'alle' ? 'bg-sp-blue text-white' : 'bg-sp-gray-light text-sp-gray hover:bg-sp-gray-mid'">
  38.                     Alle ({{ total }})
  39.                 </button>
  40.                 {% for item in industries %}
  41.                     {% if item.industry is not empty %}
  42.                     <button @click="filter = '{{ item.industry|e('js') }}'"
  43.                             class="px-4 py-2 rounded-lg text-sm font-semibold transition-colors"
  44.                             :class="filter === '{{ item.industry|e('js') }}' ? 'bg-sp-blue text-white' : 'bg-sp-gray-light text-sp-gray hover:bg-sp-gray-mid'">
  45.                         {{ item.industry }} ({{ item.number }})
  46.                     </button>
  47.                     {% endif %}
  48.                 {% endfor %}
  49.             </div>
  50.         </div>
  51.     </section>
  52.     {# --- Startup-Grid mit Hintergrund-Baendern --- #}
  53.     {% set cardsPerBand = 6 %}
  54.     {% set totalCards = startups|length %}
  55.     {% set bands = ((totalCards / cardsPerBand)|round(0, 'ceil'))|default(1) %}
  56.     {% for band in 0..(bands - 1) %}
  57.         {% set bandStartups = startups|slice(band * cardsPerBand, cardsPerBand) %}
  58.         {% set isGray = (band % 2 == 1) %}
  59.         <section class="{{ isGray ? 'bg-sp-gray-light diagonal-both py-12 sm:py-14' : 'py-8 sm:py-10' }}">
  60.             <div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
  61.                 <div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
  62.                     {% for startup in bandStartups %}
  63.                     {# --- Programm-Farbe bestimmen (Prioritaet: Acc > GS > RP > SP > Neutral) --- #}
  64.                     {% set teamTags = (startup.teamId and teams[startup.teamId] is defined) ? teams[startup.teamId].tags|default('') : '' %}
  65.                     {% if '#badge-accelerator' in teamTags %}
  66.                         {% set headerStyle = 'background: linear-gradient(135deg, #004a99 0%, #0088dd 100%)' %}
  67.                         {% set progDot = 'bg-acc-blue' %}
  68.                         {% set progText = 'text-acc-blue' %}
  69.                         {% set progName = 'Accelerator' %}
  70.                     {% elseif '#badge-gruenderstipendium' in teamTags %}
  71.                         {% set headerStyle = 'background: linear-gradient(135deg, #a8614a 0%, #d9967a 100%)' %}
  72.                         {% set progDot = 'bg-gs-terracotta' %}
  73.                         {% set progText = 'text-gs-terracotta' %}
  74.                         {% set progName = 'Gründerstipendium' %}
  75.                     {% elseif '#badge-rheinland-pitch' in teamTags %}
  76.                         {% set headerStyle = 'background: linear-gradient(135deg, #c42535 0%, #ef7480 100%)' %}
  77.                         {% set progDot = 'bg-rp-red' %}
  78.                         {% set progText = 'text-rp-red' %}
  79.                         {% set progName = 'Rheinland Pitch' %}
  80.                     {% elseif '#badge-startplatz' in teamTags %}
  81.                         {% set headerStyle = 'background: linear-gradient(135deg, #5a8a00 0%, #8fd414 100%)' %}
  82.                         {% set progDot = 'bg-sp-green' %}
  83.                         {% set progText = 'text-sp-green-dark' %}
  84.                         {% set progName = 'STARTPLATZ' %}
  85.                     {% else %}
  86.                         {% set headerStyle = 'background: linear-gradient(135deg, #5c5f64 0%, #8a8d92 100%)' %}
  87.                         {% set progDot = '' %}
  88.                         {% set progText = 'text-sp-gray' %}
  89.                         {% set progName = '' %}
  90.                     {% endif %}
  91.                     <a href="{{ path('homepage_startup_single', {slug: startup.id ~ '-' ~ startup.slug|default('')}) }}"
  92.                        class="card-brut block rounded-xl overflow-hidden group"
  93.                        x-show="filter === 'alle' || filter === '{{ startup.industry|default('')|e('js') }}'">
  94.                         {# === Farbiger Header (Gradient) === #}
  95.                         <div class="px-6 py-5" style="{{ headerStyle }}">
  96.                             <div class="flex items-center justify-between mb-1.5">
  97.                                 <span class="text-[11px] font-bold uppercase tracking-[0.15em] text-white/90">
  98.                                     {{ startup.industry|default('') }}
  99.                                 </span>
  100.                                 {% if startup.city|default(false) or startup.location|default(false) %}
  101.                                 <span class="text-[11px] font-semibold text-white/75">
  102.                                     {{ startup.city|default(startup.location) }}
  103.                                 </span>
  104.                                 {% endif %}
  105.                             </div>
  106.                             <h3 class="text-xl font-bold text-white leading-tight">{{ startup.name }}</h3>
  107.                         </div>
  108.                         {# === Weisser Body === #}
  109.                         <div class="px-6 py-5 bg-white">
  110.                             {% if startup.oneSentencePitch %}
  111.                                 {% set pitchClean = startup.oneSentencePitch|striptags|trim %}
  112.                                 <p class="text-sm text-sp-gray/70 leading-relaxed mb-4">
  113.                                     {{ (pitchClean|length > 140 ? pitchClean|slice(0, 140) ~ '…' : pitchClean)|raw }}
  114.                                 </p>
  115.                             {% endif %}
  116.                             {# Programm-Indikator #}
  117.                             {% if progName %}
  118.                             <div class="flex items-center gap-2 mb-3">
  119.                                 <span class="w-2 h-2 rounded-full {{ progDot }}"></span>
  120.                                 <span class="text-[10px] font-bold {{ progText }} uppercase tracking-wider">{{ progName }}</span>
  121.                             </div>
  122.                             {% endif %}
  123.                             <span class="text-sm font-bold {{ progName ? progText : 'text-sp-gray' }}">Mehr erfahren &rarr;</span>
  124.                         </div>
  125.                     </a>
  126.                     {% endfor %}
  127.                 </div>
  128.             </div>
  129.         </section>
  130.     {% endfor %}
  131.     {# --- Keine Ergebnisse --- #}
  132.     <div x-show="visibleCount === 0" x-cloak class="text-center py-16">
  133.         <p class="text-sp-gray/60">Keine Startups in dieser Kategorie gefunden.</p>
  134.     </div>
  135.     {# --- Pagination --- #}
  136.     {% if maxPages > 1 %}
  137.     <nav class="flex items-center justify-center gap-2 py-12">
  138.         {% if thisPage > 1 %}
  139.             <a href="{{ path('homepage_startups_home', templateVars|merge({page: thisPage - 1})) }}"
  140.                class="px-4 py-2 rounded-lg text-sm font-semibold bg-sp-gray-light text-sp-gray hover:bg-sp-gray-mid transition-colors">
  141.                 &larr; Zurück
  142.             </a>
  143.         {% endif %}
  144.         <span class="px-4 py-2 text-sm text-sp-gray/60">
  145.             Seite {{ thisPage }} von {{ maxPages }}
  146.         </span>
  147.         {% if thisPage < maxPages %}
  148.             <a href="{{ path('homepage_startups_home', templateVars|merge({page: thisPage + 1})) }}"
  149.                class="px-4 py-2 rounded-lg text-sm font-semibold bg-sp-blue text-white hover:bg-sp-blue-dark transition-colors">
  150.                 Weiter &rarr;
  151.             </a>
  152.         {% endif %}
  153.     </nav>
  154.     {% endif %}
  155. </div>
  156. {% endblock %}
  157. {% block javascripts %}
  158. <script>
  159.     function startupFilter() {
  160.         const counts = {
  161.             'alle': {{ startups|length }},
  162.             {% for item in industries %}{% if item.industry is not empty %}'{{ item.industry|e('js') }}': {{ item.number }},{% endif %}
  163.             {% endfor %}
  164.         };
  165.         return {
  166.             filter: 'alle',
  167.             get visibleCount() {
  168.                 return counts[this.filter] || 0;
  169.             }
  170.         }
  171.     }
  172. </script>
  173. {% endblock %}