Testseite: Unterschied zwischen den Versionen

Aus Bündnis für Familie Tübingen.
Keine Bearbeitungszusammenfassung
Markierung: Manuelle Zurücksetzung
Keine Bearbeitungszusammenfassung
 
(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">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kalender - August 2026</title>
  <title>Viele Formen von Familie – Programm 2026</title>
<style>
  <style>
     *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
     :root {
      --bg: #f6f7fb;
      --surface: #ffffff;
      --surface-soft: #f8fafc;
      --text: #1f2937;
      --muted: #64748b;
      --line: #dbe1ea;
      --accent: #0f766e;
      --accent-dark: #115e59;
      --accent-soft: #ecfdf5;
      --radius: 16px;
    }


    *, *::before, *::after { box-sizing: border-box; }
    html { scroll-behavior: smooth; }
     body {
     body {
       font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
      margin: 0;
       background: #f1f5f9;
      color: var(--text);
      color: #1e293b;
      background: var(--bg);
      padding: 1.5rem 1rem 3rem;
       font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    }
       line-height: 1.5;
 
    /* ===== HEADER ===== */
    .cal-header {
      max-width: 860px;
      margin-bottom: 1.25rem;
      display: flex;
      align-items: baseline;
      gap: 1rem;
     }
     }
     .cal-header h2 {
     .wrap { width: min(100% - 2rem, 1200px); margin: 0 auto; padding: clamp(1rem, 3vw, 2rem) 0; }
      font-size: 1.6rem;
    h1, h2, h3 { line-height: 1.2; overflow-wrap: anywhere; }
       font-weight: 700;
    h1 { margin: 0 0 .5rem; font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem); }
       color: #0f172a;
    h2 { margin: 0 0 1rem; font-size: clamp(1.25rem, 1rem + .8vw, 1.6rem); }
       letter-spacing: -0.03em;
    .intro { margin: 0 0 1.5rem; color: var(--muted); }
    .notice {
       margin: 0 0 1.5rem;
      padding: .85rem 1rem;
      border-left: 4px solid #d97706;
      border-radius: 10px;
       color: #78350f;
       background: #fffbeb;
     }
     }
     .cal-header p {
     .month {
       font-size: 0.8rem;
       margin-bottom: 1.5rem;
       color: #94a3b8;
      padding: clamp(.85rem, 2vw, 1.25rem);
       font-weight: 400;
      background: var(--surface);
      border: 1px solid var(--line);
       border-radius: var(--radius);
       box-shadow: 0 8px 24px rgb(15 23 42 / 5%);
     }
     }
 
     .weekdays, .grid {
    /* ===== GRID WRAPPER ===== */
     .cal-wrap {
      max-width: 860px;
       display: grid;
       display: grid;
       grid-template-columns: repeat(7, 1fr);
       grid-template-columns: repeat(7, minmax(0, 1fr));
       border-radius: 16px;
       gap: clamp(4px, 1vw, 10px);
      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;
     }
     }
 
    .weekdays { margin-bottom: .5rem; }
     /* ===== COLUMN HEADERS ===== */
     .weekdays div {
    .col-header {
      padding: .25rem;
       background: #1e293b;
      color: var(--muted);
      font-size: .85rem;
       font-weight: 700;
       text-align: center;
       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 {
     .day {
       min-height: 90px;
      min-width: 0;
       padding: 0.5rem 0.5rem 0.4rem;
       min-height: 120px;
       background: #ffffff;
       padding: .6rem;
       background: var(--surface-soft);
      border: 1px solid var(--line);
      border-radius: 12px;
       display: flex;
       display: flex;
       flex-direction: column;
       flex-direction: column;
       gap: 0.3rem;
       gap: .5rem;
       position: relative;
    }
       transition: background 0.1s;
    .day.muted { opacity: .45; }
    .dn { color: #374151; font-size: .9rem; font-weight: 700; }
    .event {
      width: 100%;
      min-width: 0;
      padding: .65rem .7rem;
      color: var(--accent-dark);
      text-align: left;
      font: inherit;
      background: var(--accent-soft);
      border: 1px solid rgb(15 118 110 / 18%);
      border-left: 4px solid var(--accent);
       border-radius: 10px;
      cursor: pointer;
      overflow-wrap: anywhere;
       transition: background .2s ease, transform .2s ease;
    }
    .event:hover, .event:focus-visible { background: #d1fae5; transform: translateY(-1px); }
    .event:focus-visible, button:focus-visible {
      outline: 3px solid rgb(37 99 235 / 35%);
      outline-offset: 2px;
     }
     }
     .day.we { background: #fafbff; }
     .event-time { display: block; margin-bottom: .15rem; font-size: .75rem; font-weight: 800; }
    .et { display: block; font-size: .84rem; font-weight: 700; line-height: 1.35; }


     .day-num {
     .event-dialog {
       font-size: 0.75rem;
       width: min(92vw, 680px);
       font-weight: 600;
      max-height: 88vh;
       color: #64748b;
      padding: 0;
      color: var(--text);
      background: var(--surface);
      border: 0;
      border-radius: 18px;
      box-shadow: 0 20px 60px rgb(15 23 42 / 25%);
    }
    .event-dialog::backdrop { background: rgb(15 23 42 / 58%); }
    .dialog-inner { max-height: 88vh; overflow: auto; padding: 1.25rem; }
    .dialog-close {
      float: right;
      width: 2.75rem;
       height: 2.75rem;
      border: 0;
      border-radius: 50%;
       color: var(--text);
      background: #eef2f7;
      font-size: 1.5rem;
       line-height: 1;
       line-height: 1;
       width: 22px;
       cursor: pointer;
      height: 22px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      flex-shrink: 0;
     }
     }
    .dialog-close:hover { background: #e2e8f0; }
    .dialog-title { margin: 0 3.25rem .9rem 0; color: var(--accent-dark); font-size: clamp(1.15rem, 1rem + .8vw, 1.5rem); }
    .dialog-date { margin: 0 0 1rem; color: var(--muted); font-weight: 700; }
    .dialog-details { display: grid; gap: .85rem; }
    .detail-row { padding-top: .85rem; border-top: 1px solid var(--line); overflow-wrap: anywhere; }
    .detail-row strong { display: block; margin-bottom: .2rem; color: var(--text); }
    .detail-description { white-space: pre-line; }
    .dialog-link { color: var(--accent-dark); font-weight: 700; overflow-wrap: anywhere; }


     /* ===== CSS-ONLY POPUP ===== */
     @media (max-width: 700px) {
    .ev-toggle { display: none; }
      .wrap { width: min(100% - 1rem, 600px); }
      .month { padding: .85rem; border-radius: 14px; }
      .weekdays, .grid { grid-template-columns: repeat(7, minmax(30px, 1fr)); gap: 3px; }
      .weekdays div { padding: .2rem 0; font-size: .7rem; }
      .day { min-height: 62px; padding: .35rem; border-radius: 9px; }
      .dn { font-size: .78rem; }
      .event { padding: .55rem .6rem; border-left-width: 3px; }
      .event-time { font-size: .65rem; }
      .et { font-size: .74rem; }
    }


     .ev-chip {
     @media (max-width: 480px) {
       display: block;
       .grid { display: block; }
       background: #eff6ff;
       .day { display: none; }
       border-left: 3px solid #3b82f6;
       .day.has-events {
      border-radius: 0 6px 6px 0;
        display: block;
      padding: 0.22rem 0.4rem;
        min-height: auto;
       font-size: 0.67rem;
        margin-bottom: .7rem;
       line-height: 1.35;
        padding: .7rem;
       cursor: pointer;
        background: var(--surface-soft);
       user-select: none;
       }
       transition: background 0.15s, transform 0.1s;
      .day.has-events .dn { margin-bottom: .55rem; font-size: 1rem; }
       .day.muted { display: none; }
       .event { margin-top: .5rem; }
       .event-time { font-size: .76rem; }
       .et { font-size: .92rem; }
     }
     }
     .ev-chip:hover {
 
       background: #dbeafe;
     @media (prefers-reduced-motion: reduce) {
      transform: translateY(-1px);
       *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; }
     }
     }
     .chip-time  { font-weight: 700; color: #2563eb; display: block; }
  </style>
     .chip-title { color: #1e40af; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
</head>
<body>
  <main class="wrap">
    <h1>Viele Formen von Familie</h1>
     <p class="intro">Hier findet ihr eine Übersicht über das gesamte Programm zur Ausstellung. Die Ausstellung ist von Anfang Oktober bis Dezember 2026 in der Hauptstelle der Stadtbibliothek (Kinder- und Jugendbereich sowie 1. Stock) und im Stadtmuseum zu sehen.</p>
    <p class="notice"><strong>In Kl&ruml;rung:</strong> Kino – drei Sonntagsmatineen mit Familienfilmen.</p>
     <div id="calendar"></div>
  </main>


     /* Overlay */
  <dialog id="eventDialog" class="event-dialog" aria-labelledby="dialogTitle">
     .ev-overlay {
    <div class="dialog-inner">
       display: none;
      <button type="button" class="dialog-close" id="dialogClose" aria-label="Details schließen">&times;</button>
       position: fixed;
      <h2 id="dialogTitle" class="dialog-title"></h2>
       inset: 0;
      <p id="dialogDate" class="dialog-date"></p>
       background: rgba(15, 23, 42, 0.6);
      <div class="dialog-details">
       backdrop-filter: blur(2px);
        <div class="detail-row"><strong>Uhrzeit</strong><span id="dialogTime"></span></div>
       z-index: 9998;
        <div class="detail-row"><strong>Zielgruppe</strong><span id="dialogAudience"></span></div>
       cursor: pointer;
        <div class="detail-row"><strong>Treffpunkt</strong><span id="dialogPlace"></span></div>
     }
        <div class="detail-row"><strong>Beschreibung</strong><div id="dialogDescription" class="detail-description"></div></div>
        <div id="dialogLinkRow" class="detail-row" hidden><strong>Weitere Informationen / Anmeldung</strong><a id="dialogLink" class="dialog-link" target="_blank" rel="noopener"></a></div>
      </div>
    </div>
  </dialog>
 
  <script>
     /*
      =====================================================
      HIER ANGEBOTE ERGĨNZEN
      =====================================================
      Jedes Angebot ist ein Objekt mit diesen Feldern:
        - year: 2026
        - month: 10 (Oktober) oder 11 (November) oder 12 (Dezember)
        - day: 1 bis 31
        - time: z. B. "18:00 Uhr" oder "09:00–11:00 Uhr" oder "Ganzt䨤gig"
        - title: Kurzer Titel der Veranstaltung
        - audience: Zielgruppe
        - place: Ort / Treffpunkt
        - description: L&auml;ngere Beschreibung (mehrzeilig erlaubt)
        - link: Optional, z. B. "https://..." oder "mailto:..."
 
      Einfach ein neues Objekt in die passende Monatsliste einf&uuml;gen.
    */
 
     const events = [
      // Oktober 2026
      { year: 2026, month: 10, day: 6, time: "20:00–21:00 Uhr", title: "Hochsensible Kinder gut unterst&uuml;tzen und begleiten", audience: "Eltern", place: "Digitales Format", description: "Eltern sein in T&uuml;bingen – so geht's leichter! Welche konkreten Tipps haben T&uuml;binger Expert*innen f&uuml;r Eltern von j&uuml;ngeren und &auml;lteren Kindern – zu Erziehungsthemen, aber auch zu Herausforderungen, die das Elternsein mit sich bringt?\n\nDiese Online-Themenreihe ist eine Kooperation der Universit&auml;tsstadt T&uuml;bingen mit der Familien-Bildungsst&auml;tte (FBS) und dem B&uuml;ndnis f&uuml;r Familie (B&uuml;Fa).\n\nNach der Anmeldung erhalten Sie einen Zoom-Zugangscode. Ein eigener Zoom-Account ist nicht erforderlich.", link: "https://www.fbs-tuebingen.de/eltern-und-lebensthemen" },
      { year: 2026, month: 10, day: 8, time: "18:00 Uhr", title: "Filmvorf&uuml;hrung mit Gespr&auml;ch &uuml;ber den Film „All Inclusive“", audience: "Alle Generationen, f&uuml;r Kinder ab 7 Jahren", place: "Aula des Uhland-Gymnasiums, Uhlandstra&szlig;e 24, 72072 T&uuml;bingen", description: "Filmvorf&uuml;hrung mit Gespr&auml;ch &uuml;ber den Film „All Inclusive“. Die Veranstaltung wird vom Interkulturellen Mehrgenerationenhaus InF&ouml; e. V. und der Lebenshilfe veranstaltet." },
       { year: 2026, month: 10, day: 9, time: "15:00 Uhr", title: "Vorlesezeit in franz&ouml;sischer Sprache mit dem LESE-HAUS", audience: "Kinder von 4 bis 8 Jahren", place: "Stadtb&uuml;cherei T&uuml;bingen, Nonnengasse 19, Thekla-Waitz-Studio", description: "Geschichten und Lieder auf Franz&ouml;sisch laden Kinder spielerisch dazu ein, erste Eindr&uuml;cke der Sprache zu sammeln. Mitarbeitende des Institut Culturel Franco-Allemand (ICFA) gestalten diese besondere Vorlesezeit rund um das Thema Familie." },
      { year: 2026, month: 10, day: 9, time: "16:00 Uhr", title: "Vorlesezeit mit dem LESE-HAUS", audience: "Kinder von 4 bis 8 Jahren", place: "Stadtb&uuml;cherei T&uuml;bingen, Nonnengasse 19, Thekla-Waitz-Studio", description: "Bei dieser Vorlesezeit auf Deutsch stehen Geschichten rund um das Thema Familie im Mittelpunkt – mal lustig, mal spannend, mal ber&uuml;hrend." },
      { year: 2026, month: 10, day: 9, time: "17:00 Uhr", title: "Vorlesezeit in ukrainischer Sprache mit dem LESE-HAUS", audience: "Kinder von 4 bis 8 Jahren", place: "Stadtb&uuml;cherei T&uuml;bingen, Nonnengasse 19, Thekla-Waitz-Studio", description: "Lesepatinnen aus der Ukraine lesen Geschichten in ihrer Muttersprache und geben Einblicke in ukrainische Erz&auml;hltraditionen rund um das Thema Familie." },
      { year: 2026, month: 10, day: 21, time: "17:00 Uhr", title: "Familiensprachen und Sprachencaf&eacute;s im elkiko Familienzentrum", audience: "T&uuml;binger Familien und Interessierte", place: "Stadtb&uuml;cherei, Hauptstelle", description: "Mitmachangebote zum Thema Familiensprachen sowie Informationen zu den Sprachencaf&eacute;s im elkiko Familienzentrum." },
      { year: 2026, month: 10, day: 22, time: "18:00 Uhr", title: "Preisverleihung des 23. Schreibwettbewerbs f&uuml;r junge Menschen der Buchhandlung Wekenmann", audience: "Alle Interessierten", place: "Museumsgesellschaft Obere S&auml;le, Wilhelmstra&szlig;e 3, T&uuml;bingen", description: "Festliche Preisverleihung: Die sechs Preistr&auml;ger*innen des Schreibwettbewerbs „We are family“ lesen aus ihren Siegertexten. Dr. Daniela H&uuml;ttig, Erste Landesbeamtin und Schirmherrin des Wettbewerbs, spricht ein Gru&szlig;wort. Musikalisch umrahmt wird der Abend von Singer/Songwriter Jakob Longfield." },
      { year: 2026, month: 10, day: 31, time: "15:00 Uhr", title: "BamBam-Band &amp; Halloween Fair for Kids", audience: "Familien mit Kindern ab 3 Jahren", place: "d.a.i. T&uuml;bingen, Karlstra&szlig;e 3, T&uuml;bingen", description: "Konzert und Halloween f&uuml;r die ganze Familie. Ab 15 Uhr spielt die BamBam-Band. Ab 16 Uhr hei&szlig;t es Trick or Treat: Kinderdisco, Basteln, Gaming und jede Menge Spa&szlig; mit Popcorn und Snacks.\n\nAlles kostenfrei auf Spendenbasis. Kost&uuml;me sind sehr willkommen. Die Veranstaltung findet in deutscher und englischer Sprache statt.", link: "https://www.dai-tuebingen.de/bambam" },
 
      // November 2026
      { year: 2026, month: 11, day: 5, time: "09:00–11:00 Uhr", title: "„Der Widerspenstigen Z&auml;hmung?“ – Workshop", audience: "Eltern von Kindern im Vorschulalter", place: "Jugend- und Familienberatungszentrum T&uuml;bingen, Bismarckstra&szlig;e 110, 72072 T&uuml;bingen, 2. Stock", description: "Manche Kinder sind Weltmeister darin, Erwachsene an ihre Grenzen zu bringen. Gemeinsam soll ein Verst&auml;ndnis f&uuml;r als schwierig empfundene kindliche Verhaltensweisen entwickelt werden. Ziel ist au&szlig;erdem, neue Reaktionsweisen auszuprobieren, um unn&ouml;tige Machtk&auml;mpfe im Familienalltag zu vermeiden.", link: "mailto:jfbz-tue@kreis-tuebingen.de" },
       { year: 2026, month: 11, day: 5, time: "19:00 Uhr", title: "Nach der Elternzeit – welche Betreuung passt f&uuml;r mein Kind und unsere Familie?", audience: "(Werdende) Eltern, die sich &uuml;ber Kleinkindbetreuung informieren m&ouml;chten", place: "Online", description: "Um eine passende Betreuung nach der Elternzeit zu finden, braucht es einen &Uuml;berblick &uuml;ber die verschiedenen M&ouml;glichkeiten der Kinderbetreuung. Welches Modell passt f&uuml;r welches Kind und welche Familie, welche Kriterien k&ouml;nnen eine Rolle spielen und was sind die Besonderheiten der Kindertagespflege?", link: "mailto:info@tageselternverein.de" },
       { year: 2026, month: 11, day: 9, time: "18:00–20:00 Uhr", title: "Wassergew&ouml;hnung – wie unterst&uuml;tze ich mein Kind?", audience: "Alle Eltern und Erziehungsberechtigten", place: "Hirsch Begegnungsst&auml;tte, Hirschgasse 9, 72070 T&uuml;bingen", description: "Schwimmen f&uuml;r alle Kinder informiert zu einem besseren Verst&auml;ndnis von Wassergew&ouml;hnung. Enthalten sind alltagspraktische &Uuml;bungen f&uuml;r Kinder vor dem Schwimmkurs. Eintritt frei, Getr&auml;nke gegen Spende." },
       { year: 2026, month: 11, day: 10, time: "18:00 Uhr", title: "Live-Show mit Miriam Davoudvandi: Das k&ouml;nnen wir uns nicht leisten", audience: "Alle Interessierten", place: "Gemeindehaus Lamm, Gro&szlig;er Saal 1, Am Markt 7, T&uuml;bingen", description: "Was es bedeutet, in Deutschland arm aufzuwachsen: Journalistin und Podcasterin Miriam Davoudvandi (aka Cashmiri) bringt mit dem aktuellen Buch „Das k&ouml;nnen wir uns nicht leisten“ ihre Geschichte mit Texten, pers&ouml;nlichen Geschichten, Humor und Pop auf die B&uuml;hne." },
      { year: 2026, month: 11, day: 10, time: "17:00–19:00 Uhr", title: "Das Geheimnis des Bildungserfolgs, Teil 1: Entwicklungsaufgaben", audience: "Eltern von Kindern der 1. bis 6. Klasse", place: "Br&uuml;ckenhaus, Werkstra&szlig;e 8, 72074 T&uuml;bingen", description: "Teil 1: Entwicklungsaufgaben, Eltern-Kind-Bindung, Mutter und Vater als Unterst&uuml;tzer*innen, Lernen und Selbstwirksamkeit. Wie k&ouml;nnen Eltern ihr Kind unterst&uuml;tzen, damit es in der Schule gut zurechtkommt? Zu diesen Fragen gibt es jeweils einen kurzen Vortrag auf Deutsch, Englisch, Arabisch und Persisch." },
      { year: 2026, month: 11, day: 11, time: "19:00–21:00 Uhr", title: "„Zu Hause in einer Erziehungsstelle“ – Podiumsdiskussion", audience: "Eltern", place: "Lorettoplatz 30, T&uuml;bingen", description: "Vorstellung von kit jugendhilfe mit dem Schwerpunkt auf professionellen Pflegefamilien und anschlie&szlig;ender Diskussionsrunde. Eine kurze R&uuml;ckmeldung zur Teilnahme w&auml;re sch&ouml;n, ist aber nicht zwingend notwendig.", link: "mailto:andrea.leitgeb@kit-jugendhilfe.de" },
      { year: 2026, month: 11, day: 15, time: "14:00–17:00 Uhr", title: "Familienbasteln im Caf&eacute; frieDa", audience: "Familien mit Kindern, 0 bis 99 Jahre", place: "Caf&eacute; frieDa, Friedrich-Dannenmann-Stra&szlig;e 69, 72070 T&uuml;bingen", description: "Bunte Bastelstunde im Caf&eacute; frieDa mit Angeboten f&uuml;r die ganz Kleinen und Gr&ouml;&szlig;eren. Unter anderem werden Leinenbeutel bemalt und bedruckt. F&uuml;r die gro&szlig;en G&auml;ste gibt es Kaffee und Kuchen auf Spendenbasis. Keine Anmeldung erforderlich." },
      { year: 2026, month: 11, day: 17, time: "17:00–19:00 Uhr", title: "Das Geheimnis des Bildungserfolgs, Teil 2: Erfolg in Schule, Bildung und Teilhabe", audience: "Eltern von Kindern der 1. bis 6. Klasse", place: "Br&uuml;ckenhaus, Werkstra&szlig;e 8, 72074 T&uuml;bingen", description: "Das Geheimnis des Bildungserfolgs – was Ihr Kind von Ihnen als Mutter und Vater braucht. Drei internationale Pr&auml;senz-Elternabende auf Deutsch, Englisch, Arabisch und Persisch f&uuml;r Eltern von Kindern der 1. bis 6. Klasse." },
       { year: 2026, month: 11, day: 19, time: "09:30–11:30 Uhr", title: "Zutaten f&uuml;r ein starkes Familienleben", audience: "Eltern mit Kindern im Alter von 0 bis 3 Jahren", place: "Jugend- und Familienberatungszentrum T&uuml;bingen, Bismarckstra&szlig;e 110, 72072 T&uuml;bingen, 2. Stock", description: "Rezeptideen f&uuml;r ein starkes Familienleben – Zutaten: Feinf&uuml;hligkeit, Zeit, Vertrauen und mehr. In gem&uuml;tlicher und kleinkindorientierter Atmosph&auml;re wird gemeinsam dar&uuml;ber gesprochen, was f&uuml;r ein starkes Familienleben sorgt.", link: "mailto:fruehehilfen@kreis-tuebingen.de" },
      { year: 2026, month: 11, day: 21, time: "10:00–15:00 Uhr", title: "Bastelspa&szlig; f&uuml;r die ganze Familie – Thanksgiving Edition", audience: "Familien mit Kindern aller Altersgruppen", place: "d.a.i. T&uuml;bingen, Karlstra&szlig;e 3, Bibliothek", description: "Kommen Sie ins d.a.i. T&uuml;bingen und basteln Sie gemeinsam wundersch&ouml;ne Thanksgiving-Dekorationen. Feiern Sie den Tag der Dankbarkeit bei einer gem&uuml;tlichen Bastelrunde in der d.a.i.-Bibliothek." },
       { year: 2026, month: 11, day: 24, time: "17:00–19:00 Uhr", title: "Das Geheimnis des Bildungserfolgs, Teil 3: Medienerziehung", audience: "Eltern von Kindern der 1. bis 6. Klasse", place: "Br&uuml;ckenhaus, Werkstra&szlig;e 8, 72074 T&uuml;bingen", description: "Das Geheimnis des Bildungserfolgs – was Ihr Kind von Ihnen als Mutter und Vater braucht. Drei internationale Pr&auml;senz-Elternabende auf Deutsch, Englisch, Arabisch und Persisch." },
      { year: 2026, month: 11, day: 24, time: "Ganzt&auml;gig", title: "Gemeinsam gegen Abfall – Papierrecycling in der Stadtb&uuml;cherei", audience: "Familien", place: "Stadtb&uuml;cherei T&uuml;bingen, Nonnengasse 19, T&uuml;bingen", description: "Im Rahmen der Europ&auml;ischen Woche der Abfallvermeidung bietet die Stadtb&uuml;cherei T&uuml;bingen eine besondere Mitmachaktion an: An einem Papierbindetisch k&ouml;nnen aus einseitig bedrucktem Altpapier Spiralbl&ouml;cke hergestellt werden. Papier ist vor Ort verf&uuml;gbar, kann aber auch gerne mitgebracht werden." },
      { year: 2026, month: 11, day: 25, time: "Ganzt&auml;gig", title: "Gemeinsam gegen Abfall – Papierrecycling in der Stadtb&uuml;cherei", audience: "Familien", place: "Stadtb&uuml;cherei T&uuml;bingen, Nonnengasse 19, T&uuml;bingen", description: "Im Rahmen der Europ&auml;ischen Woche der Abfallvermeidung bietet die Stadtb&uuml;cherei T&uuml;bingen eine besondere Mitmachaktion an: An einem Papierbindetisch k&ouml;nnen aus einseitig bedrucktem Altpapier Spiralbl&ouml;cke hergestellt werden. Papier ist vor Ort verf&uuml;gbar, kann aber auch gerne mitgebracht werden." },
       { year: 2026, month: 11, day: 26, time: "Ganzt&auml;gig", title: "Gemeinsam gegen Abfall – Papierrecycling in der Stadtb&uuml;cherei", audience: "Familien", place: "Stadtb&uuml;cherei T&uuml;bingen, Nonnengasse 19, T&uuml;bingen", description: "Im Rahmen der Europ&auml;ischen Woche der Abfallvermeidung bietet die Stadtb&uuml;cherei T&uuml;bingen eine besondere Mitmachaktion an: An einem Papierbindetisch k&ouml;nnen aus einseitig bedrucktem Altpapier Spiralbl&ouml;cke hergestellt werden. Papier ist vor Ort verf&uuml;gbar, kann aber auch gerne mitgebracht werden." }
     ];


     /* Modal */
     /*
    .ev-modal {
       =====================================================
       display: none;
       AB HIER NICHTS MEHR ÄNDERN (au&szlig;er bei Bedarf)
       position: fixed;
       =====================================================
      top: 50%;
     */
      left: 50%;
      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);
     }


     .ev-toggle:checked ~ .ev-overlay { display: block; }
     const monthNames = { 10: "Oktober", 11: "November", 12: "Dezember" };
     .ev-toggle:checked ~ .ev-modal  { display: block; }
     const weekdayNames = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];


     .ev-modal-date {
     function getDaysInMonth(year, month) {
       font-size: 0.72rem;
       return new Date(year, month, 0).getDate();
      font-weight: 600;
      color: #3b82f6;
      letter-spacing: 0.07em;
      text-transform: uppercase;
      margin-bottom: 0.4rem;
     }
     }
     .ev-modal-title {
 
       font-size: 1.3rem;
     function getWeekday(year, month, day) {
       font-weight: 700;
       const date = new Date(year, month - 1, day);
       color: #0f172a;
       let wd = date.getDay(); // 0 = Sonntag
      letter-spacing: -0.02em;
       return wd === 0 ? 6 : wd - 1; // 0 = Montag
      margin-bottom: 0.75rem;
      line-height: 1.3;
     }
     }
     .ev-modal-time {
 
       display: inline-flex;
     function escapeHtml(str) {
      align-items: center;
       return str
      gap: 0.35rem;
        .replace(/&/g, "&amp;")
      font-size: 0.82rem;
        .replace(/</g, "&lt;")
      font-weight: 600;
        .replace(/>/g, "&gt;")
      color: #2563eb;
        .replace(/"/g, "&quot;");
      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; }


     /* Close button */
     function renderCalendar() {
    .ev-close {
      const container = document.getElementById("calendar");
       position: absolute;
       const monthsToRender = [10, 11, 12];
       top: 1rem;
 
      right: 1rem;
       monthsToRender.forEach(month => {
      background: #f1f5f9;
        const monthEvents = events.filter(e => e.month === month && e.year === 2026);
      border: none;
        if (monthEvents.length === 0) return;
      border-radius: 50%;
 
      width: 30px;
        const section = document.createElement("section");
      height: 30px;
        section.className = "month";
      cursor: pointer;
        section.setAttribute("aria-labelledby", `month-${month}`);
      font-size: 0.8rem;
 
      color: #64748b;
        const heading = document.createElement("h2");
      display: flex;
        heading.id = `month-${month}`;
      align-items: center;
        heading.textContent = `${monthNames[month]} 2026`;
      justify-content: center;
        section.appendChild(heading);
      user-select: none;
 
      transition: background 0.15s;
        const weekdays = document.createElement("div");
    }
        weekdays.className = "weekdays";
    .ev-close:hover { background: #e2e8f0; color: #0f172a; }
        weekdays.setAttribute("aria-hidden", "true");
        weekdayNames.forEach(name => {
          const div = document.createElement("div");
          div.textContent = name;
          weekdays.appendChild(div);
        });
        section.appendChild(weekdays);
 
        const grid = document.createElement("div");
        grid.className = "grid";
 
        const daysInMonth = getDaysInMonth(2026, month);
        const firstWeekday = getWeekday(2026, month, 1);


    /* ===== MOBILE ===== */
        // Leere Tage vor dem 1. des Monats
    @media (max-width: 580px) {
        for (let i = 0; i < firstWeekday; i++) {
      body { padding: 1rem 0.5rem 2rem; }
          const prevDay = getDaysInMonth(2026, month - 1) - firstWeekday + 1 + i;
      .cal-header { flex-direction: column; gap: 0.2rem; }
          const dayDiv = document.createElement("div");
      .cal-header h2 { font-size: 1.3rem; }
          dayDiv.className = "day muted";
      .col-header { font-size: 0.58rem; padding: 0.5rem 0; }
          const dn = document.createElement("div");
      .day, .day-empty { min-height: 56px; }
          dn.className = "dn";
      .day { padding: 0.3rem 0.25rem; }
          dn.textContent = prevDay;
      .day-num { font-size: 0.68rem; }
          dayDiv.appendChild(dn);
      .ev-chip { font-size: 0.6rem; padding: 0.15rem 0.25rem; }
          grid.appendChild(dayDiv);
      .chip-title { display: none; }
        }
    }
  </style>
</head>
<body>


<div class="cal-header">
        // Eigentliche Tage
  <h2>Kalender - August 2026</h2>
        for (let day = 1; day <= daysInMonth; day++) {
  <p>Klick auf einen Termin fuer mehr Details</p>
          const dayEvents = monthEvents.filter(e => e.day === day);
</div>
          const dayDiv = document.createElement("div");
          dayDiv.className = "day";
          if (dayEvents.length > 0) dayDiv.classList.add("has-events");


<div class="cal-wrap">
          const dn = document.createElement("div");
  <span class="col-header">Mo</span>
          dn.className = "dn";
  <span class="col-header">Di</span>
          dn.textContent = day;
  <span class="col-header">Mi</span>
          dayDiv.appendChild(dn);
  <span class="col-header">Do</span>
  <span class="col-header">Fr</span>
  <span class="col-header">Sa</span>
  <span class="col-header">So</span>


          dayEvents.forEach(ev => {
            const btn = document.createElement("button");
            btn.type = "button";
            btn.className = "event";
            btn.setAttribute("data-date", `${day}. ${monthNames[month]} 2026`);
            btn.setAttribute("data-time", ev.time);
            btn.setAttribute("data-audience", ev.audience);
            btn.setAttribute("data-place", ev.place);
            btn.setAttribute("data-description", ev.description);
            if (ev.link) btn.setAttribute("data-link", ev.link);


    <!-- ============================================================
            const timeSpan = document.createElement("span");
    LEERE ZELLEN: August 2026 beginnt an einem Samstag (Spalte 6)
            timeSpan.className = "event-time";
    -> 5 leere Zellen fuer Mo bis Fr
            timeSpan.textContent = ev.time;
    ============================================================ -->
    <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 -->


    <!-- Sa  1 --> <div class="day we"><div class="day-num">1</div></div>
            const titleSpan = document.createElement("span");
    <!-- So  2 --> <div class="day we"><div class="day-num">2</div></div>
            titleSpan.className = "et";
    <!-- Mo  3 --> <div class="day">  <div class="day-num">3</div></div>
            titleSpan.textContent = ev.title;
    <!-- Di  4 --> <div class="day">  <div class="day-num">4</div></div>


    <!-- ============================================================
            btn.appendChild(timeSpan);
    TERMIN HINZUFUEGEN: Kopiere den Block zwischen den Stern-Kommentaren
            btn.appendChild(titleSpan);
    in den gewuenschten Tag. Aendere:
            dayDiv.appendChild(btn);
      - 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)
    ============================================================ -->


    <!-- Mi  5 - TERMIN -->
          grid.appendChild(dayDiv);
    <div class="day">
         }
      <div class="day-num">5</div>
      <!-- *** 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>


    <!-- Do  6 --> <div class="day">  <div class="day-num">6</div></div>
        // Leere Tage nach dem letzten Tag des Monats (auff&uuml;llen auf volle Wochen)
    <!-- Fr  7 --> <div class="day">  <div class="day-num">7</div></div>
        const totalCells = firstWeekday + daysInMonth;
    <!-- Sa  8 --> <div class="day we"><div class="day-num">8</div></div>
        const remaining = (7 - (totalCells % 7)) % 7;
    <!-- So  9 --> <div class="day we"><div class="day-num">9</div></div>
        for (let i = 1; i <= remaining; i++) {
    <!-- Mo 10 --> <div class="day">  <div class="day-num">10</div></div>
          const dayDiv = document.createElement("div");
    <!-- Di 11 --> <div class="day">  <div class="day-num">11</div></div>
          dayDiv.className = "day muted";
          const dn = document.createElement("div");
          dn.className = "dn";
          dn.textContent = i;
          dayDiv.appendChild(dn);
          grid.appendChild(dayDiv);
        }


    <!-- Mi 12 - TERMIN -->
         section.appendChild(grid);
    <div class="day">
         container.appendChild(section);
      <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>


     <!-- Do 13 --> <div class="day">  <div class="day-num">13</div></div>
     // Dialog-Logik
     <!-- 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>
      const dialog = document.getElementById("eventDialog");
    <!-- So 16 --> <div class="day we"><div class="day-num">16</div></div>
      const closeButton = document.getElementById("dialogClose");
    <!-- Mo 17 --> <div class="day">  <div class="day-num">17</div></div>
      const title = document.getElementById("dialogTitle");
    <!-- Di 18 --> <div class="day">  <div class="day-num">18</div></div>
      const date = document.getElementById("dialogDate");
    <!-- Mi 19 --> <div class="day">  <div class="day-num">19</div></div>
      const time = document.getElementById("dialogTime");
    <!-- Do 20 --> <div class="day">  <div class="day-num">20</div></div>
      const audience = document.getElementById("dialogAudience");
    <!-- Fr 21 --> <div class="day">  <div class="day-num">21</div></div>
      const place = document.getElementById("dialogPlace");
    <!-- Sa 22 --> <div class="day we"><div class="day-num">22</div></div>
      const description = document.getElementById("dialogDescription");
      const linkRow = document.getElementById("dialogLinkRow");
      const link = document.getElementById("dialogLink");


    <!-- So 23 - TERMIN -->
      document.addEventListener("click", (event) => {
    <div class="day we">
        if (!event.target.classList.contains("event")) return;
      <div class="day-num">23</div>
         const btn = event.target;
      <!-- *** TERMIN ANFANG *** -->
         title.textContent = btn.querySelector(".et").textContent.trim();
      <input type="checkbox" class="ev-toggle" id="ev-03">
        date.textContent = btn.dataset.date || "";
      <label class="ev-chip" for="ev-03">
         time.textContent = btn.dataset.time || "Nicht angegeben";
         <span class="chip-time">11:00</span>
         audience.textContent = btn.dataset.audience || "Nicht angegeben";
         <span class="chip-title">Familienfest Stadtpark</span>
         place.textContent = btn.dataset.place || "Nicht angegeben";
      </label>
         description.textContent = btn.dataset.description || "Keine Beschreibung vorhanden.";
      <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>


    <!-- Mo 24 --> <div class="day">  <div class="day-num">24</div></div>
        const url = btn.dataset.link;
    <!-- Di 25 --> <div class="day">  <div class="day-num">25</div></div>
        if (url) {
    <!-- Mi 26 --> <div class="day">  <div class="day-num">26</div></div>
          linkRow.hidden = false;
    <!-- Do 27 --> <div class="day">  <div class="day-num">27</div></div>
          link.href = url;
    <!-- Fr 28 --> <div class="day">  <div class="day-num">28</div></div>
          link.textContent = url.startsWith("mailto:") ? url.replace("mailto:", "") : url;
    <!-- Sa 29 --> <div class="day we"><div class="day-num">29</div></div>
          link.target = url.startsWith("mailto:") ? "_self" : "_blank";
    <!-- So 30 --> <div class="day we"><div class="day-num">30</div></div>
        } else {
    <!-- Mo 31 --> <div class="day">  <div class="day-num">31</div></div>
          linkRow.hidden = true;
          link.removeAttribute("href");
          link.textContent = "";
        }


    <!-- ============================================================
        dialog.showModal();
    LEERE ZELLEN NACH TAG 31
      });
    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 -->


</div><!-- .cal-wrap -->
      closeButton.addEventListener("click", () => dialog.close());
      dialog.addEventListener("click", (event) => {
        if (event.target === dialog) dialog.close();
      });
    })();


    // Kalender beim Laden rendern
    renderCalendar();
  </script>
</body>
</body>
</html>
</html>

Aktuelle Version vom 7. September 2026, 12:25 Uhr

<!doctype html> Viele Formen von Familie – Programm 2026

Viele Formen von Familie

Hier findet ihr eine Übersicht über das gesamte Programm zur Ausstellung. Die Ausstellung ist von Anfang Oktober bis Dezember 2026 in der Hauptstelle der Stadtbibliothek (Kinder- und Jugendbereich sowie 1. Stock) und im Stadtmuseum zu sehen.

In Kl&ruml;rung: Kino – drei Sonntagsmatineen mit Familienfilmen.

Uhrzeit
Zielgruppe
Treffpunkt
Beschreibung