Testseite: Unterschied zwischen den Versionen

Aus Bündnis für Familie Tübingen.
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Markierung: Manuelle Zurücksetzung
 
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
<!DOCTYPE html>
<html lang="de">
<html lang="de">
<head>
<head>
<meta charset="UTF-8">
<meta charset="UTF-8" />
<title>Familienangebote August 2026</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kalender - August 2026</title>
<style>
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }


<style>
    body {
body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-family: Arial, sans-serif;
      background: #f1f5f9;
     margin: 20px;
      color: #1e293b;
}
      padding: 1.5rem 1rem 3rem;
     }
 
    /* ===== HEADER ===== */
    .cal-header {
      max-width: 860px;
      margin-bottom: 1.25rem;
      display: flex;
      align-items: baseline;
      gap: 1rem;
    }
    .cal-header h2 {
      font-size: 1.6rem;
      font-weight: 700;
      color: #0f172a;
      letter-spacing: -0.03em;
    }
    .cal-header p {
      font-size: 0.8rem;
      color: #94a3b8;
      font-weight: 400;
    }
 
    /* ===== GRID WRAPPER ===== */
    .cal-wrap {
      max-width: 860px;
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      border-radius: 16px;
      overflow: hidden;
      box-shadow: 0 1px 3px rgba(0,0,0,.07), 0 8px 24px rgba(0,0,0,.08);
      border: 1px solid #e2e8f0;
      background: #e2e8f0; /* gap color between cells */
      gap: 1px;
    }
 
    /* ===== COLUMN HEADERS ===== */
    .col-header {
      background: #1e293b;
      text-align: center;
      padding: 0.6rem 0.2rem;
      font-size: 0.7rem;
      font-weight: 600;
      color: #94a3b8;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }
 
    /* ===== DAY CELLS ===== */
    .day-empty {
      min-height: 90px;
      background: #f8fafc;
    }
 
    .day {
      min-height: 90px;
      padding: 0.5rem 0.5rem 0.4rem;
      background: #ffffff;
      display: flex;
      flex-direction: column;
      gap: 0.3rem;
      position: relative;
      transition: background 0.1s;
    }
    .day.we { background: #fafbff; }
 
    .day-num {
      font-size: 0.75rem;
      font-weight: 600;
      color: #64748b;
      line-height: 1;
      width: 22px;
      height: 22px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      flex-shrink: 0;
    }


h2 {
    /* ===== CSS-ONLY POPUP ===== */
     text-align: center;
     .ev-toggle { display: none; }
}


.calendar {
    .ev-chip {
    display: grid;
      display: block;
     grid-template-columns: repeat(7, 1fr);
      background: #eff6ff;
     gap: 8px;
      border-left: 3px solid #3b82f6;
}
      border-radius: 0 6px 6px 0;
      padding: 0.22rem 0.4rem;
      font-size: 0.67rem;
      line-height: 1.35;
      cursor: pointer;
      user-select: none;
      transition: background 0.15s, transform 0.1s;
     }
    .ev-chip:hover {
      background: #dbeafe;
      transform: translateY(-1px);
     }
    .chip-time  { font-weight: 700; color: #2563eb; display: block; }
    .chip-title { color: #1e40af; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }


.weekday {
    /* Overlay */
    font-weight: bold;
    .ev-overlay {
    text-align: center;
      display: none;
    padding: 10px;
      position: fixed;
    background: #f0f0f0;
      inset: 0;
}
      background: rgba(15, 23, 42, 0.6);
      backdrop-filter: blur(2px);
      z-index: 9998;
      cursor: pointer;
    }


.day {
    /* Modal */
    border: 1px solid #ccc;
    .ev-modal {
    min-height: 120px;
      display: none;
    padding: 8px;
      position: fixed;
    cursor: pointer;
      top: 50%;
    background: #fff;
      left: 50%;
    transition: 0.2s;
      transform: translate(-50%, -50%);
}
      z-index: 9999;
      background: #fff;
      border-radius: 16px;
      max-width: 460px;
      width: calc(100% - 2rem);
      padding: 2rem;
      box-shadow: 0 20px 60px rgba(0,0,0,0.2), 0 2px 8px rgba(0,0,0,0.08);
    }


.day:hover {
    .ev-toggle:checked ~ .ev-overlay { display: block; }
     background: #f8f8f8;
     .ev-toggle:checked ~ .ev-modal  { display: block; }
}


.day-number {
    .ev-modal-date {
     font-weight: bold;
      font-size: 0.72rem;
     margin-bottom: 5px;
      font-weight: 600;
}
      color: #3b82f6;
      letter-spacing: 0.07em;
      text-transform: uppercase;
      margin-bottom: 0.4rem;
     }
    .ev-modal-title {
      font-size: 1.3rem;
      font-weight: 700;
      color: #0f172a;
      letter-spacing: -0.02em;
      margin-bottom: 0.75rem;
      line-height: 1.3;
    }
    .ev-modal-time {
      display: inline-flex;
      align-items: center;
      gap: 0.35rem;
      font-size: 0.82rem;
      font-weight: 600;
      color: #2563eb;
      background: #eff6ff;
      border-radius: 20px;
      padding: 0.3rem 0.8rem;
      margin-bottom: 1rem;
     }
    .ev-modal-note {
      font-size: 0.88rem;
      color: #475569;
      line-height: 1.65;
      margin-bottom: 1.25rem;
    }
    .ev-modal-link {
      display: inline-flex;
      align-items: center;
      gap: 0.4rem;
      background: #2563eb;
      color: #fff;
      text-decoration: none;
      font-size: 0.82rem;
      font-weight: 600;
      border-radius: 8px;
      padding: 0.5rem 1rem;
      transition: background 0.15s;
    }
    .ev-modal-link:hover { background: #1d4ed8; }


.note {
    /* Close button */
    font-size: 13px;
    .ev-close {
    white-space: pre-wrap;
      position: absolute;
}
      top: 1rem;
</style>
      right: 1rem;
      background: #f1f5f9;
      border: none;
      border-radius: 50%;
      width: 30px;
      height: 30px;
      cursor: pointer;
      font-size: 0.8rem;
      color: #64748b;
      display: flex;
      align-items: center;
      justify-content: center;
      user-select: none;
      transition: background 0.15s;
    }
    .ev-close:hover { background: #e2e8f0; color: #0f172a; }


    /* ===== MOBILE ===== */
    @media (max-width: 580px) {
      body { padding: 1rem 0.5rem 2rem; }
      .cal-header { flex-direction: column; gap: 0.2rem; }
      .cal-header h2 { font-size: 1.3rem; }
      .col-header { font-size: 0.58rem; padding: 0.5rem 0; }
      .day, .day-empty { min-height: 56px; }
      .day { padding: 0.3rem 0.25rem; }
      .day-num { font-size: 0.68rem; }
      .ev-chip { font-size: 0.6rem; padding: 0.15rem 0.25rem; }
      .chip-title { display: none; }
    }
  </style>
</head>
</head>
<body>
<body>


<h2>Familienangebote – August 2026</h2>
<div class="cal-header">
  <h2>Kalender - August 2026</h2>
  <p>Klick auf einen Termin fuer mehr Details</p>
</div>


<div class="calendar" id="calendar"></div>
<div class="cal-wrap">
  <span class="col-header">Mo</span>
  <span class="col-header">Di</span>
  <span class="col-header">Mi</span>
  <span class="col-header">Do</span>
  <span class="col-header">Fr</span>
  <span class="col-header">Sa</span>
  <span class="col-header">So</span>


<script>
const calendar = document.getElementById("calendar");


const weekdays = [
    <!-- ============================================================
     "Mo","Di","Mi","Do","Fr","Sa","So"
    LEERE ZELLEN: August 2026 beginnt an einem Samstag (Spalte 6)
];
    -> 5 leere Zellen fuer Mo bis Fr
    ============================================================ -->
     <div class="day-empty"></div><!-- Mo -->
    <div class="day-empty"></div><!-- Di -->
    <div class="day-empty"></div><!-- Mi -->
    <div class="day-empty"></div><!-- Do -->
    <div class="day-empty"></div><!-- Fr -->


weekdays.forEach(day => {
    <!-- Sa  1 --> <div class="day we"><div class="day-num">1</div></div>
     const el = document.createElement("div");
     <!-- So  2 --> <div class="day we"><div class="day-num">2</div></div>
     el.className = "weekday";
     <!-- Mo  3 --> <div class="day">  <div class="day-num">3</div></div>
     el.textContent = day;
     <!-- Di  4 --> <div class="day">  <div class="day-num">4</div></div>
    calendar.appendChild(el);
});


// August 2026 beginnt an einem Samstag
    <!-- ============================================================
const firstDayOffset = 5;
    TERMIN HINZUFUEGEN: Kopiere den Block zwischen den Stern-Kommentaren
    in den gewuenschten Tag. Aendere:
      - id="ev-XX"  -> eindeutige ID, z.B. ev-04, ev-05 ...
      - chip-time  -> Uhrzeit
      - chip-title  -> Kurztitel (wird im Chip angezeigt)
      - ev-modal-date  -> Datum ausgeschrieben
      - ev-modal-title -> Voller Titel
      - ev-modal-time  -> Uhrzeit
      - ev-modal-note  -> Beschreibungstext
      - href          -> URL (oder ganzen <a>-Tag entfernen wenn keine URL)
    ============================================================ -->


// Leere Felder vor dem 1. August
    <!-- Mi  5 - TERMIN -->
for(let i = 0; i < firstDayOffset; i++){
    <div class="day">
    const empty = document.createElement("div");
      <div class="day-num">5</div>
    calendar.appendChild(empty);
      <!-- *** TERMIN ANFANG *** -->
}
      <input type="checkbox" class="ev-toggle" id="ev-01">
      <label class="ev-chip" for="ev-01">
        <span class="chip-time">14:00</span>
        <span class="chip-title">Stadtfest Tuebingen</span>
      </label>
      <label class="ev-overlay" for="ev-01"></label>
      <div class="ev-modal">
        <label class="ev-close" for="ev-01">✕</label>
        <div class="ev-modal-date">Mittwoch, 5. August 2026</div>
        <div class="ev-modal-title">Stadtfest Tuebingen</div>
        <div class="ev-modal-time">🕐 14:00 Uhr</div>
        <div class="ev-modal-note">Das jaehrliche Stadtfest in der Innenstadt mit Live-Musik, Essen und Marktstaenden. Parkplaetze sind begrenzt - Anreise mit OPNV empfohlen.</div>
        <a class="ev-modal-link" href="https://www.tuebingen.de" target="_blank" rel="noopener">🔗 Mehr Infos</a>
      </div>
      <!-- *** TERMIN ENDE *** -->
    </div>


// Tage erzeugen
    <!-- Do  6 --> <div class="day">  <div class="day-num">6</div></div>
for(let day = 1; day <= 31; day++) {
    <!-- Fr  7 --> <div class="day">  <div class="day-num">7</div></div>
    <!-- Sa  8 --> <div class="day we"><div class="day-num">8</div></div>
    <!-- So  9 --> <div class="day we"><div class="day-num">9</div></div>
    <!-- Mo 10 --> <div class="day">  <div class="day-num">10</div></div>
    <!-- Di 11 --> <div class="day">  <div class="day-num">11</div></div>


     const cell = document.createElement("div");
     <!-- Mi 12 - TERMIN -->
    cell.className = "day";
    <div class="day">
      <div class="day-num">12</div>
      <!-- *** TERMIN ANFANG *** -->
      <input type="checkbox" class="ev-toggle" id="ev-02">
      <label class="ev-chip" for="ev-02">
        <span class="chip-time">09:30</span>
        <span class="chip-title">Netzwerktreffen Buendnis</span>
      </label>
      <label class="ev-overlay" for="ev-02"></label>
      <div class="ev-modal">
        <label class="ev-close" for="ev-02">✕</label>
        <div class="ev-modal-date">Mittwoch, 12. August 2026</div>
        <div class="ev-modal-title">Netzwerktreffen Buendnis fuer Familie</div>
        <div class="ev-modal-time">🕐 09:30 Uhr</div>
        <div class="ev-modal-note">Quartalsweise Netzwerktreffen aller Mitglieder des Buendnisses fuer Familie Tuebingen. Bitte Berichte bis 08.08. einreichen.</div>
        <a class="ev-modal-link" href="https://www.buendnis-fuer-familie-tuebingen.de/Netzwerke_und_Arbeitsgruppen" target="_blank" rel="noopener">🔗 Mehr Infos</a>
      </div>
      <!-- *** TERMIN ENDE *** -->
    </div>


     const key = "august2026_" + day;
     <!-- Do 13 --> <div class="day">  <div class="day-num">13</div></div>
     const savedText = localStorage.getItem(key) || "";
     <!-- Fr 14 --> <div class="day">  <div class="day-num">14</div></div>
    <!-- Sa 15 --> <div class="day we"><div class="day-num">15</div></div>
    <!-- So 16 --> <div class="day we"><div class="day-num">16</div></div>
    <!-- Mo 17 --> <div class="day">  <div class="day-num">17</div></div>
    <!-- Di 18 --> <div class="day">  <div class="day-num">18</div></div>
    <!-- Mi 19 --> <div class="day">  <div class="day-num">19</div></div>
    <!-- Do 20 --> <div class="day">  <div class="day-num">20</div></div>
    <!-- Fr 21 --> <div class="day">  <div class="day-num">21</div></div>
    <!-- Sa 22 --> <div class="day we"><div class="day-num">22</div></div>


     cell.innerHTML = `
     <!-- So 23 - TERMIN -->
         <div class="day-number">${day}</div>
    <div class="day we">
         <div class="note">${savedText}</div>
      <div class="day-num">23</div>
     `;
      <!-- *** TERMIN ANFANG *** -->
      <input type="checkbox" class="ev-toggle" id="ev-03">
      <label class="ev-chip" for="ev-03">
        <span class="chip-time">11:00</span>
        <span class="chip-title">Familienfest Stadtpark</span>
      </label>
      <label class="ev-overlay" for="ev-03"></label>
      <div class="ev-modal">
        <label class="ev-close" for="ev-03">✕</label>
        <div class="ev-modal-date">Sonntag, 23. August 2026</div>
        <div class="ev-modal-title">Familienfest im Stadtpark</div>
         <div class="ev-modal-time">🕐 11:00 Uhr</div>
         <div class="ev-modal-note">Grosses Familienfest mit Spiel, Spass und Unterhaltung fuer Kinder jeden Alters. Eintritt frei, Anmeldung nicht erforderlich.</div>
        <a class="ev-modal-link" href="https://www.buendnis-fuer-familie-tuebingen.de/Aktuelles" target="_blank" rel="noopener">🔗 Mehr Infos</a>
      </div>
      <!-- *** TERMIN ENDE *** -->
     </div>


     cell.addEventListener("click", () => {
     <!-- Mo 24 --> <div class="day">  <div class="day-num">24</div></div>
        const current = localStorage.getItem(key) || "";
    <!-- Di 25 --> <div class="day">  <div class="day-num">25</div></div>
        const text = prompt(
    <!-- Mi 26 --> <div class="day">  <div class="day-num">26</div></div>
            "Eintrag für den " + day + ". August 2026:",
    <!-- Do 27 --> <div class="day">  <div class="day-num">27</div></div>
            current
    <!-- Fr 28 --> <div class="day">  <div class="day-num">28</div></div>
        );
    <!-- Sa 29 --> <div class="day we"><div class="day-num">29</div></div>
    <!-- So 30 --> <div class="day we"><div class="day-num">30</div></div>
    <!-- Mo 31 --> <div class="day">  <div class="day-num">31</div></div>


        if(text !== null) {
    <!-- ============================================================
            localStorage.setItem(key, text);
    LEERE ZELLEN NACH TAG 31
            cell.querySelector(".note").textContent = text;
    31. August = Montag -> noch 6 leere Zellen (Di bis So)
        }
    ============================================================ -->
     });
    <div class="day-empty"></div><!-- Di -->
    <div class="day-empty"></div><!-- Mi -->
    <div class="day-empty"></div><!-- Do -->
    <div class="day-empty"></div><!-- Fr -->
    <div class="day-empty"></div><!-- Sa -->
     <div class="day-empty"></div><!-- So -->


    calendar.appendChild(cell);
</div><!-- .cal-wrap -->
}
</script>


</body>
</body>
</html>
</html>

Aktuelle Version vom 10. Juni 2026, 11:26 Uhr

Kalender - August 2026

Kalender - August 2026

Klick auf einen Termin fuer mehr Details

Mo Di Mi Do Fr Sa So
1
2
3
4
5
Mittwoch, 5. August 2026
Stadtfest Tuebingen
🕐 14:00 Uhr
Das jaehrliche Stadtfest in der Innenstadt mit Live-Musik, Essen und Marktstaenden. Parkplaetze sind begrenzt - Anreise mit OPNV empfohlen.
🔗 Mehr Infos
6
7
8
9
10
11
12
Mittwoch, 12. August 2026
Netzwerktreffen Buendnis fuer Familie
🕐 09:30 Uhr
Quartalsweise Netzwerktreffen aller Mitglieder des Buendnisses fuer Familie Tuebingen. Bitte Berichte bis 08.08. einreichen.
🔗 Mehr Infos
13
14
15
16
17
18
19
20
21
22
23
Sonntag, 23. August 2026
Familienfest im Stadtpark
🕐 11:00 Uhr
Grosses Familienfest mit Spiel, Spass und Unterhaltung fuer Kinder jeden Alters. Eintritt frei, Anmeldung nicht erforderlich.
🔗 Mehr Infos
24
25
26
27
28
29
30
31