/* ============================================================
   allgood v0.2 — "der Agent"
   Dunkle, ruhige Oberfläche. Ein Akzent, der den Zustand trägt:
   grau im Ruhezustand, bernstein beim Denken, grün wenn alles OK ist.
   ============================================================ */

:root {
  --bg: #08090c;
  --bg-lift: #0e1015;
  --line: rgba(255, 255, 255, 0.09);
  --text: #e9ecf2;
  --text-dim: #7d8494;
  --text-faint: #4a5060;

  --idle: #8a93a6;
  --think: #f0b849;
  --ok: #d6e4dc; /* fast weiss, nur ein Hauch Grün */
  /* Phosphorgrün eines alten Monochrom-Terminals. Bewusst nicht das grelle
     Neongrün der Hacker-Klischees, sondern etwas müder und leicht ins
     Milchige gezogen, damit es neben dem Gold nicht wie ein Fremdkörper
     wirkt, sondern wie dieselbe Röhre in einer anderen Stimmung. */
  --deep: #7ef9a4;

  /* Der Akzent wird zur Laufzeit umgeschaltet */
  --accent: var(--idle);
  --accent-soft: rgba(138, 147, 166, 0.14);

  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
  position: relative;
}

/* Sehr subtiler Lichtschein hinter der Bühne, folgt dem Zustand */
body::before {
  content: "";
  position: fixed;
  inset: -20%;
  background: radial-gradient(
    46% 40% at 50% 42%,
    var(--accent-soft),
    transparent 70%
  );
  transition: background 1.4s var(--ease-soft);
  pointer-events: none;
  z-index: 0;
}

/* Feines Korn, damit die Fläche nicht digital-flach wirkt */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* ---------- Kopfzeile: Statusanzeige ---------- */

.head {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 26px;
  font-size: 13px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  letter-spacing: -0.01em;
  font-weight: 500;
  color: var(--text-dim);
}

.brand b {
  color: var(--text);
  font-weight: 600;
}

.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent);
  transition: background 0.6s var(--ease-soft);
  animation: breathe 3.4s var(--ease-soft) infinite;
}

@keyframes breathe {
  0%,
  100% {
    box-shadow: 0 0 0 0 var(--accent-soft);
    opacity: 0.75;
  }
  50% {
    box-shadow: 0 0 0 6px transparent;
    opacity: 1;
  }
}

.head-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.status {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-faint);
  letter-spacing: 0.02em;
}

/* Lautsprecher-Schalter, deutlich sichtbar. An = Wellen leuchten im Akzent,
   aus = Wellen verblassen und ein Strich liegt darüber. */
.spk {
  appearance: none;
  border: 0;
  background: none;
  padding: 4px;
  cursor: pointer;
  color: var(--text-dim);
  display: inline-flex;
  transition: color 0.25s var(--ease-soft);
}
.spk:hover {
  color: var(--text);
}
.spk svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.spk .spk-body {
  fill: currentColor;
  stroke: currentColor;
}
.spk .spk-waves path {
  opacity: 0;
  transition: opacity 0.25s var(--ease-soft);
}
.spk .spk-off {
  opacity: 1;
  stroke: currentColor;
  transition: opacity 0.25s var(--ease-soft);
}
/* Zustand "an" wird per Klasse gesetzt */
.spk.on {
  color: var(--ok);
}
.spk.on .spk-waves path {
  opacity: 1;
}
.spk.on .spk-off {
  opacity: 0;
}

/* ---------- Bühne ---------- */

.stage {
  position: relative;
  z-index: 5;
  height: 100%;
  display: grid;
  place-items: center;
  padding: 80px 24px;
}

.scene {
  width: min(560px, 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 34px;
}

/* ---------- Einstieg ---------- */

.ask {
  font-size: clamp(26px, 5.2vw, 40px);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.03em;
  text-align: center;
  text-wrap: balance;
  max-width: 15ch;
}

.ask em {
  font-style: normal;
  color: var(--text-dim);
}

.go {
  position: relative;
  appearance: none;
  border: 1px solid var(--line);
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.05),
    rgba(255, 255, 255, 0.01)
  );
  color: var(--text);
  font: 500 16px/1 var(--sans);
  letter-spacing: -0.01em;
  padding: 17px 30px;
  border-radius: 100px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  transition:
    transform 0.5s var(--ease),
    border-color 0.4s var(--ease-soft),
    box-shadow 0.5s var(--ease-soft);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset;
}

.go:hover {
  border-color: rgba(214, 228, 220, 0.34);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.08) inset,
    0 0 34px -8px rgba(214, 228, 220, 0.34);
  transform: translateY(-1px);
}

.go:active {
  transform: translateY(0) scale(0.985);
}

.go .arrow {
  color: var(--text-faint);
  transition:
    transform 0.5s var(--ease),
    color 0.4s;
}

.go:hover .arrow {
  transform: translateX(4px);
  color: var(--ok);
}

.hint {
  font-size: 13px;
  color: var(--text-faint);
  letter-spacing: -0.01em;
}

/* ---------- Arbeitsphase: der Agent denkt ---------- */

.work {
  width: 100%;
  display: none;
  flex-direction: column;
  gap: 20px;
}

.work.on {
  display: flex;
}

.log {
  font-family: var(--mono);
  font-size: 13.5px;
  line-height: 1.85;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2px;
  overflow: hidden;
  mask-image: linear-gradient(180deg, transparent, #000 22%, #000 100%);
}

.line {
  display: flex;
  gap: 11px;
  align-items: baseline;
  color: var(--text-dim);
  opacity: 0;
  transform: translateY(6px);
  animation: rise 0.5s var(--ease) forwards;
}

@keyframes rise {
  to {
    opacity: 1;
    transform: none;
  }
}

/* Ältere Zeilen treten zurück, die aktuelle steht vorn */
.line.past {
  color: var(--text-faint);
  opacity: 0.55;
}

.line .mark {
  color: var(--accent);
  flex: none;
  transition: color 0.5s;
}

.line.warn .mark,
.line.warn .txt {
  color: var(--think);
  text-shadow: 0 0 16px rgba(240, 184, 73, 0.35);
  transition:
    color 1.2s var(--ease-soft),
    text-shadow 1.2s var(--ease-soft);
}

/* Die auslösende Zeile ist selbst eine Warnzeile und stünde sonst als
   einziges Element weiter in Gold da, während ringsum alles ins Grün
   kippt. Sie muss mitziehen, sonst zerfällt das Bild genau im Moment
   der Pointe. */
body[data-tief] .line.warn .mark,
body[data-tief] .line.warn .txt {
  color: var(--deep);
  text-shadow: 0 0 16px rgba(126, 249, 164, 0.35);
}

.line.done .mark,
.line.done .txt {
  color: var(--ok);
  text-shadow: 0 0 18px rgba(52, 226, 155, 0.4);
}

/* Hervorgehobene Zeilen leuchten beim Erscheinen kurz auf, dann beruhigt es
   sich. Der Effekt, den Martin mag: selten, aber wirkungsvoll. */
.line.warn,
.line.done {
  animation:
    rise 0.5s var(--ease) forwards,
    flare 1.4s var(--ease-soft);
}

@keyframes flare {
  0% {
    filter: brightness(1.9);
  }
  40% {
    filter: brightness(1.35);
  }
  100% {
    filter: brightness(1);
  }
}

/* Ein einzelnes leuchtendes Schlüsselwort mitten in einer neutralen Zeile.
   Sparsam einsetzen, sonst nutzt sich der Reiz ab. */
.txt .glow {
  color: var(--ok);
  text-shadow: 0 0 14px rgba(52, 226, 155, 0.45);
}
.txt .glow.amber {
  color: var(--think);
  text-shadow: 0 0 14px rgba(240, 184, 73, 0.4);
}

/* Kurzer Glitch: die Zeile zittert einmal beim Erscheinen. Dezent. */
.line.glitch .txt {
  animation: glitch 0.34s steps(2) 1;
}
@keyframes glitch {
  0% {
    transform: translateX(0);
    opacity: 1;
  }
  25% {
    transform: translateX(-2px);
    opacity: 0.7;
  }
  50% {
    transform: translateX(2px);
    opacity: 1;
  }
  75% {
    transform: translateX(-1px);
    opacity: 0.85;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

.caret {
  display: inline-block;
  width: 7px;
  height: 15px;
  background: var(--accent);
  margin-left: 3px;
  transform: translateY(2px);
  animation: caret 1s steps(2) infinite;
}

@keyframes caret {
  50% {
    opacity: 0;
  }
}

/* Fortschritt als dünne, unregelmäßig laufende Linie */
.bar {
  height: 1px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}

.bar i {
  position: absolute;
  inset: 0 100% 0 0;
  background: linear-gradient(90deg, transparent, var(--accent));
  /* Übergänge stehen weiter unten bei den Zuständen, weil die Farbe seit
     dem Grün-Umschlag auch mitten im Durchlauf wechseln kann. */
}

/* ---------- Auflösung ---------- */

.done-screen {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 26px;
  text-align: center;
}

.done-screen.on {
  display: flex;
  animation: rise 0.9s var(--ease) forwards;
}

.seal {
  position: relative;
  width: 74px;
  height: 74px;
  display: grid;
  place-items: center;
}

.seal svg {
  width: 34px;
  height: 34px;
  stroke: var(--ok);
  stroke-width: 1.9;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 32;
  stroke-dashoffset: 32;
  animation: draw 0.7s var(--ease) 0.25s forwards;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}

/* Ein einziger Ring, der nach aussen läuft. Kein Konfetti. */
.seal::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--ok);
  border-radius: 50%;
  opacity: 0;
  animation: ring 1.5s var(--ease) 0.3s;
}

@keyframes ring {
  0% {
    opacity: 0.6;
    transform: scale(0.72);
  }
  100% {
    opacity: 0;
    transform: scale(1.9);
  }
}

.verdict {
  font-size: clamp(28px, 6vw, 44px);
  font-weight: 600;
  letter-spacing: -0.035em;
}

.footnote {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--text-faint);
  line-height: 1.75;
  max-width: 42ch;
  text-wrap: balance;
}

.again {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 4px;
}

.ghost {
  appearance: none;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text-dim);
  font: 500 14px/1 var(--sans);
  padding: 13px 20px;
  border-radius: 100px;
  cursor: pointer;
  transition:
    color 0.3s,
    border-color 0.3s,
    background 0.3s;
}

.ghost:hover {
  color: var(--text);
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.03);
}

.ghost.warm:hover {
  color: var(--ok);
  border-color: rgba(214, 228, 220, 0.34);
}

/* ---------- Fusszeile ---------- */

.foot {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 20px 24px;
  font-size: 12px;
  color: var(--text-faint);
}

.foot a,
.foot button {
  color: var(--text-faint);
  text-decoration: none;
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
  padding: 3px 2px;
  transition: color 0.25s;
}

.foot a:hover,
.foot button:hover {
  color: var(--text-dim);
}

.foot .sep {
  opacity: 0.3;
}

.foot select {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--text-faint);
  font: inherit;
  cursor: pointer;
  padding: 3px 2px;
}

.foot select option {
  background: var(--bg-lift);
  color: var(--text);
}

/* Der Rückweg zur alten Fassung — bewusst als Fussnote, nicht als Werbung */
.foot .classic {
  color: var(--text-faint);
}

.foot .classic:hover {
  color: var(--think);
}

/* Ton-Schalter */
.sound {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.sound .waves {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: 10px;
}

.sound .waves span {
  width: 2px;
  background: currentColor;
  height: 3px;
  border-radius: 1px;
}

.sound.on .waves span {
  animation: eq 1.1s var(--ease-soft) infinite;
}

.sound.on .waves span:nth-child(2) {
  animation-delay: 0.18s;
}

.sound.on .waves span:nth-child(3) {
  animation-delay: 0.36s;
}

@keyframes eq {
  0%,
  100% {
    height: 3px;
  }
  50% {
    height: 10px;
  }
}

/* ---------- Sprachhinweis ---------- */

.langbar {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translate(-50%, -140%);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 100px;
  background: rgba(14, 16, 21, 0.85);
  backdrop-filter: blur(12px);
  font-size: 13px;
  color: var(--text-dim);
  transition: transform 0.7s var(--ease);
}

.langbar.on {
  transform: translate(-50%, 0);
}

.langbar button {
  background: none;
  border: 0;
  color: var(--ok);
  font: 500 13px/1 var(--sans);
  cursor: pointer;
}

.langbar .x {
  color: var(--text-faint);
  font-size: 15px;
  line-height: 1;
}

/* ---------- Zustände ---------- */

body[data-state="thinking"] {
  --accent: var(--think);
  --accent-soft: rgba(240, 184, 73, 0.12);
}

body[data-state="ok"] {
  --accent: var(--ok);
  --accent-soft: rgba(214, 228, 220, 0.11);
}

/* Der eine Moment, in dem die Maschine zu tief schaut.

   Dann kippt das warme Gold in das Phosphorgrün eines alten
   Monochrom-Terminals: kälter, älter, sachlicher. Der Wechsel passiert immer
   an derselben Stelle im Ablauf (die Sorge, die bleibt), niemals zufällig —
   sonst wirkt er wie ein Anzeigefehler statt wie Absicht.

   Er überschreibt "thinking", solange er gesetzt ist, und wird zum
   Schlussbild wieder entfernt: da behauptet die Seite ja erneut, alles sei
   in Ordnung. Die Übergangszeiten stecken in den nutzenden Elementen
   (Hintergrundschimmer 1,4 s, Marker 0,5 s), das Umschlagen geschieht also
   langsam genug, dass man es eher spürt als sieht. */
body[data-state="thinking"][data-tief] {
  --accent: var(--deep);
  --accent-soft: rgba(126, 249, 164, 0.1);
}

/* Caret und Fortschrittsbalken hatten bisher keinen Farbübergang, weil die
   Farbe nie mitten im Durchlauf wechselte. Jetzt tut sie das. */
.caret {
  transition: background 1.2s var(--ease-soft);
}

.bar i {
  transition:
    right 0.9s var(--ease-soft),
    background 1.2s var(--ease-soft);
}

.fade-out {
  animation: fade 0.55s var(--ease-soft) forwards;
}

@keyframes fade {
  to {
    opacity: 0;
    transform: scale(0.97) translateY(-8px);
    filter: blur(6px);
  }
}

/* ---------- Kleine Bildschirme ---------- */

@media (max-width: 560px) {
  .head {
    padding: 16px 18px;
  }
  .status {
    display: none;
  }
  .log {
    font-size: 12.5px;
    min-height: 230px;
  }
  .stage {
    padding: 70px 20px 90px;
  }
  /* Auf dem Handy zerfiel die Fusszeile in zwei Zeilen, weil vier Rechts-
     Links, zwei Auswahlfelder und die Trenner nebeneinander nicht mehr
     passen. Eine umbrechende Fusszeile sieht nach Versehen aus, deshalb
     etwas enger setzen und die Auswahlfelder schmaler halten. */
  .foot {
    font-size: 11px;
    gap: 4px;
    padding: 16px 10px;
  }
  .foot .sep {
    margin: 0 -1px;
  }
  .foot-sel {
    font-size: 11px;
    padding-right: 2px;
  }

  /* Das Schlussverdikt darf auf schmalen Geräten etwas kleiner starten:
     die längsten erlaubten Sätze (42 Zeichen) brauchen sonst drei Zeilen
     und schieben den Weiter-Knopf aus dem ersten Blickfeld. */
  .verdict {
    font-size: clamp(25px, 7.4vw, 34px);
  }
}

/* ---------- Rücksicht auf Bewegungsempfindlichkeit ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .line {
    opacity: 1;
    transform: none;
  }
}

/* ---------- Abspann ----------
   Bewusst kein Knopf und keine Bitte um Geld: acht Monate Kaffee-Knopf
   haben null Zahlungen gebracht. Eine leise Zeile, die zur Pointe passt,
   ist ehrlicher und bringt eher einen Klick als ein Bezahlfeld. */

.credits {
  margin-top: 10px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  max-width: 40ch;
}

.credits p {
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--text-faint);
  white-space: pre-line;
  letter-spacing: -0.005em;
}

/* Der Link sitzt jetzt IM Satz, auf dem Wort "Mensch". Er darf sich nicht
   als Knopf aufführen: eine kaum sichtbare Unterstreichung genügt, damit
   man ihn findet, ohne dass der Abspann zur Werbefläche wird. Erst beim
   Darüberfahren tritt er hervor. */
.credits a.human {
  color: var(--text-dim);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  padding-bottom: 1px;
  transition:
    color 0.3s var(--ease-soft),
    border-color 0.3s var(--ease-soft);
}

.credits a.human:hover {
  color: var(--text);
  border-bottom-color: var(--accent);
}
