@charset "UTF-8";
/* ==========================================================================
   froodnotes — Die Rohrpost
   Eine Anlage aus drei Teilen: der Einwurf unten, der Schacht rechts,
   der Strom dazwischen. Nichts blendet ein oder aus; es schnappt, rastet
   und fährt. Bewegung ist mechanisch, weil eine Rohrpost mechanisch ist.
   ========================================================================== */

/* ---------- Schrift ---------- */

@font-face {
  font-family: "Delight";
  src: url("fonts/Delight-Regular.woff2") format("woff2"),
       url("fonts/Delight-Regular.woff") format("woff");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Delight";
  src: url("fonts/Delight-Bold.woff2") format("woff2"),
       url("fonts/Delight-Bold.woff") format("woff");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Delight";
  src: url("fonts/Delight-Black.woff2") format("woff2"),
       url("fonts/Delight-Black.woff") format("woff");
  font-weight: 900; font-style: normal; font-display: swap;
}

/* ---------- Die Welt ---------- */

:root {
  /* froodmat, bestätigt aus froodmat-leistungen.html */
  --rot:        #F40000;   /* Feldrot: Schacht, Klappe, Kapselnase, Punkte */
  --rot-wand:   #F40000;   /* Die Schachtwand — nachts gedämpft, damit die Kante führt */
  --rot-schrift:#C40000;   /* Rot, das Schrift trägt oder Schrift ist (4.9:1+) */
  --rot-tief:   #B00A0A;
  --creme:      #FEDEB5;
  --papier:     #FFF6E7;
  --tinte:      #1C1109;
  --tinte-weich:#7A6549;

  /* Abgeleitete Rollen */
  --grund:      var(--creme);
  --flaeche:    var(--papier);
  --schrift:    var(--tinte);
  /* Eine Spur dunkler als --tinte-weich: auf Creme trägt der Markenwert
     kleine Schrift nicht (4.3:1). */
  --gedimmt:    #6E5A40;
  --kante:      var(--tinte);
  --linie:      rgba(28, 17, 9, .16);
  --senke:      rgba(28, 17, 9, .06);
  --auf-rot:    var(--creme);

  /* Maße */
  --schacht-b:  104px;
  --rand:       28px;
  --rundung:    20px;
  --kante-st:   2px;

  /* Bewegung — mechanisch: Anschlag statt Ausklang */
  --schnapp:    90ms cubic-bezier(.2, 0, 0, 1);
  --rast:       160ms cubic-bezier(.2, .9, .1, 1);
  --abfahrt:    380ms cubic-bezier(.5, 0, .95, .3);

  color-scheme: light;
}

/* Nachts im Bett ist dieselbe Anlage, nur ohne Ladenbeleuchtung. */
@media (prefers-color-scheme: dark) {
  :root {
    --grund:      #140C06;
    --flaeche:    #221609;
    --schrift:    #FBEBD4;
    --gedimmt:    #A98F6E;
    /* Im Dunkeln trägt das Signalrot Schrift bereits (4.1:1 gross, 8:1 als Fläche). */
    --rot-schrift:#F40000;
    /* Die 2px-Kante ist der Bau der Welt und muss auch nachts tragen:
       #4A3418 kam auf 1,7:1 gegen den Grund — die Kapseln lösten sich auf. */
    --kante:      #8A6A38;
    /* Und die Schachtwand darf die Kante nicht überstrahlen: gedämpftes Rot,
       auf dem die Creme-Beschriftung zugleich erst lesbar wird (6:1). */
    --rot-wand:   #A80505;
    --linie:      rgba(251, 235, 212, .18);
    --senke:      rgba(251, 235, 212, .07);
    --auf-rot:    #FFF6E7;
    color-scheme: dark;
  }
}

/* ---------- Boden ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--grund);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--grund);
  color: var(--schrift);
  font-family: "Delight", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

/* Die Flächen, die der Browser stellt, gehören auch zur Gestaltung. */
::selection { background: var(--rot-schrift); color: #fff; }
:focus-visible {
  outline: 3px solid var(--rot);
  outline-offset: 2px;
  border-radius: 4px;
}
.strom { scrollbar-width: thin; scrollbar-color: var(--rot) transparent; }
.strom::-webkit-scrollbar { width: 10px; }
.strom::-webkit-scrollbar-track { background: transparent; }
.strom::-webkit-scrollbar-thumb {
  background: var(--rot);
  border: 3px solid var(--grund);
  border-radius: 99px;
}

button { font: inherit; color: inherit; }

.visuell-versteckt {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

.sprung {
  position: fixed; top: 0; left: 0; z-index: 100;
  transform: translateY(-110%);
  background: var(--rot-schrift); color: #fff;
  font-weight: 900; padding: 12px 20px;
  text-decoration: none;
}
.sprung:focus { transform: none; }

/* ==========================================================================
   Die Anlage
   ========================================================================== */

.anlage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--schacht-b);
  grid-template-rows: minmax(0, 1fr);
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* ---------- Der Schacht ---------- */

.schacht {
  grid-column: 2;
  position: relative;
  background: var(--rot-wand);
  border-left: var(--kante-st) solid var(--kante);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 12px 0 calc(12px + env(safe-area-inset-bottom));
  overflow: hidden;
}

/* Das Rohr: eine dunklere Bahn in der Mitte, in der die Kapsel fährt.
   Die Wölbung kommt aus dem Querverlauf, die Flansche aus dem Längsverlauf —
   ein Rohr ist nie eine glatte Fläche. */
.schacht-rohr {
  position: absolute;
  inset: 0 auto 0 50%;
  width: 46px;
  transform: translateX(-50%);
  background:
    /* Flanschringe alle 96px */
    repeating-linear-gradient(180deg,
      transparent 0 88px,
      rgba(0,0,0,.34) 88px 92px,
      rgba(255,255,255,.14) 92px 96px),
    /* Wölbung */
    linear-gradient(90deg,
      rgba(0,0,0,.34) 0, rgba(0,0,0,.08) 24%,
      rgba(255,255,255,.20) 46%, rgba(0,0,0,.12) 72%, rgba(0,0,0,.36) 100%);
  border-left: 1px solid rgba(0,0,0,.4);
  border-right: 1px solid rgba(0,0,0,.4);
}

/* Die Mündung unten: hier fährt die Kapsel ein. */
.schacht-rohr::after {
  content: "";
  position: absolute;
  left: -5px; right: -5px;
  bottom: 0;
  height: 34px;
  border-radius: 3px 3px 0 0;
  background: rgba(0,0,0,.5);
  box-shadow:
    inset 0 9px 12px -6px rgba(0,0,0,.95),
    0 -1px 0 rgba(255,255,255,.22);
}

/* Beschriftung längs des Schachts, wie auf einer echten Anlage. */
.schacht-schrift {
  position: absolute;
  top: 18px; left: 50%;
  transform: translateX(-50%);
  writing-mode: vertical-rl;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .34em;
  text-transform: uppercase;
  /* Sitzt auf der dunklen Rohrbahn, nicht auf der Signalrot-Wand. */
  color: rgba(254, 222, 181, .92);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .65);
  pointer-events: none;
  z-index: 2;
}

/* Druckaufbau beim Tippen: das Rohr füllt sich von unten. */
.schacht-druck {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(255,246,231,.55), rgba(255,246,231,.05));
  transform: scaleY(var(--druckf, 0));
  transform-origin: bottom;
  transition: transform 120ms linear;
  will-change: transform;
}

/* Die Druckwelle beim Abschicken. */
.schacht-welle {
  position: absolute;
  left: 0; right: 0;
  height: 120px;
  bottom: 0;
  background: linear-gradient(0deg, rgba(255,246,231,0), rgba(255,246,231,.85), rgba(255,246,231,0));
  opacity: 0;
  transform: translateY(100%);
  will-change: transform;
}
.faehrt .schacht-welle {
  /* Ohne zweite Kurve: `--abfahrt` bringt Dauer UND Kurve mit. Ein zusätzliches
     `linear` machte die Kurzschreibweise ungültig — die Druckwelle der Abfahrt
     hat deshalb nie stattgefunden, obwohl sie überall beschrieben stand. */
  animation: welle var(--abfahrt);
}
/* Nur Transform: `bottom` wäre bei jedem Absenden ein Layout-Durchlauf. */
@keyframes welle {
  0%   { transform: translateY(100%);  opacity: 1; }
  100% { transform: translateY(-100vh); opacity: 1; }
}

/* Die Tagesleiste — Registerkante: ein Reiter je Tag, Höhe nach Aufkommen. */
.tagesleiste {
  position: relative;
  list-style: none;
  margin: 0 0 44px; padding: 0 7px 0 0;
  display: flex;
  flex-direction: column-reverse;
  gap: 5px;
  z-index: 1;
}

.tagesleiste-tag {
  position: relative;
  height: 13px;
  display: flex;
  align-items: center;
}

.tagesleiste-balken {
  display: block;
  height: 6px;
  width: max(11px, var(--anteil));
  margin-left: auto;
  background: var(--creme);
  opacity: .62;
  border-radius: 3px 0 0 3px;
  box-shadow: 0 0 0 1px rgba(28,17,9,.3);
  transition: opacity var(--rast);
}

.tagesleiste-tag.ist-heute .tagesleiste-balken {
  opacity: 1;
  height: 9px;
  border-radius: 4px 0 0 4px;
  background: var(--creme);
  box-shadow: 0 0 0 2px rgba(28,17,9,.5);
}

.tagesleiste-tag:hover .tagesleiste-balken { opacity: 1; }

/* Ein Tag ohne Gedanken wird gezeichnet, nicht weggelassen — eine Lücke zu
   zeigen ist das Einzige, wofür eine Registerkante da ist. */
.tagesleiste-tag.ist-leer .tagesleiste-balken {
  width: 11px;
  height: 2px;
  opacity: .3;
  box-shadow: none;
}

.tagesleiste-text {
  position: absolute;
  right: calc(100% + 10px);
  white-space: nowrap;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--creme);
  background: var(--tinte);
  padding: 3px 8px;
  border-radius: 3px;
  opacity: 0;
  pointer-events: none;
  transform: translateX(4px);
  transition: opacity var(--schnapp), transform var(--schnapp);
}
.tagesleiste-tag:hover .tagesleiste-text,
.tagesleiste-tag:focus-within .tagesleiste-text {
  opacity: 1; transform: none;
}

/* ==========================================================================
   Die Station
   ========================================================================== */

.station {
  grid-column: 1;
  grid-row: 1;
  display: grid;
  /* Ohne diese Spalte wird die implizite `auto`-Spalte vom min-content des
     Kopfes gehalten (Logo + Titel + Stand + Ton = 341px). Unter 380px lief die
     Station dann über den Schacht hinaus und der Einwurf über den Bildrand. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  min-width: 0;
  min-height: 0;
  height: 100%;
}

/* ---------- Kopf ---------- */

.kopf {
  padding: 14px var(--rand);
  padding-top: calc(14px + env(safe-area-inset-top));
  border-bottom: var(--kante-st) solid var(--kante);
  background: var(--grund);
}

/* Der Kopf trägt seine Trennlinie über die volle Breite, sein Inhalt aber
   steht auf demselben Maß wie der Strom und der Einwurf. Sonst hängt der
   Ton-Schalter allein am Bildrand und bekommt die auffälligste Leerstelle
   der Seite, während die Stationsanzeige sich links drängt. */
.kopf-innen {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: 74ch;
  margin: 0 auto;
  width: 100%;
}

.marke { display: flex; align-items: center; gap: 12px; margin-right: auto; min-width: 0; }
.marke-zeichen { width: 30px; height: 30px; flex: 0 0 auto; display: block; }
.marke h1 {
  margin: 0 2px 0 0;
  font-size: 21px;
  font-weight: 900;
  letter-spacing: -.035em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Stationsanzeige: wie viele Kapseln noch unterwegs sind. */
.stand {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 12px 5px 8px;
  border: var(--kante-st) solid var(--kante);
  border-radius: 99px;
  background: var(--flaeche);
  white-space: nowrap;
}

.stand-zahl {
  font-size: 20px;
  font-weight: 900;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  min-width: 1.2ch;
  text-align: center;
  color: var(--rot-schrift);
}
/* Null heißt nicht „nichts zu sehen", sondern „alles ist da". Rot heißt
   unterwegs, Tinte heißt angekommen — also steht die Null in Tinte. */
.stand[data-leer="ja"] .stand-zahl { color: var(--schrift); }

.stand-text {
  font-size: 13px;
  font-weight: 700;
  color: var(--gedimmt);
}

.stand.schlaegt { animation: schlag var(--rast); }
@keyframes schlag {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.13); }
  100% { transform: scale(1); }
}

/* Ton-Schalter */
.ton {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px 7px 10px;
  border: var(--kante-st) solid var(--kante);
  border-radius: 99px;
  background: none;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  transition: background var(--schnapp), color var(--schnapp);
}
.ton svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ton .ton-korpus { fill: currentColor; stroke-linejoin: round; }
.ton .ton-wellen { display: none; }
.ton[aria-pressed="true"] { background: var(--rot-schrift); color: #fff; border-color: var(--rot-schrift); }
.ton[aria-pressed="true"] .ton-wellen { display: block; }
.ton[aria-pressed="true"] .ton-aus { display: none; }
.ton:hover { background: var(--senke); }
.ton[aria-pressed="true"]:hover { background: var(--rot-tief); }
.ton-text { display: none; }

/* ==========================================================================
   Der Strom
   ========================================================================== */

.strom {
  overflow-y: auto;
  overflow-x: hidden;
  padding: 20px var(--rand) 22px;
  scroll-padding-bottom: 24px;
}

.kapseln {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 74ch;
}

/* ---------- Die Kapsel ---------- */

.kapsel {
  position: relative;
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr) auto;
  align-items: stretch;
  background: var(--flaeche);
  border: var(--kante-st) solid var(--kante);
  border-radius: var(--rundung);
  overflow: hidden;
  transition: border-color var(--rast);
}

.kapsel:hover { border-color: var(--rot); }

/* Die Filzringe, die eine echte Kapsel in ihrem Rohr abdichten. */
.kapsel-ring {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 4px;
  background: repeating-linear-gradient(
    180deg, var(--kante) 0 3px, transparent 3px 6px);
  opacity: .5;
  pointer-events: none;
  z-index: 2;
}
.kapsel-ring-links  { left: 68px; }
.kapsel-ring-rechts { right: 40px; }

/* Nase: Uhrzeit, in Delight Black. */
.kapsel-kopf {
  position: relative;
  background: transparent;
  color: var(--auf-rot);
  border-right: var(--kante-st) solid var(--kante);
  padding: 11px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  text-align: center;
}

/* Das Rot der Nase liegt als eigene Schicht darunter, damit es bei der
   Ankunft nach oben auslaufen kann — in die Richtung, in die die Kapsel
   gefahren ist. Der Schriftzug bleibt dabei stehen. */
.kapsel-kopf::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--rot-schrift);
  transform-origin: top;
}
.kapsel-kopf > * { position: relative; z-index: 1; }

.kapsel-zeit {
  font-size: 17px;
  font-weight: 900;
  letter-spacing: -.045em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
/* Keine Deckkraft auf einen durchgerechneten Farbwert: sie rechnet ihn
   ein zweites Mal und schiebt 11px-Text unter 3:1. Der Rang kommt aus
   Größe und Schnitt, nicht aus Verblassen. */
.kapsel-tag {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: inherit;
  line-height: 1;
}

.kapsel-leib { padding: 11px 16px; min-width: 0; }

.kapsel-text {
  margin: 0;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  outline: none;
  border-radius: 4px;
}
/* Lesen und Schreiben sind zwei Zustände eines Objekts: kein Bearbeiten-Modus. */
.kapsel-text[contenteditable="true"] {
  box-shadow: inset 0 0 0 2px var(--rot);
  padding: 4px 6px;
  margin: -4px -6px;
  white-space: pre-wrap;
}

.k-tag  { color: var(--rot-schrift); font-weight: 700; }
.k-link { color: var(--rot-schrift); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1.5px; }

.kapsel-bild { margin-top: 9px; }
.kapsel-bild img {
  display: block;
  max-width: 100%;
  height: auto;
  max-height: 240px;
  width: auto;
  border: var(--kante-st) solid var(--kante);
  border-radius: 8px;
}

.kapsel-marken {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 9px;
}
.kapsel-marken:empty { display: none; }

.marke-tag, .marke-link, .marke-eigen {
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 99px;
  border: 1.5px solid var(--linie);
  color: var(--gedimmt);
  line-height: 1.5;
}
.marke-link::before { content: "[["; }
.marke-link::after  { content: "]]"; }
.marke-eigen {
  border-color: var(--rot-schrift);
  color: var(--rot-schrift);
}

/* Heck: Zustand und Verwerfen. */
.kapsel-fuss {
  border-left: var(--kante-st) solid var(--kante);
  padding: 11px 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 40px;
}

.kapsel-zustand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gedimmt);
  writing-mode: vertical-rl;
  white-space: nowrap;
}
.kapsel-zustand::before {
  content: "";
  flex: 0 0 auto;
  width: 11px; height: 11px;
  border-radius: 50%;
  border: 2px solid var(--rot);
  animation: unterwegs 1.6s steps(2, jump-none) infinite;
}
/* Der Puls schließt den Ring nie zur vollen Scheibe: die volle rote Scheibe
   gehört „hier". Auf dem Handy fällt die Beschriftung weg, dort trägt allein
   der Punkt — und zwei Stufen, die sich nur in der Phase einer Animation
   unterscheiden, sind im Standbild dieselbe Stufe. */
@keyframes unterwegs {
  0%, 100% { box-shadow: inset 0 0 0 0   var(--rot); }
  50%      { box-shadow: inset 0 0 0 2px var(--rot); }
}

/* ---------- Die drei Stufen des Weges ----------
   Der Punkt am Heck erzählt, wo der Gedanke wirklich liegt. Eine Stufe ist
   keine Stufe, wenn man sie nur an der Phase einer Animation erkennt — die
   drei Füllungen (voll rot · roter Ring · volle Tinte) halten deshalb auch im
   Standbild und mit abgeschalteter Bewegung auseinander.

   hier       — nur auf diesem Gerät, noch nicht beim Server. Voller Druck.
   unterwegs  — beim Server, wartet auf die Abholung.
   abgeholt   — im Vault. Rot heißt unterwegs, Tinte heißt angekommen. */
.kapsel.ist-hier .kapsel-zustand::before {
  animation: none;
  background: var(--rot);
  box-shadow: none;
}

/* Abgeholt heißt: die Kapsel liegt still. Die Form bleibt scharf, nur das
   Rot der Nase erlischt — Rot bedeutet in dieser Anlage „noch unterwegs". */
.kapsel.ist-abgeholt { background: transparent; }
.kapsel.ist-abgeholt .kapsel-kopf { color: var(--gedimmt); }
.kapsel.ist-abgeholt .kapsel-kopf::before { transform: scaleY(0); }
.kapsel.ist-abgeholt .kapsel-zeit { color: var(--schrift); }
.kapsel.ist-abgeholt .kapsel-ring { opacity: .22; }   /* Deckkraft auf einer Zeichnung, nicht auf einem Textwert — erlaubt. */
/* Rot heißt unterwegs, Tinte heißt angekommen. Die beiden Zustände dürfen sich
   nicht bloß in der Phase einer Animation unterscheiden — im Standbild, mit
   abgeschalteter Bewegung und im Ausdruck müssen sie verschieden aussehen. */
.kapsel.ist-abgeholt .kapsel-zustand::before {
  animation: none;
  background: var(--schrift);
  border-color: var(--schrift);
}
.kapsel.ist-abgeholt:hover { border-color: var(--rot); }

/* Ohne die Rückfrage verwirft der erste Druck sofort — die Rücknahme fängt den
   Fehlgriff auf, die Trefferfläche muss ihn seltener machen. Das gezeichnete
   Kreuz bleibt 15px, nur der Griff wächst auf Daumenmaß. */
.kapsel-weg {
  border: 0; background: none;
  display: grid;
  place-items: center;
  min-width: 44px; min-height: 44px;
  padding: 0; margin: -10px -7px;
  cursor: pointer;
  color: var(--gedimmt);
  opacity: 0;
  transition: opacity var(--schnapp), color var(--schnapp);
}
.kapsel-weg svg { display: block; width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.kapsel:hover .kapsel-weg, .kapsel-weg:focus-visible { opacity: 1; }
.kapsel-weg:hover { color: var(--rot-schrift); }

/* ---------- Verwerfen ----------
   Kein Stempel und kein Systemdialog: die Kapsel klappt sofort zu, und die
   Rücknahme steht sechs Sekunden lang im Melder. Die Rückfrage hatte den Text
   verdeckt, über den sie fragte — man sollte über ein Objekt entscheiden, das
   man nicht mehr sah. Undo ist für den Absichtsfall schneller und für den
   Fehlgriff sicherer; api.php löscht ohnehin nur weich. */

/* ==========================================================================
   Die Ankunft — das Gegenstück zur Abfahrt
   ==========================================================================
   Die Abfahrt hat einen Höhepunkt, die Ankunft hatte keinen: eine Kapsel stand
   auf „unterwegs", bis irgendwann ein Neuladen sie still auf „abgeholt" setzte.
   Der Moment, für den die ganze Anlage existiert, fand nicht statt. Jetzt fährt
   er sichtbar ab: das Rot läuft aus der Nase nach oben aus, der Punkt am Heck
   schlägt auf Tinte um, eine Welle läuft den Schacht herunter — die leere
   Kapsel, die zurückkommt — und der Stand zählt herunter. */

.kapsel.kommt-an .kapsel-kopf::before {
  animation: nase-leer var(--abfahrt) forwards;
}
/* Die Beschriftung wechselt mit der Fläche, auf der sie steht: creme gehört
   auf Rot, Tinte auf Papier. Ohne diesen Wechsel steht die Uhrzeit für einen
   Moment cremefarben auf der schon freigelegten Fläche. */
.kapsel.kommt-an .kapsel-kopf { animation: nase-schrift var(--abfahrt) forwards; }
@keyframes nase-schrift {
  0%, 88% { color: var(--auf-rot); }
  89%     { color: var(--gedimmt); }
  100%    { color: var(--gedimmt); }
}
.kapsel.kommt-an .kapsel-zeit { animation: nase-zeit var(--abfahrt) forwards; }
@keyframes nase-zeit {
  0%, 88% { color: var(--auf-rot); }
  89%     { color: var(--schrift); }
  100%    { color: var(--schrift); }
}
@keyframes nase-leer {
  0%   { transform: scaleY(1); }
  100% { transform: scaleY(0); }
}

/* Der Punkt schlägt erst um, wenn das Rot heraus ist — die Reihenfolge ist die
   Aussage: erst leer, dann angekommen. */
.kapsel.kommt-an .kapsel-zustand::before {
  animation: punkt-fuellt var(--abfahrt) forwards;
}
/* Der Umschlag liegt in den Keyframes, nicht in einer Schrittkurve: der Token
   trägt die Kurve, und ein zweiter Kurvenwert machte die Regel ungültig. */
@keyframes punkt-fuellt {
  0%, 96% { background: transparent;    border-color: var(--rot); }
  97%     { background: var(--schrift); border-color: var(--schrift); }
  100%    { background: var(--schrift); border-color: var(--schrift); }
}

/* Die Rückwelle: dieselbe Welle wie bei der Abfahrt, nur andersherum. */
.schacht-rueckwelle {
  position: absolute;
  left: 0; right: 0;
  height: 120px;
  top: 0;
  background: linear-gradient(180deg, rgba(255,246,231,0), rgba(255,246,231,.85), rgba(255,246,231,0));
  opacity: 0;
  transform: translateY(-100%);
  will-change: transform;
}
.kommt-an .schacht-rueckwelle {
  animation: rueckwelle var(--abfahrt);
}
@keyframes rueckwelle {
  0%   { opacity: 0; transform: translateY(-100%); }
  18%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(calc(100vh + 100%)); }
}

/* Der Anschlag bei null: die Anlage wird still. Kein neues Bauteil, sondern
   dieselbe Stationsanzeige — sie schlägt ein letztes Mal und geht auf Tinte. */
.stand.wird-still { animation: still-werden var(--abfahrt); }
@keyframes still-werden {
  0%   { transform: scale(1); }
  30%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* Ankunft im Strom: Anschlag, kein Einblenden. */
.kapsel.landet { animation: landung 220ms cubic-bezier(.16, 1, .3, 1); }
@keyframes landung {
  0%   { transform: translateY(-14px) scaleY(.88); }
  58%  { transform: translateY(0) scaleY(1.05); }
  76%  { transform: translateY(0) scaleY(.985); }
  100% { transform: none; }
}

/* Verwerfen: die Kapsel klappt zu. */
.kapsel.faellt {
  animation: fall 180ms cubic-bezier(.4, 0, 1, .5) forwards;
  transform-origin: top;
}
@keyframes fall {
  to { transform: scaleY(0); opacity: 0; margin-bottom: -12px; }
}

/* ---------- Leerlauf: Abwesenheit wird gezeichnet ---------- */

.leerlauf {
  max-width: 74ch;
  margin: 8vh auto 0;
  text-align: center;
}
.leerlauf[hidden] { display: none; }

.leerlauf-plaetze {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 26px;
}
.leerlauf-plaetze span {
  display: block;
  height: 62px;
  border: var(--kante-st) dashed var(--linie);
  border-radius: var(--rundung);
}
.leerlauf-plaetze span:nth-child(2) { opacity: .6; }
.leerlauf-plaetze span:nth-child(3) { opacity: .3; }

.leerlauf-text {
  margin: 0;
  color: var(--gedimmt);
  font-size: 16px;
  line-height: 1.6;
}

/* ==========================================================================
   Der Einwurf
   ========================================================================== */

.einwurf {
  position: relative;
  margin: 0 var(--rand) 0;
  border: var(--kante-st) solid var(--kante);
  border-bottom: 0;
  border-radius: var(--rundung) var(--rundung) 0 0;
  background: var(--flaeche);
  max-width: 74ch;
  width: calc(100% - var(--rand) * 2);
  justify-self: center;
}

/* Die Klappe: schnappt beim Einwerfen zu. */
.klappe {
  position: relative;
  height: 26px;
  border-radius: calc(var(--rundung) - 2px) calc(var(--rundung) - 2px) 0 0;
  background: var(--rot-schrift);
  border-bottom: var(--kante-st) solid var(--kante);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transform-origin: top;
}

.klappe-schrift {
  position: relative;
  z-index: 1;
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--auf-rot);
}

/* Druckanzeige in der Klappe: füllt sich, während du schreibst. */
.klappe-druck {
  position: absolute;
  inset: 0;
  background: var(--rot-tief);
  transform: scaleX(var(--druckf, 0));
  transform-origin: left;
  transition: transform 120ms linear;
  will-change: transform;
}

/* Nieten links und rechts — die Klappe ist verschraubt. */
.klappe-nieten {
  position: absolute;
  inset: 0 10px;
  z-index: 1;
  background:
    radial-gradient(circle at left  center, rgba(28,17,9,.5) 2.5px, transparent 2.6px),
    radial-gradient(circle at right center, rgba(28,17,9,.5) 2.5px, transparent 2.6px);
}

.einwurf.wirft .klappe { animation: schnappen 200ms cubic-bezier(.2, 0, 0, 1); }
@keyframes schnappen {
  0%   { transform: scaleY(1); }
  35%  { transform: scaleY(2.9); }
  100% { transform: scaleY(1); }
}

/* ---------- Das Feld ---------- */

.feld { position: relative; }

.feld textarea,
.feld-spiegel {
  font: inherit;
  font-size: 18px;
  line-height: 1.5;
  padding: 14px 16px 8px;
  margin: 0;
  border: 0;
  width: 100%;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  letter-spacing: 0;
}

.feld textarea {
  display: block;
  position: relative;
  z-index: 1;
  background: transparent;
  color: transparent;
  caret-color: var(--rot);
  resize: none;
  outline: none;
  max-height: 42vh;
  overflow-y: auto;
  min-height: 56px;
  scrollbar-width: thin;
  scrollbar-color: var(--linie) transparent;
}
.feld textarea::placeholder { color: var(--gedimmt); opacity: 1; }
.feld textarea:focus-visible { outline: none; }

/* Der Spiegel trägt die Farbe: #tags rot, [[Verlinkungen]] unterstrichen. */
.feld-spiegel {
  position: absolute;
  inset: 0;
  z-index: 0;
  color: var(--schrift);
  pointer-events: none;
  overflow: hidden;
}

/* Fokus zeigt sich als roter Balken am Feldfuß, nicht als Rahmen. */
.feld::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--rot);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--rast);
}
.einwurf:focus-within .feld::after { transform: scaleX(1); }

/* ---------- Bildvorschau ---------- */

.bildvorschau {
  position: relative;
  margin: 0 16px 4px;
  display: inline-block;
}
.bildvorschau[hidden] { display: none; }
.bildvorschau img {
  display: block;
  max-height: 96px;
  width: auto;
  max-width: 100%;
  border: var(--kante-st) solid var(--kante);
  border-radius: 8px;
}
.bildvorschau-weg {
  position: absolute;
  top: -8px; right: -8px;
  width: 26px; height: 26px;
  border-radius: 50%;
  border: var(--kante-st) solid var(--kante);
  background: var(--rot-schrift);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}
.bildvorschau-weg svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; }

/* ---------- Werkzeuge ---------- */

.werkzeuge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  padding-bottom: calc(8px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--linie);
  /* Ein Umbruch hier schiebt die Hauptaktion auf eine eigene Zeile und macht
     den Einwurf so hoch, dass er den Strom frisst. Lieber schrumpfen. */
  flex-wrap: nowrap;
  min-width: 0;
}

.werkzeuge-luft { flex: 1 1 auto; }

.wz {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  gap: 6px;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 99px;
  background: none;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--gedimmt);
  transition: background var(--schnapp), color var(--schnapp);
}
.wz svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.wz:hover { background: var(--senke); color: var(--schrift); }

.wz[aria-pressed="true"] { background: var(--rot-schrift); color: #fff; }
.wz[aria-pressed="true"]:hover { background: var(--rot-tief); }

/* Das Diktat pulst, solange es hört. */
#diktat[aria-pressed="true"] { animation: hoert 1.1s steps(2, jump-none) infinite; }
@keyframes hoert {
  0%, 100% { box-shadow: 0 0 0 0 rgba(244, 0, 0, .55); }
  50%      { box-shadow: 0 0 0 7px rgba(244, 0, 0, 0); }
}

/* Eigene Datei: ein gestanztes Loch, das sich füllt. */
.wz-loch .wz-loch { display: none; }
.wz-eigen .wz-loch {
  width: 15px; height: 15px;
  border-radius: 50%;
  border: 2.5px solid currentColor;
  background: transparent;
  transition: background var(--schnapp);
}
.wz-eigen[aria-pressed="true"] .wz-loch { background: #fff; }

.zaehler {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--gedimmt);
  padding: 0 4px;
  opacity: 0;
  transition: opacity var(--schnapp);
}
.einwurf.hat-text .zaehler { opacity: 1; }
.zaehler.zu-lang { color: var(--rot); }

/* Die Hauptaktion. */
.einwerfen {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  white-space: nowrap;
  gap: 8px;
  min-height: 44px;
  padding: 0 20px;
  border: var(--kante-st) solid var(--kante);
  border-radius: 99px;
  background: var(--rot-schrift);
  color: #fff;
  font-size: 15px;
  font-weight: 900;
  letter-spacing: -.02em;
  cursor: pointer;
  transition: background var(--schnapp), transform var(--schnapp), opacity var(--schnapp);
}
.einwerfen-taste {
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 5px;
  background: rgba(0, 0, 0, .22);
  line-height: 1.3;
}

.einwerfen svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.einwerfen:hover:not(:disabled) { background: var(--rot-tief); }
.einwerfen:active:not(:disabled) { transform: translateY(1px); }
.einwerfen:disabled {
  background: transparent;
  color: var(--gedimmt);
  border-color: var(--linie);
  cursor: default;
}

/* ---------- Vervollständigung ---------- */

/* Der Stapel über dem Einwurf: Melder ganz oben, darunter die Liste, darunter
   das Feld. Der Melder hängt am Kopf dieses Stapels statt an einer festen
   Bildschirmkante — dadurch wächst er mit der geöffneten Liste mit und braucht
   keine gerechnete Höhe. */
.ueber-einwurf {
  position: absolute;
  left: 10px; right: 10px;
  bottom: calc(100% + 8px);
  z-index: 20;
  pointer-events: none;
  display: flex;
  flex-direction: column;
}

.vorschlag {
  position: static;
  pointer-events: auto;
  background: var(--flaeche);
  border: var(--kante-st) solid var(--kante);
  border-radius: 12px;
  max-height: 220px;
  overflow-y: auto;
  padding: 5px;
  box-shadow: 0 12px 28px -12px rgba(28, 17, 9, .5);
}
.vorschlag[hidden] { display: none; }

.vorschlag button {
  display: block;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  padding: 9px 12px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 15px;
  font-weight: 700;
}
.vorschlag button[aria-selected="true"],
.vorschlag button:hover { background: var(--rot-schrift); color: #fff; }

/* ---------- Fußnote ---------- */

.fussnote {
  margin: 0;
  padding: 0 var(--rand);
  font-size: 12px;
  font-weight: 700;
  color: var(--gedimmt);
  text-align: center;
  min-height: 0;
}
.fussnote:empty { display: none; }
.fussnote:not(:empty) { padding: 5px var(--rand) 9px; }
.fussnote.warnt { color: var(--rot-schrift); }

/* ==========================================================================
   Die Flugbahn — die Kapsel auf ihrem Weg in den Schacht
   ========================================================================== */

.flugbahn {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
  overflow: hidden;
}

.flieger {
  position: absolute;
  background: var(--rot);
  border: var(--kante-st) solid var(--kante);
  border-radius: 99px;
  will-change: transform;
  box-shadow: 0 6px 18px -6px rgba(28, 17, 9, .6);
}
.flieger::before, .flieger::after {
  content: "";
  position: absolute;
  top: 12%; bottom: 12%;
  width: 3px;
  background: rgba(28, 17, 9, .45);
}
.flieger::before { left: 22%; }
.flieger::after  { right: 22%; }

/* ---------- Melder (Bildschirmleser + kurze Hinweise) ---------- */

/* Der Melder fährt aus dem Stapel aus, nicht über ihn: der Schacht schneidet
   ihn ab, solange er unten steht. Vorher lag er als feste Leiste am unteren
   Bildrand über Feld, Werkzeugen und „Einwerfen" — und nahm dabei Taps an. */
.melder-schacht {
  display: flex;
  justify-content: center;
  overflow: hidden;
  /* Ohne Meldung nimmt der Schacht keine Höhe ein — sonst stünde die
     Vorschlagsliste dauerhaft um eine leere Melderzeile zu hoch. Der Schacht
     klappt auf, dann fährt der Melder aus; beim Zurückfahren klappt er erst zu,
     wenn der Melder wieder unten ist. Beides schaltet `melden()` um, damit hier
     keine Layout-Eigenschaft in einer Überblendung steht. */
  height: 0;
}
.melder-schacht.offen {
  height: auto;
  margin-bottom: 8px;
}

.melder {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: min(100%, 520px);
  transform: translateY(calc(100% + 8px));
  background: var(--tinte);
  color: var(--creme);
  font-size: 14px;
  font-weight: 700;
  padding: 11px 20px;
  border-radius: 10px;
  transition: transform var(--rast);
}
.melder.zeigt { transform: none; }

/* Die Rücknahme ist das einzige Bedienelement im Melder — der Rest ist Text
   und darf nichts abfangen. */
.melder-knopf {
  flex: 0 0 auto;
  pointer-events: auto;
  min-height: 34px;
  padding: 0 14px;
  border: var(--kante-st) solid var(--creme);
  border-radius: 99px;
  background: none;
  color: var(--creme);
  font-size: 13px;
  font-weight: 900;
  letter-spacing: -.02em;
  cursor: pointer;
  transition: background var(--schnapp), color var(--schnapp);
}
.melder-knopf:hover { background: var(--creme); color: var(--tinte); }
.melder-knopf:active { transform: translateY(1px); }
.melder-knopf[hidden] { display: none; }

/* ==========================================================================
   Kleine Geräte
   ========================================================================== */

@media (max-width: 820px) {
  :root { --schacht-b: 40px; --rand: 14px; }

  body { font-size: 16px; }

  .schacht-rohr { width: 20px; }
  .tagesleiste { padding: 0 4px; gap: 4px; margin-bottom: 40px; }
  .tagesleiste-text { display: none; }

  /* Vierzehn Tage statt achtundzwanzig: in 40px Breite wird die
     Desktop-Dichte zur Schraffur. Lieber weniger Tage, dafür lesbar. */
  .tagesleiste-tag { height: 11px; }
  .tagesleiste-tag:nth-last-child(n + 15) { display: none; }
  .tagesleiste-balken { height: 5px; }
  .tagesleiste-tag.ist-leer .tagesleiste-balken { height: 3px; opacity: .45; }
  .tagesleiste-tag.ist-heute .tagesleiste-balken { height: 8px; }

  .kopf { padding: 10px var(--rand); }
  .kopf-innen { gap: 10px; }
  .marke h1 { font-size: 18px; }
  .marke-zeichen { width: 26px; height: 26px; }
  .stand { padding: 4px 11px 4px 8px; gap: 6px; }
  .stand-zahl { font-size: 17px; }
  .stand-text { font-size: 12px; white-space: nowrap; }
  /* „Kapseln" trägt der Kontext; Zahl und Zustand reichen. */
  .stand-lang { display: none; }

  .strom { padding: 14px var(--rand) 18px; }
  .kapseln { gap: 10px; }

  .kapsel { grid-template-columns: 48px minmax(0, 1fr) auto; }
  .kapsel-ring-links { left: 48px; }
  .kapsel-ring-rechts { right: 30px; }
  .kapsel-kopf { padding: 9px 3px; }
  .kapsel-zeit { font-size: 14px; letter-spacing: -.05em; }
  .kapsel-tag { font-size: 10px; }
  .kapsel-leib { padding: 9px 11px; }
  .kapsel-fuss { width: 30px; padding: 9px 3px; }
  .kapsel-zustand { font-size: 0; letter-spacing: 0; }
  .kapsel-weg { opacity: 1; }

  .einwurf { margin: 0 var(--rand); width: calc(100% - var(--rand) * 2); }
  .feld textarea, .feld-spiegel { font-size: 17px; padding: 12px 13px 6px; }
  .feld textarea { max-height: 34vh; }

  .wz > span:not(.wz-loch) { display: none; }
  .wz { padding: 0 13px; }
  .wz-eigen .wz-loch { width: 17px; height: 17px; }
  .einwerfen { padding: 0 16px; }
  .einwerfen-taste { display: none; }
  .zaehler { display: none; }

  .fussnote:not(:empty) { padding-left: 10px; padding-right: 10px; }
}

/* Ganz schmal: die Werkzeugleiste darf nicht umbrechen. */
@media (max-width: 380px) {
  /* Auf ein „fr…" verzichtet der Kopf lieber ganz: das Zeichen trägt die Marke,
     und der Platz gehört Stand und Ton. */
  .marke h1 { display: none; }

  .werkzeuge { gap: 2px; padding: 6px 6px; padding-bottom: calc(6px + env(safe-area-inset-bottom)); }
  .wz { padding: 0 9px; }
  .einwerfen { padding: 0 13px; font-size: 14px; }
}

/* Auf iOS schiebt die Tastatur das Layout — dvh hält den Einwurf sichtbar. */
@supports (height: 100dvh) {
  .anlage { height: 100dvh; }
}

/* ==========================================================================
   Ruhe
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .flugbahn { display: none; }
  .schacht-rueckwelle { display: none; }
  /* Der Zustand bleibt sichtbar, nur ohne Puls. */
  .kapsel-zustand::before { animation: none; background: transparent; }
  .kapsel.ist-hier .kapsel-zustand::before { background: var(--rot); }
  .kapsel.ist-abgeholt .kapsel-zustand::before { background: var(--schrift); }
}

/* ==========================================================================
   Anmeldung
   ========================================================================== */

.tor {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 24px;
}

.tor-karte {
  width: min(100%, 400px);
  border: var(--kante-st) solid var(--kante);
  border-radius: var(--rundung);
  background: var(--flaeche);
  overflow: hidden;
}

/* Die Klappe der Anmeldekarte trägt kein Wort: über einer Überschrift wäre
   eine gesperrte Versalzeile ein Eyebrow, egal wie sehr sie zur Welt gehört.
   Das Bauteil allein sagt schon, worum es geht. */
.tor-klappe {
  position: relative;
  height: 30px;
  background: var(--rot-schrift);
  border-bottom: var(--kante-st) solid var(--kante);
}
.tor-klappe .klappe-nieten { inset: 0 12px; }

.tor-leib { padding: 26px 24px 24px; text-align: center; }
.tor-leib svg { width: 54px; height: 54px; display: block; margin: 0 auto 16px; }
.tor-leib h1 { margin: 0 0 6px; font-size: 27px; font-weight: 900; letter-spacing: -.035em; }
.tor-leib p { margin: 0 0 20px; color: var(--gedimmt); font-size: 15px; }

.tor-leib input {
  font: inherit;
  font-size: 17px;
  width: 100%;
  padding: 13px 15px;
  border: var(--kante-st) solid var(--kante);
  border-radius: 10px;
  background: var(--grund);
  color: var(--schrift);
  margin-bottom: 12px;
}
.tor-leib input::placeholder { color: var(--gedimmt); }

.tor-feld { position: relative; }

/* Der Zeigen-Schalter ist ein Werkzeug, kein zweiter Hauptknopf: er erbt die
   Breite und das Rot der Hauptaktion ausdrücklich nicht. Er steht zwischen den
   Feldern und der Aktion, weil er zu den Feldern gehört. */
.tor-leib .tor-zeigen {
  width: auto;
  min-height: 44px;
  margin: 0 auto 14px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 0;
  border-radius: 99px;
  background: none;
  color: var(--gedimmt);
  font-size: 13px;
  font-weight: 700;
  transition: background var(--schnapp), color var(--schnapp);
}
.tor-leib .tor-zeigen:hover { background: var(--senke); color: var(--schrift); }
.tor-leib .tor-zeigen[hidden] { display: none; }

.tor-zeigen svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Gedrückt heißt: das Wort steht offen da. Der Strich durchs Auge gehört
   deshalb in den zugeklappten Zustand, nicht in den offenen. */
.tor-zeigen[aria-pressed="true"]  .tor-strich { display: none; }
.tor-zeigen[aria-pressed="false"] .tor-strich { display: block; }

.tor-fussnote {
  margin: 16px 0 0 !important;
  font-size: 12px !important;
  font-weight: 700;
  line-height: 1.5;
  color: var(--gedimmt);
}

.tor-leib button {
  width: 100%;
  min-height: 48px;
  border: var(--kante-st) solid var(--kante);
  border-radius: 99px;
  background: var(--rot-schrift);
  color: #fff;
  font-size: 16px;
  font-weight: 900;
  cursor: pointer;
}
.tor-leib button:hover { background: var(--rot-tief); }

.tor-fehler {
  margin: 0 0 14px !important;
  color: var(--rot-schrift) !important;
  font-weight: 700;
}
