    :root {
      --bg: #f3f6fb;
      --panel: #ffffff;
      --line: #d7e0ee;
      --text: #1f2a37;
      --muted: #5b6677;
      --accent: #0f766e;
      --accent-soft: #d9f4f1;
    }

    * { box-sizing: border-box; }

    body {
      margin: 0;
      font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
      color: var(--text);
      background:
        radial-gradient(circle at 0% 0%, #d9ecff 0%, transparent 40%),
        radial-gradient(circle at 100% 100%, #e6f8ef 0%, transparent 35%),
        var(--bg);
      min-height: 100vh;
      min-height: 100dvh;
    }

    .layout {
      display: grid;
      grid-template-columns: 340px 1fr;
      min-height: 100vh;
      min-height: 100dvh;
    }

    .sidebar {
      border-right: 1px solid var(--line);
      background: var(--panel);
      padding: 18px 14px;
      overflow-y: auto;
    }

    /* Hamburger + Schliessen-Button: nur im Kompaktmodus sichtbar (siehe unten). */
    .menu-toggle,
    .menu-close {
      display: none;
      flex: 0 0 auto;
      width: 34px;
      height: 34px;
      align-items: center;
      justify-content: center;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: #f8fbff;
      color: var(--text);
      font-size: 1rem;
      line-height: 1;
      cursor: pointer;
    }

    .menu-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
    }

    /* Kurz-Einblendung (Toast) z. B. nach dem Setzen eines Bookmarks. */
    .app-toast {
      position: fixed;
      left: 50%;
      bottom: 24px;
      transform: translateX(-50%) translateY(16px);
      max-width: 90vw;
      background: var(--accent);
      color: #fff;
      padding: 10px 18px;
      border-radius: 999px;
      font-size: 0.9rem;
      font-weight: 600;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      box-shadow: 0 12px 30px rgba(16, 24, 40, 0.28);
      opacity: 0;
      pointer-events: none;
      transition: opacity 200ms ease, transform 200ms ease;
      z-index: 3000;
    }

    .app-toast.show {
      opacity: 1;
      transform: translateX(-50%) translateY(0);
    }

    /* Banner ganz oben im Menue, ueber "Kapitel / Abschnitte" (aus app-cfg.php).
       Container mit Bild + optionalem zentriertem Text-Overlay. Halbe Bildhoehe:
       aspect-ratio = doppeltes Breiten/Hoehen-Verhaeltnis des Bildes (2045x1529).
       object-fit:cover fuellt randlos und ohne Verzerrung (oben/unten beschnitten). */
    .menu-banner {
      position: relative;
      display: block;
      width: 100%;
      aspect-ratio: 4090 / 1529;
      border-radius: 8px;
      border: 1px solid var(--line);
      margin-bottom: 12px;
      overflow: hidden;
    }

    .menu-banner-img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    /* Der NAME DER APP im Banner - links oben, weiss mit Schlagschatten.
       ⚠ LINKS OBEN, NICHT MITTIG. Mittig lag der Text ueber dem Motiv und war
         je nach Bild schwer zu lesen; oben links ist bei allen drei Bannern die
         ruhigste Ecke. Der Schatten bleibt trotzdem - ein Banner kann getauscht
         werden, und dann liegt dort ploetzlich etwas Helles. */
    .menu-banner-text {
      position: absolute;
      inset: 0;
      display: flex;
      align-items: flex-start;
      justify-content: flex-start;
      text-align: left;
      padding: 9px 12px 0;
      color: #ffffff;
      font-weight: 700;
      line-height: 1.15;
      font-size: clamp(0.98rem, 3.6vw, 1.35rem);
      letter-spacing: 0.01em;
      text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85), 0 1px 2px rgba(0, 0, 0, 0.9);
      pointer-events: none;
      /* ⚠ EIN DUNKLER VERLAUF UNTER DER SCHRIFT, nicht nur ein Schatten. Der
         Ausschnitt links oben ist je Banner ein anderer - beim Kuestenpatent
         faellt der Titel dort auf den weissen Rumpf, und der Schatten allein
         reichte nicht. Der Verlauf laeuft nach 70 % aus, das Bild bleibt also
         Bild. */
      background: linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.18) 45%, rgba(0, 0, 0, 0) 72%);
    }

    /* ---- Zeile zurueck zu My Skipper360 -------------------------------
       Steht zwischen Banner und "Kapitel / Abschnitte" - dort, wo man nach
       dem Blick aufs Banner ohnehin hinsieht.
       ⚠ SICHTBAR ALS LINK, nicht als Knopf: Es ist ein Weg hinaus, keine
         Aktion in dieser App. Der Pfeil sagt die Richtung. */
    .menu-portal {
      display: flex;
      align-items: center;
      gap: 6px;
      margin: -4px 0 12px;
      padding: 5px 9px;
      border: 1px solid var(--line);
      border-radius: 8px;
      text-decoration: none;
      color: var(--accent);
      background: var(--accent-soft);
      font-size: 0.9rem;
      font-weight: 600;
    }
    .menu-portal:hover {
      border-color: #bce8e4;
      filter: brightness(0.97);
    }
    .menu-portal-pfeil {
      font-size: 0.95rem;
      line-height: 1;
      opacity: .8;
    }
    /* Zeile: Portal-Link links (waechst), Profil-Knopf rechts (v87) */
    .menu-portal-row { display: flex; align-items: stretch; gap: 8px; margin: -4px 0 12px; }
    .menu-portal-row .menu-portal { flex: 1 1 auto; margin: 0; }
    .menu-profil {
      flex: 0 0 auto;
      padding: 5px 10px;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: var(--accent-soft);
      color: var(--accent);
      font: inherit;
      font-size: 0.9rem;
      font-weight: 600;
      cursor: pointer;
      white-space: nowrap;
    }
    .menu-profil:hover { border-color: #bce8e4; filter: brightness(0.97); }
    /* Profil-Fenster (v87) - Stil wie die Login-Card */
    .profil-modal[hidden] { display: none; }
    /* ⚠ ÜBER DEM MENÜ. Auf dem Handy liegt die Seitenleiste als Vollbild-Overlay (z-index 1300)
       über der Seite - mit z-index 60 öffnete sich das Profil DAHINTER und war erst sichtbar,
       wenn das Menü zuging (23.09.). Jetzt wie das Bookmarks-Fenster oberhalb davon. */
    .profil-modal { position: fixed; inset: 0; z-index: 2100; display: flex; align-items: center; justify-content: center; padding: 20px; }
    .profil-backdrop { position: absolute; inset: 0; background: rgba(16, 24, 40, 0.45); }
    .profil-dialog { position: relative; width: 100%; max-width: 560px; max-height: 88dvh; overflow: auto; background: #fff; border-radius: 14px; box-shadow: 0 18px 48px rgba(16, 24, 40, 0.28); }
    @media (max-width: 560px) {
      .profil-modal { padding: 10px; align-items: flex-start; padding-top: max(12px, env(safe-area-inset-top, 0px)); }
      .profil-dialog { max-height: calc(100dvh - 24px); }
      .profil-body { padding: 14px; }
      .profil-tab th:nth-child(3), .profil-tab td:nth-child(3) { display: none; }   /* Spalte "zuletzt" - auf dem Handy zu eng */
    }
    .profil-head { display: flex; align-items: center; justify-content: space-between; background: #2176c1; color: #fff; font-size: 17px; font-weight: 600; padding: 14px 18px; }
    .profil-close { background: none; border: 0; color: #fff; font-size: 18px; cursor: pointer; }
    .profil-body { padding: 16px 18px; font-size: 14px; color: #1d2327; }
    .profil-body h4 { margin: 14px 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: #50575e; }
    .profil-body p { margin: 0 0 6px; }
    .profil-muted { color: #6b7280; font-size: 12.5px; }
    .profil-warn { color: #b91c1c; font-weight: 600; }
    .profil-tab { width: 100%; border-collapse: collapse; font-size: 13px; }
    .profil-tab th, .profil-tab td { text-align: left; padding: 5px 6px; border-bottom: 1px solid #eceff1; vertical-align: top; }
    .profil-tab th { font-size: 11.5px; color: #6b7280; font-weight: 600; }
    .profil-tab tr.profil-ist td { background: #f0f7fd; }
    .profil-entf { font: inherit; font-size: 12px; padding: 3px 9px; border: 1px solid #c3c7cb; border-radius: 6px; background: #fff; cursor: pointer; }
    .profil-entf:hover { border-color: #b91c1c; color: #b91c1c; }
    .profil-name { font: inherit; font-size: 12px; padding: 0 5px; border: 0; background: none; color: #6b7280; cursor: pointer; }
    .profil-name:hover { color: #2176c1; }
    .profil-foot { padding: 10px 18px 14px; border-top: 1px solid #eceff1; font-size: 13px; }
    .profil-foot a { color: #2176c1; text-decoration: none; font-weight: 600; }

    .menu-backdrop {
      display: none;
    }

    .sidebar h1 {
      margin: 0 0 8px;
      font-size: 1.1rem;
    }

    .sidebar p {
      margin: 0 0 16px;
      color: var(--muted);
      font-size: 0.9rem;
      line-height: 1.4;
    }

    .menu-error {
      color: #b42318;
      background: #fef3f2;
      border: 1px solid #fecdca;
      border-radius: 8px;
      padding: 10px;
    }

    .app-version {
      margin: -6px 0 12px;
      color: var(--muted);
      font-size: 0.75rem;
      letter-spacing: 0.02em;
      text-align: left;
    }

    details {
      border: 1px solid var(--line);
      border-radius: 10px;
      margin-bottom: 10px;
      overflow: hidden;
      background: #fbfdff;
    }

    summary {
      list-style: none;
      cursor: pointer;
      padding: 10px 12px;
      font-weight: 600;
      background: #f8fbff;
      border-bottom: 1px solid transparent;
    }

    details[open] summary {
      border-bottom-color: var(--line);
    }

    summary::-webkit-details-marker {
      display: none;
    }

    .section-list {
      padding: 6px 8px;
      display: grid;
      gap: 2px;
    }

    .section-row {
      display: flex;
      align-items: center;
      gap: 4px;
      /* Feste Zeilenhoehe: ein FB-Badge daneben darf die Zeile NICHT hoeher machen
         als eine Zeile ohne Badge. min-height = Standard-Buttonhoehe. */
      min-height: 32px;
    }

    .section-row .section-link {
      flex: 1 1 auto;
      min-width: 0;
    }

    .section-link {
      display: block;
      text-decoration: none;
      color: var(--text);
      border: 1px solid transparent;
      border-radius: 8px;
      padding: 5px 9px;
      font-size: 0.93rem;
    }

    /* Favoriten-Stern neben jedem Abschnitt. */
    .fav-star {
      flex: 0 0 auto;
      width: 28px;
      height: 28px;
      border: 0;
      background: transparent;
      color: #c7ced9;
      font-size: 1.05rem;
      line-height: 1;
      cursor: pointer;
      border-radius: 6px;
    }

    .fav-star:hover {
      background: var(--accent-soft);
      color: var(--accent);
    }

    .fav-star.is-fav {
      color: #f2b705;
    }

    /* Button in der Sidebar, der das Bookmarks-Modal oeffnet. */
    /* Bookmarks-Button in der oberen Bar (neben den Pfeilen) - immer sichtbar. */
    .bm-open {
      flex: 0 0 auto;
      width: 30px;
      height: 30px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: #fffdf5;
      color: #f2b705;
      font-size: 1.05rem;
      line-height: 1;
      cursor: pointer;
    }

    .bm-open:hover {
      background: #fef7e0;
      border-color: #f5e0a3;
    }

    /* Bookmarks-Modal (Overlay). */
    .bm-modal[hidden] {
      display: none;
    }

    .bm-modal {
      position: fixed;
      inset: 0;
      z-index: 2000;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }

    .bm-backdrop {
      position: absolute;
      inset: 0;
      background: rgba(17, 24, 39, 0.45);
    }

    .bm-dialog {
      position: relative;
      z-index: 1;
      width: min(560px, 100%);
      max-height: 82vh;
      display: flex;
      flex-direction: column;
      background: var(--panel);
      border: 1px solid var(--line);
      border-radius: 14px;
      box-shadow: 0 24px 60px rgba(16, 24, 40, 0.28);
      overflow: hidden;
    }

    .bm-head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 14px 16px;
      border-bottom: 1px solid var(--line);
      background: linear-gradient(90deg, #eef6ff, #f6fffc);
      font-weight: 600;
    }

    .bm-close {
      width: 30px;
      height: 30px;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: #ffffff;
      color: var(--text);
      font-size: 1rem;
      line-height: 1;
      cursor: pointer;
    }

    .bm-body {
      padding: 12px 16px 16px;
      overflow-y: auto;
    }

    .bm-body h3 {
      margin: 14px 0 8px;
      font-size: 0.85rem;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      color: var(--muted);
    }

    .bm-body h3:first-child {
      margin-top: 0;
    }

    .bm-list {
      display: grid;
      gap: 6px;
    }

    .bm-empty {
      color: var(--muted);
      font-size: 0.88rem;
      font-style: italic;
      padding: 4px 2px;
    }

    .bm-item {
      display: flex;
      align-items: center;
      gap: 6px;
    }

    .bm-link {
      flex: 1 1 auto;
      min-width: 0;
      display: flex;
      flex-direction: column;
      text-decoration: none;
      color: var(--text);
      border: 1px solid var(--line);
      border-radius: 8px;
      padding: 7px 10px;
      background: #fbfdff;
    }

    .bm-link:hover {
      background: var(--accent-soft);
      border-color: #bce8e4;
    }

    .bm-sec {
      font-weight: 600;
      font-size: 0.92rem;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .bm-chap {
      font-size: 0.76rem;
      color: var(--muted);
    }

    /* Gespeicherte Position (Ueberschrift) in einem Bookmark. */
    .bm-head {
      font-size: 0.78rem;
      color: var(--accent);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .bm-action {
      flex: 0 0 auto;
      width: 28px;
      height: 28px;
      border: 0;
      background: transparent;
      color: var(--muted);
      font-size: 1.05rem;
      line-height: 1;
      cursor: pointer;
      border-radius: 6px;
    }

    .bm-action:hover:not(:disabled) {
      background: #fdecec;
      color: #b42318;
    }

    .bm-action:disabled {
      color: #d5dbe4;
      cursor: default;
    }

    /* Kurs-Bereich im Modal. */
    .bm-course-head,
    .bm-favhead {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      gap: 8px;
    }

    .bm-hint {
      font-size: 0.72rem;
      color: var(--muted);
    }

    .bm-item.is-current .bm-link {
      border-color: var(--accent);
      background: var(--accent-soft);
    }

    .bm-link.bm-missing {
      opacity: 0.55;
      pointer-events: none;
    }

    .bm-textbtn {
      border: 0;
      background: transparent;
      color: #b42318;
      font-size: 0.8rem;
      cursor: pointer;
      padding: 2px 4px;
      border-radius: 6px;
    }

    .bm-textbtn:hover {
      background: #fdecec;
    }

    .bm-footer {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 16px;
      padding-top: 12px;
      border-top: 1px solid var(--line);
    }

    .bm-footbtn {
      flex: 1 1 auto;
      min-width: 140px;
      padding: 9px 12px;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: #f8fbff;
      color: var(--text);
      font-weight: 600;
      font-size: 0.86rem;
      cursor: pointer;
    }

    .bm-footbtn:hover {
      background: var(--accent-soft);
      border-color: #bce8e4;
    }

    /* Kurs-Schrittanzeige in der oberen Bar. */
    .course-badge[hidden] {
      display: none;
    }

    .course-badge {
      flex: 0 0 auto;
      display: inline-flex;
      align-items: center;
      height: 30px;
      padding: 0 8px;
      border: 1px solid #cdeeea;
      border-radius: 8px;
      background: var(--accent-soft);
      color: #0b4d47;
      font-size: 0.8rem;
      font-weight: 600;
      white-space: nowrap;
    }

    /* Suche. */
    .search-head {
      gap: 8px;
    }

    .search-input {
      flex: 1 1 auto;
      min-width: 0;
      padding: 8px 10px;
      border: 1px solid var(--line);
      border-radius: 8px;
      font-size: 0.95rem;
      font-family: inherit;
      color: var(--text);
      background: #fff;
    }

    .search-input:focus {
      outline: none;
      border-color: var(--accent);
      box-shadow: 0 0 0 3px var(--accent-soft);
    }

    .search-hit .bm-chap {
      font-family: Consolas, "Courier New", monospace;
      font-size: 0.72rem;
    }

    .search-kw {
      display: inline-block;
      margin-top: 2px;
      font-size: 0.72rem;
      color: var(--accent);
    }

    .section-link:hover {
      background: var(--accent-soft);
      border-color: #bce8e4;
    }

    /* ---- Gesperrter Abschnitt: Lizenz fehlt ----------------------------
       Sichtbar bleiben, nicht verschwinden: Ein fehlender Eintrag sieht aus
       wie ein Fehler; ein Eintrag mit Schloss sagt "das gibt es, aber nicht
       mit dieser Lizenz" - und dass es mehr gibt, ist genau die Auskunft, die
       eine freie Stufe geben soll.
       ⚠ NICHT AUSGRAUEN BIS ZUR UNLESBARKEIT. Der Titel muss lesbar bleiben,
         sonst kann niemand entscheiden, ob sich das Freischalten lohnt. */
    .section-link--gesperrt {
      color: var(--muted);
      cursor: not-allowed;
    }
    .section-link--gesperrt:hover {
      background: transparent;
      border-color: transparent;
    }
    /* Ohne Lizenz: freie Abschnitte leicht gruen, gesperrte leicht rot (Schriftfarbe, nicht Hintergrund). */
    .menu--ohne-lizenz .section-link:not(.section-link--gesperrt) { color: #2f8f5b; }
    .menu--ohne-lizenz .section-link--gesperrt { color: #c9605e; }
    .menu--ohne-lizenz .section-link:not(.section-link--gesperrt).active { color: #1f6f45; }
    .sec-schloss {
      flex: 0 0 auto;
      font-size: 0.82rem;
      line-height: 1;
      opacity: .75;
      margin-left: 2px;
      user-select: none;
    }
    .sec-schloss[hidden] { display: none; }
    /* Die Flagge zum Bookmarken bleibt sichtbar - man darf sich auch vormerken,
       was man noch nicht sehen darf. */

    /* Abschnitt ohne hinterlegte Datei: sichtbar, aber erkennbar unfertig. */
    .section-link--todo {
      color: var(--muted);
      font-style: italic;
    }

    .section-link--todo::after {
      content: "in Arbeit";
      float: right;
      font-style: normal;
      font-size: 0.72rem;
      color: #92700a;
      background: #fef7e0;
      border: 1px solid #f5e0a3;
      border-radius: 999px;
      padding: 1px 7px;
    }

    .section-link.active {
      border-color: var(--chap-color, var(--accent));
      background: var(--accent-soft);
      color: #0b4d47;
      box-shadow: inset 3px 0 0 0 var(--chap-color, var(--accent));
    }

    /* Farbliche Kapitel-Kennzeichnung: Punkt vor dem Kapitel + Akzente in Kapitelfarbe.
       Farbe kommt aus --chap-color (je <details> gesetzt): app-cfg > XML-Attribut farbe > Default. */
    .chap-dot {
      display: inline-block;
      flex: none;
      width: 11px;
      height: 11px;
      border-radius: 50%;
      margin-right: 9px;
      vertical-align: middle;
      background: var(--chap-color, #1e6fd0);
      box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.06);
    }

    summary {
      border-left: 4px solid var(--chap-color, transparent);
    }

    .section-list {
      /* Gleiche Breite + kein Einzug wie beim summary-Strich -> durchgehend buendig. */
      border-left: 4px solid var(--chap-color, transparent);
      margin-left: 0;
    }

    /* Farb-Legende (Modal ueber den 🎨-Button): Bereich -> Farbe. */
    .legend-list {
      display: grid;
      gap: 9px;
    }

    .legend-row {
      display: flex;
      align-items: center;
      gap: 11px;
    }

    .legend-swatch {
      flex: none;
      width: 16px;
      height: 16px;
      border-radius: 4px;
      box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
    }

    .legend-name {
      font-size: 0.95rem;
    }

    .legend-head {
      font-size: 0.72rem;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      color: var(--muted);
      margin-top: 4px;
    }

    .legend-head:first-child {
      margin-top: 0;
    }

    /* Filter-Pulldown: sitzt in der Sidebar oben ueber den Kapiteln. */
    .menu-filter {
      display: grid;
      gap: 5px;
      margin: 0 0 12px;
    }

    .menu-filter-label {
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .filter-select {
      font: inherit;
      font-size: 0.9rem;
      padding: 7px 9px;
      width: 100%;
      border: 1px solid var(--line, #d0d7de);
      border-radius: 8px;
      background: #fff;
      color: var(--text);
      cursor: pointer;
    }

    /* Kleines Stufen-Label (z. B. "FB2") im Abschnitt, vor dem Bookmark-Symbol.
       Einheitlich dunkelblau fuer alle. */
    .fb-badge {
      flex: none;
      font-size: 0.6rem;
      font-weight: 700;
      line-height: 1;
      padding: 2px 5px;
      border: 1px solid currentColor;
      border-radius: 999px;
      color: #1e40af;   /* Dunkelblau, fuer alle gleich */
      letter-spacing: 0.02em;
      white-space: nowrap;
    }

    .content {
      padding: 18px;
    }

    .viewer-wrap {
      position: relative;
      /* Spalte statt fester Rechnung: Der Kopf nimmt sich, was er braucht, der
         Rahmen darunter bekommt den Rest. Das ist der Kern der Korrektur -
         siehe die iframe-Regel weiter unten. */
      display: flex;
      flex-direction: column;
      height: calc(100vh - 36px);
      height: calc(100dvh - 36px);
      background: var(--panel);
      border: 1px solid var(--line);
      border-radius: 14px;
      overflow: hidden;
      box-shadow: 0 12px 30px rgba(16, 24, 40, 0.08);
    }

    /* Anmelde-Overlay: erscheint, wenn im iframe eine geschuetzte/Login-Seite liegt. */
    .auth-overlay[hidden] { display: none; }

    .auth-overlay {
      position: absolute;
      inset: 0;
      z-index: 10;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
      background: rgba(243, 246, 251, 0.92);
      backdrop-filter: blur(2px);
    }

    /* Login-Card im Stil des Skipper360-Dashboards (crm.css). */
    .auth-card {
      width: 100%;
      max-width: 380px;
      background: #fff;
      border-radius: 14px;
      overflow: hidden;
      box-shadow: 0 18px 48px rgba(16, 24, 40, 0.28);
    }

    .auth-card-head {
      background: #2176c1;
      color: #fff;
      font-size: 18px;
      font-weight: 600;
      padding: 18px 22px;
    }

    .auth-card-inner { padding: 22px; }

    .auth-msg {
      margin: 0 0 14px;
      font-size: 13px;
      color: #50575e;
      line-height: 1.45;
    }

    .auth-msg:empty { display: none; }

    .auth-fld { display: block; margin-bottom: 14px; font-size: 13px; color: #50575e; }
    .auth-fld span { display: block; margin-bottom: 5px; }

    .auth-fld input {
      width: 100%;
      padding: 10px 12px;
      border: 1px solid #c3c7cb;
      border-radius: 8px;
      font-size: 14px;
      font-family: inherit;
    }

    .auth-fld input:focus {
      outline: none;
      border-color: #2176c1;
      box-shadow: 0 0 0 3px rgba(33, 118, 193, 0.15);
    }

    .auth-check {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 13px;
      color: #50575e;
      margin-bottom: 16px;
    }

    .auth-submit {
      width: 100%;
      padding: 11px 14px;
      background: #2176c1;
      color: #fff;
      border: none;
      border-radius: 8px;
      font-size: 15px;
      font-weight: 600;
      cursor: pointer;
    }

    .auth-submit:hover { background: #1b5e9b; }

    .auth-reset {
      display: inline-block;
      margin-top: 14px;
      color: #2176c1;
      font-size: 13px;
      text-decoration: none;
    }

    .auth-reset:hover { text-decoration: underline; }

    .auth-form[hidden], .auth-reset[hidden] { display: none; }

    .viewer-head {
      position: relative;
      z-index: 11;
      flex: 0 0 auto;      /* darf wachsen, wenn die Zeile umbricht */
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 10px;
      border-bottom: 1px solid var(--line);
      padding: 10px 14px;
      background: linear-gradient(90deg, #eef6ff, #f6fffc);
      font-size: 0.92rem;
    }

    .viewer-nav {
      flex: 0 0 auto;
      display: flex;
      gap: 6px;
    }

    /* ⚠ MITTIG UEBER FLEX, nicht ueber die Zeilenhoehe. Ein Knopf zentriert
       seinen Text zwar waagrecht von selbst, senkrecht aber nur so gut, wie es
       die Schrift zulaesst: Bei einem Zeichen, dessen Tinte hoch ueber der
       Grundlinie sitzt (⇤, ⇥), sass das Bild sichtbar zu hoch, waehrend die
       Emoji daneben passten. Gemeldet als "der Pfeil ist nicht mittig". */
    .nav-btn {
      width: 30px;
      height: 30px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      border: 1px solid var(--line);
      border-radius: 8px;
      background: #ffffff;
      color: var(--accent);
      font-size: 1.1rem;
      line-height: 1;
      cursor: pointer;
    }
    /* Ein SVG im Knopf nimmt die Textfarbe an und bleibt in jeder Schrift
       gleich gross - anders als ein Sonderzeichen. */
    .nav-btn svg { display: block; }

    .nav-btn:hover:not(:disabled) {
      background: var(--accent-soft);
      border-color: #bce8e4;
    }

    .nav-btn:disabled {
      color: #c7ced9;
      cursor: default;
    }

    /* Zoom-Steuerung (A- % A+) in der Icon-Leiste. */
    .zoom-ctrl {
      flex: 0 0 auto;
      display: inline-flex;
      align-items: center;
      gap: 3px;
    }

    .zoom-btn {
      font-size: 0.9rem;
      font-weight: 700;
    }

    .zoom-label {
      min-width: 44px;
      padding: 4px 4px;
      border: 0;
      background: transparent;
      color: var(--text);
      font-size: 0.8rem;
      font-weight: 700;
      font-variant-numeric: tabular-nums;
      text-align: center;
      cursor: pointer;
      border-radius: 6px;
    }

    .zoom-label:hover {
      background: var(--accent-soft);
    }

    .viewer-title {
      flex: 1 1 auto;
      min-width: 0;
      display: flex;
      align-items: baseline;
      gap: 6px;
      white-space: nowrap;
      overflow: hidden;
    }

    .crumb-chap {
      flex: 0 1 auto;
      min-width: 0;
      color: var(--muted);
      font-weight: 500;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .crumb-sep {
      flex: 0 0 auto;
      color: var(--muted);
    }

    .crumb-sec {
      flex: 1 1 auto;
      min-width: 0;
      font-weight: 600;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .viewer-file {
      flex: 0 1 auto;
      min-width: 0;
      color: var(--muted);
      font-family: Consolas, "Courier New", monospace;
      font-size: 0.82rem;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    iframe {
      border: 0;
      width: 100%;
      /* ⚠ Hier stand height: calc(100% - 44px) - 44 px war die angenommene Hoehe
         der Kopfzeile. Am Telefon hochkant bricht sie aber in ZWEI Reihen um und
         ist dann rund 80 px hoch; der Rahmen ragte um die Differenz nach unten
         hinaus und wurde von overflow:hidden abgeschnitten. Eine Zahl, die eine
         andere Zahl raten muss, geht frueher oder spaeter schief.
         Jetzt teilt der Flex-Kasten den Platz auf: Kopf zuerst, Rest hierher.
         min-height: 0 ist dabei Pflicht - ein Flex-Element darf sonst nicht
         unter seine Inhaltsgroesse schrumpfen und ragt weiter hinaus. */
      flex: 1 1 auto;
      min-height: 0;
      height: auto;
      background: #fff;
    }

    /* Vollmenue (feste Spalte links): gilt, solange der body NICHT .kompakt
       traegt. Frueher hing das an einer Media-Query allein - eine Media-Query
       kann man aber nicht abwaehlen. Jetzt setzt menu-app.js die Klasse aus
       derselben Bedingung PLUS der Wahl des Nutzers (Knopf in der Icon-Leiste).
       Genau das ist der Trick am Umschalter. */
    body:not(.kompakt) .layout {
      height: 100vh;
      height: 100dvh;
      overflow: hidden;
    }

    body:not(.kompakt) .sidebar {
      min-height: 0;
    }

    /* Kompaktmodus: Hamburger + Overlay-Menue, Inhalt auf voller Flaeche.
       Ausgeloest von der Klasse .kompakt am body, die menu-app.js setzt: aus
       derselben Bedingung wie frueher (schmal ODER niedrig - BEWUSST ohne
       orientation-Filter, damit auch Landscape-Handys und fast quadratische
       Foldables den Hamburger bekommen) und vom Nutzer ueberstimmbar. */
    body.kompakt .layout {
      grid-template-columns: 1fr;
    }

    /* Hamburger sitzt in derselben Bar wie Pfeile + Breadcrumb;
       Schliessen-Button erscheint im Kopf des Overlay-Menues. */
    body.kompakt .menu-toggle,
    body.kompakt .menu-close {
      display: inline-flex;
    }

    body.kompakt .content {
      padding: 8px;
    }

    /* px-Anzeige (Scrollposition, reine bm-Justierhilfe) im Kompaktmodus
       ausblenden -> obere Leiste bleibt schlank. */
    body.kompakt .viewer-file {
      display: none;
    }

    body.kompakt .viewer-wrap {
      /* 16px = die Polsterung von .content oben und unten. Dazu der sichere
         Bereich am unteren Rand: Auf iPhones liegt dort die Streifen-Geste,
         auf Android teils die Navigationsleiste - ohne env() klebt die letzte
         Zeile darunter. Geraete ohne diesen Bereich melden 0px. */
      height: calc(100vh - 16px);
      height: calc(100dvh - 16px - env(safe-area-inset-bottom, 0px));
    }

    body.kompakt .sidebar {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1300;
      max-height: none;
      overflow-y: auto;
      border-right: 0;
      border-bottom: 0;
      border-top: 0;
      /* Eigene Hoehe + Offset (statt -110%): versteckt zuverlaessig auch bei
         niedrigen Viewports (Landscape-Handys), wo -110% einen Streifen der
         Menue-Unterkante oben stehen liess. */
      transform: translateY(calc(-100% - 56px));
      transition: transform 220ms ease;
      will-change: transform;
    }

    body.kompakt.menu-open .sidebar {
      transform: translateY(0);
    }

    body.kompakt .menu-backdrop {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      z-index: 1250;
      display: block;
      background: rgba(17, 24, 39, 0.25);
      opacity: 0;
      pointer-events: none;
      transition: opacity 220ms ease;
    }

    body.kompakt.menu-open .menu-backdrop {
      opacity: 1;
      pointer-events: auto;
    }

    body.kompakt.menu-open .content {
      display: none;
    }

    body.kompakt.menu-open {
      overflow: hidden;
    }

    /* Handy hochkant: Breadcrumb unter die Symbol-Reihe legen (eigene Zeile),
       damit die Symbole oben nicht gequetscht werden. */
    @media (max-width: 560px) {
      .viewer-head {
        flex-wrap: wrap;
        row-gap: 6px;
      }
      .viewer-title {
        order: 10;          /* rutscht hinter die Buttons */
        flex: 1 1 100%;     /* volle Breite -> eigene Zeile darunter */
      }
      /* Aktions-Icons (Suche, Farbe, Bookmarks, Lesezeichen setzen) rechtsbuendig;
         die Navigations-Icons (Menu, Start, Pfeile) bleiben links. Das auto-Margin
         am ersten Aktions-Icon schiebt die Gruppe nach rechts. */
      #searchOpen {
        margin-left: auto;
      }
    }

    /* =======================================================================
       Umschalter Vollmenue <-> Hamburger  (.menu-mode)
       -----------------------------------------------------------------------
       Der Knopf wird von menu-app.js gebaut und steht direkt neben dem
       Hamburger - dieselbe Stelle in beiden Modi, man muss also nicht erst
       das Menue oeffnen, um es wieder festzustecken.

       Sichtbar ist er NUR dort, wo das feste Menue ohnehin von selbst
       erscheint - also breit genug UND hoch genug. Anderswo waere er ein
       Knopf, der in eine Ansicht fuehrt, die dort gar nicht taugt: eine
       340px-Spalte liesse vom Inhalt nichts uebrig.
       menu-app.js prueft dieselbe Bedingung (wahlQuery) und laesst die
       gespeicherte Wahl nur dort gelten - sonst koennte man sich in einem
       Modus aussperren, aus dem der Knopf nicht mehr herausfuehrt.
       ======================================================================= */
    /* ⚠ KEIN font-size MEHR. Der Knopf trug 1rem und war damit KLEINER als
       seine Nachbarn (1.1rem) - zusammen mit dem zierlichen ⇤ wirkte er
       verloren. Sein Zeichen ist jetzt ein SVG mit fester Groesse. */
    .menu-mode {
      display: none;
    }

    @media (min-width: 901px) and (min-height: 601px) {
      .menu-mode {
        display: inline-flex;
      }
    }

    /* ---- Schmaler Schirm: das Banner wird ein STREIFEN ------------------
       Am Tablet liegt das Menue ueber die ganze Breite. Mit dem
       Seitenverhaeltnis des Bildes (4090:1529) waere das Banner dort fast
       300 px hoch - man sieht ein Foto und muss scrollen, um das erste
       Kapitel zu finden. Feste Hoehe plus object-fit:cover (steht schon am
       Bild) heisst: Das Bild fuellt den Streifen und wird beschnitten, statt
       ihn aufzublasen.
       ⚠ DIE BEDINGUNG IST DIESELBE WIE autoQuery in menu-app.js
         (max-width:900px, max-height:600px) - also genau die Lage, in der das
         Menue zum Overlay wird. Wer eine der beiden aendert, muss die andere
         mitziehen; das gilt in dieser Datei schon fuer .menu-mode darueber. */
    @media (max-width: 900px), (max-height: 600px) {
      .menu-banner {
        aspect-ratio: auto;
        height: 92px;
      }
      .menu-banner-text {
        padding: 7px 10px 0;
        font-size: clamp(0.95rem, 3.2vw, 1.25rem);
      }
    }

    /* Gedrueckter Zustand (Vollbild) faerbt wie ein aktiver Reiter. */
    .nav-btn[aria-pressed="true"] {
      background: var(--accent-soft);
      border-color: #bce8e4;
    }

    /* =======================================================================
       Quer und niedrig: Icon-Leiste als Spalte an der RECHTEN Kante
       -----------------------------------------------------------------------
       Handy im Landscape (und jedes kurze Fenster): die waagrechte Leiste
       kostet ~46px HOEHE - das ist bei 375px Schirmhoehe rund ein Achtel des
       Inhalts. Quergestellt kostet sie dieselben Pixel in der BREITE, und
       davon ist im Landscape reichlich da.

       Rechts und nicht links, aus zwei Gruenden: das Overlay-Menue faehrt von
       oben/links ein, und links laege die Leiste unter dem Daumen der Hand,
       die das Geraet haelt.

       Bewusst NICHT in das Kapitel-Menue verlegt: ‹ und › werden beim Lesen
       staendig gebraucht, im Menue kostete jeder Sprung zwei Tipper.

       Der Breadcrumb bleibt - senkrecht laufend unter den Symbolen. "Wo bin
       ich" ganz zu streichen waere der groessere Verlust.
       ======================================================================= */
    @media (max-height: 500px) and (min-width: 560px) {
      .content {
        padding: 0;
      }

      body.kompakt .viewer-wrap,
      .viewer-wrap {
        height: 100vh;
        height: 100dvh;
        border-radius: 0;
        border-width: 0;
        box-shadow: none;
      }

      /* Die Leiste LIEGT UEBER dem Inhalt, sie steht nicht daneben.
         -----------------------------------------------------------------
         Der Grund ist gemessen, nicht gestalterisch: Media-Queries in einem
         iframe messen den IFRAME, nicht das Geraet. Eine Leiste, die Breite
         wegnimmt, verschiebt also die Zahl, gegen die Elementor seine
         Breakpoints haelt. Bei 844px Geraetebreite blieben 770px - drei
         Pixel ueber Elementors Mobil-Breakpoint (767). Dieselbe Seite kippte
         dadurch je nach SCHIRMHOEHE von zwei Spalten auf eine, weil die
         Leiste ab 500px Hoehe erscheint.

         Ueberlagernd bleibt der iframe auf voller Breite - Elementor sieht
         844px, gleich wie breit die Leiste ist. Den Platz daneben schafft
         ein padding-right IM iframe (menu-app.js, iframeStil()): ein
         Innenabstand aendert die Viewport-Breite nicht, ein schmalerer
         Rahmen schon. Das ist der ganze Unterschied.

         ⚠ Bei FREMDEN Inhalten (externer Spiegel) laesst sich nichts
         injizieren - dort deckt die Leiste den rechten Rand ab. Dasselbe
         gilt schon fuer die WP-Adminbar-Regel daneben. */
      /* ZWEI Spalten, nicht eine.
         Nachgerechnet fuer ein 812x375-Handy: einspaltig brauchen die elf
         Symbole 372 der 375 verfuegbaren Pixel - fuer den Breadcrumb bliebe
         nichts, und die Leiste muesste scrollen. Zweispaltig sind es rund 200,
         der Rest gehoert der Beschriftung.

         display: contents bei .viewer-nav und .zoom-ctrl loest deren eigene
         Kaesten auf, sodass die einzelnen Knoepfe selbst zu Gitterfeldern
         werden. Ohne das laege die ganze Pfeilgruppe in EINEM Feld und waere
         breiter als die Spalte. */
      .viewer-head {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 74px;
        z-index: 11;
        box-shadow: -6px 0 14px rgba(16, 24, 40, 0.06);
        display: grid;
        grid-template-columns: repeat(2, 30px);
        gap: 6px;
        align-content: start;
        justify-content: center;
        padding: 8px 6px;
        border-bottom: 0;
        border-left: 1px solid var(--line);
        background: linear-gradient(180deg, #eef6ff, #f6fffc);
        overflow-y: auto;
        overflow-x: hidden;
      }

      .viewer-nav,
      .zoom-ctrl {
        display: contents;
      }

      /* A− und A+ nebeneinander, die Prozentzahl mittig darunter.
         Zwei Kniffe noetig, weil die drei durch display: contents einzelne
         Gitterfelder sind und die Zahl im HTML ZWISCHEN den Knoepfen steht:

         grid-column: 1 an A− beginnt zuverlaessig eine neue Zeile - die
         Auto-Platzierung rueckt eine Zeile weiter, wenn Spalte 1 schon
         belegt ist. Ohne das haengt die Paarung davon ab, ob die Zahl der
         Symbole davor gerade oder ungerade ist, und die aendert sich: der
         Vollbild-Knopf fehlt auf dem iPhone, der Umschalter unter 820px.

         order: 1 an der Zahl schiebt sie hinter A+, ohne das HTML zu drehen
         (Screenreader lesen weiter A− / Wert / A+). */
      .zoom-ctrl > .zoom-btn:first-child {
        grid-column: 1;
      }

      .zoom-label {
        order: 1;
        grid-column: 1 / -1;
        min-width: 0;
        width: 100%;
        text-align: center;
        font-size: 0.75rem;
      }

      /* Reihenfolge unten in der Leiste: A− A+ / 100 % / Lesezeichen.
         Die beiden Lesezeichen-Knoepfe ans Ende (order 2, also hinter die
         Prozentzahl mit order 1). Sie gehoeren zum Merken, nicht zum Lesen -
         was beim Blaettern staendig gebraucht wird, bleibt oben.
         Dass die zwei nebeneinander landen, besorgt die Prozentzahl von
         selbst: sie spannt ueber beide Spalten, danach beginnt eine frische
         Zeile. */
      #bmOpen,
      #bmSet {
        order: 2;
      }

      /* Kein Breadcrumb im Querformat.
         Versucht war er senkrecht unter den Symbolen. Am Bild nachgemessen
         blieben dafuer ~71px Resthoehe - daraus wurde "Die Log...", und ein
         gekuerzter Breadcrumb ist schlechter als gar keiner. Wo man ist,
         steht ohnehin in der Ueberschrift des Abschnitts und im Menue am
         hervorgehobenen Eintrag. */
      .viewer-title {
        display: none;
      }

      .viewer-file,
      .course-badge {
        display: none;
      }

      /* Volle Breite - genau darum geht es. Die Leiste liegt darueber. */
      iframe {
        width: 100%;
        height: 100%;
      }
    }

    /* =======================================================================
       Breadcrumb in die zweite Zeile, wenn die Leiste eng wird
       -----------------------------------------------------------------------
       Bisher hing das an der FENSTERbreite (max-width: 560px). Das trifft den
       Fall nicht: Auf einem iPad hochkant ist das Fenster 1024 breit, die
       Leiste aber nur rund 650 - das feste Menue nimmt 340 weg. Die Symbole
       drueckten den Breadcrumb dort zusammen, obwohl oben Platz ist.

       Gemessen wird deshalb der KASTEN, nicht das Fenster: .viewer-wrap wird
       zum Container, und die Regel greift, wenn er schmaler als 700px ist.
       Das passt sich von selbst an - klappt man das Menue ein, wird die
       Leiste breit und der Breadcrumb rueckt wieder in dieselbe Zeile.
       ======================================================================= */
    .viewer-wrap {
      container-type: inline-size;
    }

    @container (max-width: 700px) {
      .viewer-head {
        flex-wrap: wrap;
        row-gap: 6px;
      }
      /* Hinter die Knoepfe, ueber die volle Breite -> eigene Zeile darunter. */
      .viewer-title {
        order: 10;
        flex: 1 1 100%;
      }
      /* Die Aktions-Symbole rechtsbuendig; Menue, Start und Pfeile bleiben
         links. Dasselbe Prinzip wie im 560px-Block. */
      #searchOpen {
        margin-left: auto;
      }
    }
