/* ---------------------------------------------------------------------------
   Kursplan — glas.css
   Die Glasflaechen.

   Bedienflaechen liegen als Glasscheiben ueber dem Inhalt, lassen den
   Hintergrund durchscheinen und verwaschen ihn. Die Tiefe entsteht durch
   Unschaerfe, Saettigung und feine Lichtkanten — nicht durch Schlagschatten.

   Sparsam einsetzen: Glas ist fuer schwebende Ebenen. Tab-Leiste, Kopfleiste,
   Sheets, Dialoge, Toasts und die Kacheln im Stundenplan. Fliesstextabschnitte
   bleiben schlicht.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   1. Das Kernrezept
   --------------------------------------------------------------------------- */

.glas {
  background: var(--glas-fuellung);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid var(--glas-rand);
  border-radius: var(--radius-l);
  /* Oben innen eine helle Lichtkante, darunter ein weicher, weiter, schwacher
     Schatten. Kein harter grauer Kartenschatten. */
  box-shadow: 0 1px 0 0 var(--glas-glanz) inset,
              0 8px 24px -12px var(--glas-schatten);
}

/* Kraeftiger fuer grosse schwebende Flaechen wie Sheets. */
.glas--stark {
  backdrop-filter: blur(36px) saturate(180%);
  -webkit-backdrop-filter: blur(36px) saturate(180%);
  box-shadow: 0 1px 0 0 var(--glas-glanz) inset,
              0 -12px 48px -16px var(--glas-schatten);
}

/* Ohne Unschaerfe muss die App genauso benutzbar aussehen: dann eine deckende
   Fuellung statt der durchscheinenden. */
@supports not (backdrop-filter: blur(1px)) {
  .glas,
  .glas--stark {
    background: var(--glas-fuellung-deckend);
  }
}

/* ---------------------------------------------------------------------------
   2. Kopfleiste

   Grosser Titel, der beim Scrollen zu einer kompakten, verwaschenen Leiste
   zusammenschrumpft. Die Leiste klebt oben und ist zunaechst unsichtbar.
   --------------------------------------------------------------------------- */

.kopfleiste {
  position: sticky;
  top: 0;
  z-index: 30;
  padding-top: env(safe-area-inset-top);
  /* Ohne Glas und ohne Rand, solange oben nichts weggescrollt ist. */
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transition: background var(--dauer-mittel) var(--kurve),
              box-shadow var(--dauer-mittel) var(--kurve);
}

.kopfleiste__innen {
  display: flex;
  align-items: center;
  gap: var(--abstand-3);
  min-height: 52px;
}

.kopfleiste__titel {
  flex: 1;
  min-width: 0;
  font-size: var(--schrift-m);
  font-weight: 600;
  text-align: center;
  /* Erscheint erst, wenn der grosse Titel weggescrollt ist. */
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--dauer-mittel) var(--kurve),
              transform var(--dauer-mittel) var(--kurve);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kopfleiste__aktionen {
  display: flex;
  gap: var(--abstand-2);
  margin-left: auto;
}

/* Zusammengeschrumpft: verwaschene Leiste, Titel sichtbar. */
.kopfleiste--kompakt {
  background: var(--glas-fuellung);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  box-shadow: 0 1px 0 0 var(--glas-glanz) inset,
              0 1px 0 0 var(--glas-rand);
}

.kopfleiste--kompakt .kopfleiste__titel {
  opacity: 1;
  transform: none;
}

@supports not (backdrop-filter: blur(1px)) {
  .kopfleiste--kompakt {
    background: var(--glas-fuellung-deckend);
  }
}

/* ---------------------------------------------------------------------------
   3. Tab-Leiste

   Unten schwebend, aus Glas. Ab 768 px an der linken Seite.
   --------------------------------------------------------------------------- */

.tableiste {
  position: fixed;
  z-index: 40;
  left: max(var(--abstand-3), env(safe-area-inset-left));
  right: max(var(--abstand-3), env(safe-area-inset-right));
  bottom: calc(var(--abstand-3) + env(safe-area-inset-bottom));
  display: flex;
  gap: var(--abstand-1);
  padding: var(--abstand-1);
  border-radius: var(--radius-xl);
}

.tableiste__ziel {
  flex: 1;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 2px;
  min-height: var(--treffer);
  padding: var(--abstand-1);
  border-radius: calc(var(--radius-xl) - var(--abstand-1));
  color: var(--text-leise);
  text-decoration: none;
  transition: color var(--dauer-schnell) var(--kurve),
              background var(--dauer-schnell) var(--kurve);
}

.tableiste__name {
  font-size: var(--schrift-xs);
  font-weight: 600;
}

/* Aktives Ziel farbig eingefaerbt. */
.tableiste__ziel--aktiv {
  color: var(--akzent);
  background: color-mix(in srgb, var(--akzent) 12%, transparent);
}

@media (min-width: 768px) {
  .tableiste {
    left: max(var(--abstand-3), env(safe-area-inset-left));
    right: auto;
    top: var(--abstand-3);
    bottom: var(--abstand-3);
    width: calc(var(--leiste) - var(--abstand-6));
    flex-direction: column;
    justify-content: flex-start;
    padding: var(--abstand-2);
    border-radius: var(--radius-l);
  }

  .tableiste__ziel {
    flex: none;
    grid-template-columns: auto 1fr;
    justify-items: start;
    align-items: center;
    gap: var(--abstand-3);
    padding: var(--abstand-3);
    border-radius: var(--radius-m);
  }

  .tableiste__name {
    font-size: var(--schrift-s);
  }
}

/* ---------------------------------------------------------------------------
   4. Sheets und Dialoge

   Ein Sheet faehrt von unten hoch und laesst sich nach unten wegziehen. Auf
   breiten Bildschirmen wird daraus ein zentrierter Dialog.
   --------------------------------------------------------------------------- */

.dialog {
  padding: 0;
  border: 1px solid var(--glas-rand);
  color: var(--text);
  max-height: 90dvh;
  overflow: visible;
}

.dialog::backdrop {
  /* Abgedunkelt und leicht verwaschen. */
  background: var(--glas-schleier);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}

.dialog__innen {
  padding: var(--abstand-5);
  overflow-y: auto;
  max-height: inherit;
  overscroll-behavior: contain;
}

.dialog h2 {
  margin-bottom: var(--abstand-4);
}

.dialog ul {
  margin-bottom: var(--abstand-4);
}

.dialog li {
  margin-bottom: var(--abstand-2);
  font-size: var(--schrift-s);
}

.dialog__knoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--abstand-3);
  justify-content: flex-end;
  margin-top: var(--abstand-5);
}

/* Der Griff, an dem man das Sheet nach unten wegzieht. */
.dialog__griff {
  display: none;
  padding: var(--abstand-3) 0 var(--abstand-1);
  cursor: grab;
  touch-action: none;
}

.dialog__griff::before {
  content: "";
  display: block;
  width: 36px;
  height: 5px;
  margin: 0 auto;
  border-radius: 999px;
  background: var(--rand-stark);
  opacity: .7;
}

/* --- Bestaetigungsdialog: immer zentriert -------------------------------- */

.dialog:not(.dialog--sheet) {
  width: min(30em, calc(100vw - 2 * var(--abstand-4)));
  border-radius: var(--radius-l);
}

/* --- Sheet: schmal von unten, breit zentriert ---------------------------- */

@media (max-width: 767px) {
  .dialog--sheet {
    width: 100%;
    max-width: none;
    margin: auto 0 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    border-bottom: none;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .dialog--sheet .dialog__griff {
    display: block;
  }

  .dialog--sheet .dialog__innen {
    padding-top: var(--abstand-2);
  }

  /* Faehrt in 320 ms hoch. */
  .dialog--sheet[open] {
    animation: sheet-hoch var(--dauer-sheet) var(--kurve);
  }

  .dialog--sheet[open]::backdrop {
    animation: schleier-auf var(--dauer-sheet) var(--kurve);
  }

  /* Beim Schliessen wieder nach unten. */
  .dialog--sheet.dialog--faehrt-runter {
    animation: sheet-runter var(--dauer-mittel) var(--kurve) forwards;
  }
}

@media (min-width: 768px) {
  .dialog--sheet {
    width: min(34em, calc(100vw - 2 * var(--abstand-6)));
    border-radius: var(--radius-l);
  }

  .dialog--sheet[open] {
    animation: dialog-auf var(--dauer-mittel) var(--kurve);
  }
}

@keyframes sheet-hoch {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

@keyframes sheet-runter {
  from { transform: translateY(var(--zug, 0px)); }
  to   { transform: translateY(100%); }
}

@keyframes schleier-auf {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes dialog-auf {
  from { opacity: 0; transform: scale(.97); }
  to   { opacity: 1; transform: none; }
}

/* Waehrend des Ziehens folgt das Sheet dem Finger, ohne Uebergang. */
.dialog--zieht {
  transition: none;
  animation: none;
}

/* ---------------------------------------------------------------------------
   5. Toasts

   Kurze Rueckmeldung ueber der Tab-Leiste.
   --------------------------------------------------------------------------- */

.toastbereich {
  position: fixed;
  z-index: 50;
  left: max(var(--abstand-3), env(safe-area-inset-left));
  right: max(var(--abstand-3), env(safe-area-inset-right));
  bottom: calc(var(--abstand-3) + 76px + env(safe-area-inset-bottom));
  display: grid;
  gap: var(--abstand-2);
  justify-items: center;
  pointer-events: none;
}

.toast {
  max-width: 32em;
  padding: var(--abstand-3) var(--abstand-5);
  border-radius: var(--radius-l);
  font-size: var(--schrift-s);
  animation: toast-auf var(--dauer-mittel) var(--kurve);
}

.toast--fehler {
  color: var(--fehler);
  font-weight: 600;
}

.toast--geht {
  animation: toast-zu var(--dauer-mittel) var(--kurve) forwards;
}

@keyframes toast-auf {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

@keyframes toast-zu {
  from { opacity: 1; }
  to   { opacity: 0; transform: translateY(4px); }
}

@media (min-width: 768px) {
  .toastbereich {
    left: calc(var(--leiste) + var(--abstand-3));
    bottom: var(--abstand-6);
  }
}

/* ---------------------------------------------------------------------------
   6. Offline-Balken

   Dezent, ueber der Tab-Leiste. Er sagt, dass man liest statt zu arbeiten, und
   von wann der Stand ist.
   --------------------------------------------------------------------------- */

.offlinebalken {
  position: fixed;
  z-index: 45;
  left: max(var(--abstand-3), env(safe-area-inset-left));
  right: max(var(--abstand-3), env(safe-area-inset-right));
  bottom: calc(var(--abstand-3) + 76px + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--abstand-2);
  padding: var(--abstand-2) var(--abstand-4);
  border-radius: var(--radius-l);
  color: var(--text-leise);
  font-size: var(--schrift-s);
  animation: toast-auf var(--dauer-mittel) var(--kurve);
}

.offlinebalken__punkt {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-leise);
}

@media (min-width: 768px) {
  .offlinebalken {
    left: calc(var(--leiste) + var(--abstand-3));
    bottom: var(--abstand-6);
  }
}

/* Was nicht geht, sieht auch nicht so aus, als ginge es. */
.ist-offline [data-schreibt] {
  opacity: .45;
}

/* ---------------------------------------------------------------------------
   7. Installhinweis fuer iOS

   Schmal, unten, wegtippbar. Erscheint nur in Safari auf iOS ausserhalb des
   Standalone-Modus.
   --------------------------------------------------------------------------- */

.installhinweis {
  position: fixed;
  z-index: 46;
  left: max(var(--abstand-3), env(safe-area-inset-left));
  right: max(var(--abstand-3), env(safe-area-inset-right));
  bottom: calc(var(--abstand-3) + 76px + env(safe-area-inset-bottom));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--abstand-3);
  padding: var(--abstand-3) var(--abstand-4);
  border-radius: var(--radius-l);
  animation: toast-auf var(--dauer-mittel) var(--kurve);
}

.installhinweis__text {
  flex: 1 1 14em;
  font-size: var(--schrift-s);
  color: var(--text-leise);
}

.installhinweis__weg {
  flex: none;
}
