/* NEXUP Download. Farben, Schrift und Material wie auf nexup.studio.
   Schriften liegen als Dateien daneben, nicht als base64 im Stylesheet:
   so werden sie zwischengespeichert und komprimiert. */

@font-face { font-family: "Montserrat"; src: url("schrift/montserrat-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Montserrat"; src: url("schrift/montserrat-500.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Montserrat"; src: url("schrift/montserrat-600.woff2") format("woff2"); font-weight: 600; font-display: swap; }

:root {
  --e0: #070a10;
  --e1: #0d1420;
  --e2: #131c2b;
  --e3: #1b2637;
  --tinte: #eef3f9;
  --tinte-72: rgba(238, 243, 249, .72);
  --tinte-52: rgba(238, 243, 249, .52);
  --marke: #3d77bb;
  --marke-hell: #87abd5;
  --gut: #3fb27f;
  --schlecht: #d9534f;
  --kante: rgba(255, 255, 255, .09);
  --licht: rgba(255, 255, 255, .16);
  --r: 10px;
  --r-gr: 16px;
  --r-xl: 24px;
  /* Breite des Satzspiegels. Das Netz liest sie aus und dunkelt ausserhalb
     davon ab, damit die Tafel in der Mitte die Buehne behaelt. */
  --wrap: 720px;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: clamp(24px, 6vw, 64px) 20px 64px;
  background: var(--e0);
  color: var(--tinte);
  font: 400 16px/1.65 "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

/* ---- Netzgrund ----
   Liegt fest hinter allem und scrollt nicht mit: es ist Raum, kein Inhalt.
   Gezeichnet wird in netz.js, hier steht nur, wo es haengt. */
.mesh { position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; opacity: .9; }

/* ---- Licht ----
   Die Website legt ihr Licht als weiche Flaechen UEBER das Netz, nicht
   darunter: erst dadurch bekommt die Flaeche eine Richtung und der Grund
   hoert auf, gleichmaessig dunkel zu sein. Werte und Farben sind die der
   Startseite (.glut--e und .glut--a), nur fest im Fenster statt in einem
   Abschnitt, weil es hier nur einen Abschnitt gibt.
   Ohne diese Ebene sieht das Netz aus wie ein Muster statt wie Raum. */
.licht { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.glut { position: absolute; border-radius: 50%; pointer-events: none; }
.glut--e {
  width: min(120vw, 1500px); height: min(70vh, 620px);
  top: -34%; left: 50%; translate: -50% 0;
  background: radial-gradient(ellipse at center, rgba(61,119,187,.22), rgba(36,81,138,.09) 46%, transparent 72%);
}
.glut--a {
  width: min(78vw, 900px); aspect-ratio: 1; top: -18%; right: -12%;
  background: radial-gradient(circle, rgba(61,119,187,.30), rgba(61,119,187,.08) 42%, transparent 68%);
}
.glut--b {
  width: min(52vw, 560px); aspect-ratio: 1; top: 34%; left: -16%;
  background: radial-gradient(circle, rgba(36,81,138,.28), transparent 66%);
}

/* ---- Korn ----
   Nimmt dem Verlauf die Streifen. Grosse dunkle Flaechen bilden sonst
   sichtbare Stufen, weil 8 Bit je Kanal dafuer zu grob sind. Das Rauschen
   bricht die Stufenkante auf. Winziges SVG, kein Bild.
   Liegt UEBER dem Inhalt, wie auf der Website (dort z-index 60). Darunter
   wuerde es nur den Grund kruemeln und die Schrift bliebe glatt - dann sind
   es zwei Materialien statt einem. */
.korn {
  position: fixed; inset: 0; z-index: 3; pointer-events: none; opacity: .055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

.huelle { max-width: 720px; margin: 0 auto; position: relative; z-index: 2; }

/* ---- Auftauchen ----
   Nur wenn Javascript laeuft. Ohne die .js-Bedingung staende bei
   abgeschaltetem Javascript eine unsichtbare Seite da. */
.js .steigt {
  opacity: 0; transform: translateY(18px);
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
  transition-delay: calc(var(--i, 0) * 70ms);
}
.js .steigt.da { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .steigt { opacity: 1; transform: none; transition: none; }
  .korn { display: none; }
}

.marke { display: block; width: 168px; margin: 0 auto clamp(28px, 5vw, 48px); opacity: .9; transition: opacity .2s; }
.marke:hover { opacity: 1; }
.marke img { width: 100%; height: auto; display: block; }

/* Glas, Zeichen fuer Zeichen wie auf der Website: 158 Grad, drei Marken,
   22px Unschaerfe mit Saettigung, Lichtkante .16, zwei Schatten. Wer hier
   eigene Werte erfindet, baut ein zweites Material. */
.tafel {
  position: relative; isolation: isolate;
  background:
    linear-gradient(158deg, rgba(255,255,255,.072), rgba(255,255,255,.018) 46%, rgba(255,255,255,.042)),
    rgba(12,18,27,.58);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  backdrop-filter: blur(22px) saturate(150%);
  border: 1px solid var(--kante);
  border-radius: var(--r-xl);
  padding: clamp(24px, 5vw, 44px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.16),
    0 2px 6px rgba(0,0,0,.36),
    0 44px 90px -54px rgba(0,0,0,.95);
}
/* Wo es keine Hintergrundunschaerfe gibt, wird das Glas zur deckenden
   Flaeche. Ohne diesen Zweig saehe man dort den Netzgrund durch die Tafel
   hindurch und die Schrift stuende im Dreiecksmuster. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .tafel { background: var(--e2); }
}
.tafel--schmal { max-width: 420px; margin: 0 auto; }
/* Abstand zwischen zwei Tafeln. Ueber den Nachbarwaehler und nicht als
   margin-bottom an jeder Tafel: sonst haengt unter der letzten ein Rand, den
   niemand bestellt hat, und der Fuss der Seite rutscht mit.
   Dieselbe Leiter wie das Innenpolster der Tafel (clamp 24..44): der Abstand
   ZWISCHEN zwei Karten darf nicht kleiner sein als der Abstand INNERHALB
   einer, sonst lesen sich beide als ein Block mit einer Naht in der Mitte. */
.tafel + .tafel { margin-top: clamp(28px, 5vw, 44px); }

h1 { font-size: clamp(24px, 4vw, 32px); font-weight: 600; letter-spacing: -.02em; margin: 0 0 10px; }
h2 { font-size: 17px; font-weight: 600; margin: 0; }
.lead { color: var(--tinte-72); margin: 0 0 28px; }
.klein { font-size: 13px; color: var(--tinte-52); font-weight: 400; }

/* ---- Formular ---- */
.form { display: grid; gap: 8px; margin: 0 0 22px; }
.form label { font-size: 13px; color: var(--tinte-72); margin-top: 10px; }
.form input {
  width: 100%; padding: 13px 15px; font: inherit; color: var(--tinte);
  background: rgba(0,0,0,.28); border: 1px solid var(--kante); border-radius: var(--r);
  transition: border-color .18s, box-shadow .18s;
}
.form input::placeholder { color: rgba(238,243,249,.32); }
.form input:focus { outline: none; border-color: var(--marke); box-shadow: 0 0 0 3px rgba(61,119,187,.28) inset; }
/* Der Code ist 24 Zeichen lang. Fest auf 19px mit .09em Laufweite passte er
   am Handy nicht ins Feld: die letzte Vierergruppe wurde abgeschnitten, und
   zwar genau dort, wo der Kunde ihn eintippt. Beides waechst jetzt mit der
   Breite mit. */
#code {
  font-size: clamp(15px, 4.1vw, 19px);
  letter-spacing: .09em;
  text-align: center; font-weight: 500;
}
/* Gemessen bei 375 Punkten: 22 Zeichen brauchten 271 Punkte, verfuegbar waren
   253. Allein die Laufweite kostete 30 davon. Sie faellt deshalb am Handy weg
   und das Polster wird schmaler - dann bleiben 241 und der Code steht ganz da.
   Lieber eng gesetzt als abgeschnitten: was man nicht ganz sieht, tippt man
   falsch ab. */
@media (max-width: 430px) {
  /* Auf schmalen Schirmen ist Polster der teuerste Platz. Statt die Schrift
     immer weiter zu schrumpfen (bei 320 Punkten waeren 12,7px noetig, das
     liest niemand mehr) bekommt die Karte aussen und innen weniger Rand.
     Gemessen bei 320: vorher fehlten 22 Punkte, jetzt bleibt Reserve. */
  body { padding-left: 14px; padding-right: 14px; }
  .tafel { padding: 24px 18px; }
  #code { letter-spacing: 0; padding-left: 8px; padding-right: 8px; font-size: clamp(13.5px, 4.4vw, 17px); }
}

.form button, .knopf {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 14px; padding: 13px 22px; font: inherit; font-weight: 600;
  color: #fff; background: var(--marke); border: 0; border-radius: var(--r);
  cursor: pointer; text-decoration: none; transition: filter .18s, transform .18s;
}
.form button:hover, .knopf:hover { filter: brightness(1.12); }
.form button:active, .knopf:active { transform: translateY(1px); }
.knopf--aus { background: var(--e3); color: var(--tinte-52); cursor: default; }
.knopf--aus:hover { filter: none; }
.knopf--leise { background: none; border: 1px solid var(--kante); color: var(--tinte-52); padding: 6px 10px; margin: 0; font-weight: 400; }
.knopf--leise:hover { color: var(--schlecht); border-color: var(--schlecht); filter: none; }

.form--reihe { grid-template-columns: 1fr 90px auto; gap: 10px; align-items: end; }
.form--reihe button { margin-top: 0; }
@media (max-width: 560px) { .form--reihe { grid-template-columns: 1fr; } }

/* ---- Meldungen ---- */
.meldung { padding: 13px 16px; border-radius: var(--r); border: 1px solid var(--kante); background: rgba(0,0,0,.24); font-size: 14.5px; margin: 0 0 20px; }
.meldung--fehler { border-color: rgba(217,83,79,.5); background: rgba(217,83,79,.12); }
.meldung--gut { border-color: rgba(63,178,127,.5); background: rgba(63,178,127,.12); }

/* ---- Versionen ---- */
.versionen { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
/* Die Tafel ist die Scheibe, der Eintrag ist ein Blatt darauf: leichte
   Aufhellung mit Ring, Radius eine Stufe kleiner als der der Tafel. Ein
   Innenkasten mit demselben Radius wie sein Behaelter sieht aus, als sei er
   hineingerutscht. */
.version {
  background: rgba(255,255,255,.035); border: 1px solid var(--kante);
  border-radius: var(--r-gr); padding: 20px 22px;
  transition: border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease);
}
.version:hover { border-color: rgba(255,255,255,.16); background: rgba(255,255,255,.05); }
.version--neu { border-color: rgba(61,119,187,.5); background: rgba(61,119,187,.09); }
/* Ohne diese Zeile gewinnt .version:hover ueber .version--neu (hoehere
   Spezifitaet) und die aktuelle Fassung verliert beim Ueberfahren ihr Blau. */
.version--neu:hover { border-color: rgba(61,119,187,.75); background: rgba(61,119,187,.14); }
.version__kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.version__datum { font-size: 13px; color: var(--tinte-52); white-space: nowrap; }
.abzeichen { display: inline-block; margin-left: 8px; padding: 2px 9px; font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--marke-hell); background: rgba(61,119,187,.18); border-radius: 999px; vertical-align: middle; }
.hinweise { margin: 12px 0 0; padding-left: 20px; color: var(--tinte-72); font-size: 14.5px; }
.hinweise li { margin: 4px 0; }
.version .knopf { margin-top: 18px; }

/* ---- Notiz mit dem persoenlichen Link ---- */
.notiz { margin: 28px 0 0; padding: 18px 20px; background: rgba(0,0,0,.24); border: 1px solid var(--kante); border-radius: var(--r-gr); }
.notiz b { font-size: 14px; }
.notiz p { margin: 6px 0 12px; font-size: 14px; color: var(--tinte-72); }
code.link { display: block; margin-top: 8px; padding: 11px 13px; background: rgba(0,0,0,.4); border-radius: var(--r); font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12.5px; color: var(--marke-hell); word-break: break-all; }

/* ---- Liste im Verwaltungsbereich ---- */
.liste { width: 100%; border-collapse: collapse; margin-top: 22px; font-size: 14px; }
.liste th { text-align: left; font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--tinte-52); font-weight: 600; padding: 0 12px 10px 0; border-bottom: 1px solid var(--kante); }
.liste td { padding: 12px 12px 12px 0; border-bottom: 1px solid rgba(255,255,255,.05); vertical-align: top; }
.liste code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 13px; color: var(--marke-hell); }
.liste tr.ist-weg { opacity: .5; }
.liste form { margin: 0; }
@media (max-width: 640px) { .liste thead { display: none; } .liste td { display: block; border: 0; padding: 3px 0; } .liste tr { display: block; padding: 12px 0; border-bottom: 1px solid var(--kante); } }

/* ---- Fuss ---- */
.fuss { margin: 26px 0 0; font-size: 13.5px; color: var(--tinte-52); text-align: center; line-height: 1.8; }
a { color: var(--marke-hell); }

/* ---- Und jetzt? ----
   Dieselbe Bahn wie der Ablauf auf nexup.studio: eine Linie, Kreise darauf,
   die der Reihe nach pulsen. Werte, Verlaeufe, Schatten und der Puls sind
   unveraendert von dort uebernommen.

   Genommen ist die SENKRECHTE Fassung (auf der Website die fuer schmale
   Schirme): die vier Takte der Startseite tragen je einen Satz, hier stehen
   ganze Absaetze. Nebeneinander waeren das drei Spalten Kleingedrucktes. */
.bahn {
  --kreis: 44px;
  --bahn-rand: calc(var(--kreis) + clamp(14px, 4vw, 20px));
  position: relative;
  list-style: none;
  display: grid; grid-template-columns: minmax(0, 1fr);
  gap: clamp(26px, 5vw, 40px);
  margin: 0 0 30px; padding: 0 0 0 var(--bahn-rand);
}
/* Die Linie beginnt und endet weich. Eine Kante am Anfang saehe aus wie ein
   abgeschnittenes Kabel. */
.bahn::before {
  content: ""; position: absolute; left: calc(var(--kreis) / 2);
  top: 0; bottom: 0; width: 1px;
  background: linear-gradient(180deg,
    transparent, rgba(127,178,238,.50) 6%,
    rgba(127,178,238,.30) 74%, rgba(127,178,238,.10) 92%, transparent);
}
.takt { position: relative; min-width: 0; }
.takt-nr {
  position: absolute; left: calc(-1 * var(--bahn-rand)); top: .7em; translate: 0 -50%;
  display: grid; place-items: center;
  width: var(--kreis); height: var(--kreis); border-radius: 50%;
  background: linear-gradient(rgba(61,119,187,.20), rgba(61,119,187,.08)), rgba(9,13,20,.94);
  box-shadow: inset 0 0 0 1px rgba(127,178,238,.28), 0 0 14px 0 rgba(127,178,238,.11);
  font-size: 1rem; font-weight: 700; line-height: 1; letter-spacing: -.01em;
  color: var(--marke-hell);
  /* Der Puls laeuft versetzt durch die Kreise, gesteuert ueber --i am Takt.
     Gleichzeitig waere es ein Blinken, nacheinander ist es ein Weg. */
  animation: taktpuls 3.4s var(--ease) infinite;
  animation-delay: calc(var(--i, 0) * 420ms);
}
@keyframes taktpuls {
  0%, 100% { box-shadow: inset 0 0 0 1px rgba(127,178,238,.28),
             0 0 14px 0 rgba(127,178,238,.11), 0 0 0 0 rgba(127,178,238,.16); }
  55%      { box-shadow: inset 0 0 0 1px rgba(127,178,238,.46),
             0 0 16px 0 rgba(127,178,238,.17), 0 0 0 11px rgba(127,178,238,0); }
}
.takt h2 { margin: 0 0 6px; font-size: 17px; line-height: 1.3; }
.takt p { margin: 0 0 8px; color: var(--tinte-72); font-size: 15px; }
.takt p.klein { margin-top: 10px; }
@media (max-width: 430px) {
  .bahn { --kreis: 38px; }
  .takt-nr { font-size: .9rem; }
}
@media (prefers-reduced-motion: reduce) { .takt-nr { animation: none; } }

.notiz--warnung { border-color: rgba(217,166,79,.42); background: rgba(217,166,79,.10); }

/* ---- Kopierzeile ----
   Der Link ist 70 Zeichen lang. Am Handy markiert den niemand fehlerfrei,
   deshalb ein Knopf daneben statt der Hoffnung auf ruhige Finger. */
.linkzeile { display: flex; align-items: stretch; gap: 8px; margin-top: 8px; }
.linkzeile code.link { flex: 1 1 auto; margin-top: 0; }
.kopieren { flex: 0 0 auto; margin-top: 0; white-space: nowrap; align-self: stretch; }
.kopieren.hat-kopiert { color: var(--gut); border-color: rgba(63,178,127,.55); }
@media (max-width: 560px) { .linkzeile { flex-direction: column; } .kopieren { align-self: flex-start; } }
