/* ============================================================================
 * Gedup · Seitenstil
 * ----------------------------------------------------------------------------
 * Farben und Schrift sind dieselben wie in der App (src/ui/theme.ts). Wer von
 * hier in den Play Store und dann in die App geht, soll dreimal dasselbe
 * Produkt sehen — deshalb steht hier keine eigene Markenwelt, sondern die der
 * App noch einmal.
 *
 * Gelb ist Akzent und wird NIE zur Fläche. In der App ist die gelbe Flut der
 * Moment, in dem man es geschafft hat; würde hier ein Abschnitt gelb
 * grundiert, verpufft er.
 * ========================================================================== */

:root {
  --bone: #fbfaf7;
  --surface: #ffffff;
  --ink: #111111;
  --muted: #8a8579;
  --hair: #e6e4de;
  --indigo: #4b3bff;
  --yellow: #ffd23d;
  --on-indigo: #ffffff;
  --shadow: 0 24px 60px -32px rgba(17, 17, 17, 0.4);

  --measure: 62ch;
  --page: 1080px;
  --gutter: clamp(20px, 5vw, 48px);

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bone: #121110;
    --surface: #1c1a18;
    --ink: #f2efe8;
    --muted: #948e82;
    --hair: #2c2a26;
    --indigo: #6c5dff;
    --shadow: 0 24px 60px -32px rgba(0, 0, 0, 0.8);
  }
}

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

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
  /* Die gedrehten Geräte im Kopfbereich ragen absichtlich etwas über ihre
     Spalte hinaus. Ohne das hier schöbe das auf einem schmalen Bildschirm die
     ganze Seite seitwärts. */
  overflow-x: clip;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

/* --- Gerüst ------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

section {
  padding-block: clamp(64px, 11vw, 132px);
  border-top: 1px solid var(--hair);
}

section:first-of-type {
  border-top: 0;
}

/* Nach dem dunklen Band trennt schon der Farbwechsel, eine Linie wäre doppelt. */
.night + section {
  border-top: 0;
}

/* --- Typografie --------------------------------------------------------- */

h1,
h2,
h3 {
  text-wrap: balance;
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.08;
}

h1 {
  font-size: clamp(38px, 7vw, 68px);
}

h2 {
  font-size: clamp(28px, 4.4vw, 42px);
}

h3 {
  font-size: 19px;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

p {
  margin: 0;
  max-width: var(--measure);
}

.label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 18px;
}

.lead {
  font-size: clamp(17px, 1.9vw, 20px);
  color: var(--muted);
  margin-top: 22px;
}

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

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-block: 26px;
  border-bottom: 1px solid var(--hair);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
}

.brand-mark {
  width: 26px;
  height: 26px;
  /* Dieselbe Rundung wie auf dem Startbildschirm des Handys, damit die Marke
     hier und dort als dasselbe Zeichen gelesen wird. */
  border-radius: 8px;
  flex: none;
}

.top nav {
  display: flex;
  gap: clamp(14px, 3vw, 28px);
  font-size: 14px;
}

.top nav a {
  color: var(--muted);
  text-decoration: none;
}

.top nav a:hover,
.top nav a:focus-visible {
  color: var(--ink);
}

/* --- Nacht: der Kopfbereich der Startseite ---------------------------------

   Wie der Willkommens-Screen der App: immer dunkel, in beiden Modi, mit dem
   Polarlicht oben. Die Bewegungen stehen nicht hier, sondern kommen aus
   src/hero.mjs, nachgerechnet aus den Werten der App.

   Die Kopfzeile liegt auf der Startseite über dem Band, damit das Licht bis
   an den oberen Rand reicht wie in der App. */

.landing header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
}

.landing .top {
  border-bottom-color: rgba(255, 255, 255, 0.12);
}

.landing .brand {
  color: #ffffff;
}

.landing .top nav a {
  color: rgba(255, 255, 255, 0.7);
}

.landing .top nav a:hover,
.landing .top nav a:focus-visible {
  color: #ffffff;
}

.night {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* Die Mitte des Verlaufs steht sofort da, der Verlauf blendet ein wie in
     der App. Sonst spränge die untere Hälfte mit einem Schlag auf Schwarz. */
  background: #07051a;
  color: #ffffff;
  padding-top: calc(80px + clamp(32px, 7vw, 72px));
  padding-bottom: clamp(48px, 8vw, 96px);
}

.night::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background: linear-gradient(to bottom, #0e0a33 0%, #07051a 50%, #000000 100%);
}

/* Etwa ein Drittel der Höhe, ein Stück über den Rand geschoben, nach unten
   läuft es von selbst aus. Wie AuroraLight.tsx. */
.night-light {
  position: absolute;
  left: 0;
  top: -80px;
  z-index: -1;
  width: 100%;
  height: max(240px, 32vh);
  pointer-events: none;
  /* Der Shader lässt das Licht nach unten auslaufen, am Rand der Leinwand ist
     es aber noch nicht ganz weg. Im Browser stand dort eine gerade Kante. */
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
}

.hero-title {
  color: #ffffff;
}

.hero-title .w,
.hero-title .jump {
  display: inline-block;
}

/* Der Kasten, aus dem das Wort springt. Er schneidet ab, was noch unter der
   Zeile steckt. Innen- und Aussenabstand kommen aus src/hero.mjs. */
.hero-title .clip {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}

/* Lavendel nach Violett, die Farben des Polarlichts. In der App bekommt jeder
   Buchstabe eine Farbe, im Browser geht der echte Verlauf. */
.hero-title .accent {
  background: linear-gradient(90deg, #c9bdff, #8a6bff);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.night .lead {
  color: rgba(255, 255, 255, 0.85);
}

.night .cta-soon {
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.22);
}

.night .cta-dot {
  background: #8a6bff;
}

.night .cta-note {
  color: rgba(255, 255, 255, 0.6);
}

/* --- Titelbereich ------------------------------------------------------- */

.hero {
  display: grid;
  gap: clamp(44px, 7vw, 72px);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .hero {
    grid-template-columns: 1.05fr 0.95fr;
  }
}

.cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 34px;
  padding: 15px 26px;
  border-radius: 999px;
  background: var(--indigo);
  color: var(--on-indigo);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

/* Solange es den Store-Eintrag nicht gibt, steht hier kein Knopf. Ein Knopf,
   der nichts tut oder woandershin springt, ist der erste gebrochene Handschlag
   der Seite — also eine Auskunft im selben Rahmen, sichtbar nicht anklickbar. */
.cta-soon {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hair);
  cursor: default;
}

.cta-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--indigo);
  flex: none;
}

/* App Store und Google Play nebeneinander. Das Abzeichen ist Apples eigenes
   und bleibt unverändert, nur seine Höhe passt sich dem Knopf daneben an. */
.stores {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 34px;
}

.stores .cta {
  margin-top: 0;
  min-height: 48px;
  box-sizing: border-box;
}

.store-badge {
  display: inline-flex;
  border-radius: 8px;
}

.store-badge img {
  display: block;
  height: 48px;
  width: auto;
}

.store-badge:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: 3px;
}

.cta-note {
  font-size: 14px;
  color: var(--muted);
  margin-top: 14px;
}

/* --- Der Missionskranz -------------------------------------------------- */

/* Derselbe Kranz wie auf der Paywall der App. Die Verhältnisse stammen aus
   src/billing/MissionRing.tsx und stehen hier in Prozent, damit er mitwächst.

   Drei Ebenen, und jede hat einen Grund:

     .ring         steht still und trägt den Kern
     .ring-orbit   dreht sich, und mit ihr wandern die Kacheln
     .ring-plinth  dreht gegenläufig, damit die Figuren aufrecht bleiben

   Ohne die dritte Ebene stünde der Liegestütz irgendwann auf dem Kopf, und
   dann liest er sich nicht mehr als Liegestütz — dieselbe Überlegung, aus der
   die Kacheln in der App gar nicht erst mitgedreht werden. Der Wecker in der
   Mitte bleibt aussen vor, denn er ist das, worum die Missionen kreisen. */

.ring {
  justify-self: center;
  width: min(360px, 76vw);
  aspect-ratio: 1;
  position: relative;
}

.ring-orbit {
  position: absolute;
  inset: 0;
}

.ring-tile {
  position: absolute;
  width: 18.518%;
  height: 18.518%;
}

.ring-plinth {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  /* Ohne Sockel. Bis zum 17.09.2026 stand hier ein helles Quadrat, weil fünf
     der Figuren eine hell gerenderte Bodenscheibe mitbrachten und im Dunkeln
     sonst in einem leuchtenden Fleck standen. Die Scheibe ist inzwischen aus
     den Bildern heraus, also steht jedes Symbol frei. */
}

.ring-plinth picture,
.ring-plinth img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Indigo, weil in der Mitte der Wecker steht und nicht eine Mission. */
.ring-core {
  position: absolute;
  left: 29.63%;
  top: 29.63%;
  width: 40.74%;
  height: 40.74%;
  border-radius: 50%;
  background: var(--indigo);
  display: grid;
  place-items: center;
}

.ring-core img {
  width: 58%;
  height: 58%;
  object-fit: contain;
}

/* Ohne JavaScript steht der Kranz einfach da. Erst die Klasse `js` macht ihn
   unsichtbar, und erst `is-in` — vom Beobachter beim Hineinscrollen gesetzt —
   lässt ihn auftreten. So sieht niemand eine leere Fläche, wenn das Skript
   nicht läuft. */

.js .ring-tile {
  opacity: 0;
  animation: ring-in 320ms cubic-bezier(0.215, 0.61, 0.355, 1) var(--d) forwards;
  animation-play-state: paused;
}

.js .ring-orbit {
  animation: ring-spin 48s linear infinite;
  animation-play-state: paused;
}

.js .ring-plinth {
  animation: ring-spin-back 48s linear infinite;
  animation-play-state: paused;
}

.js .ring.is-in .ring-tile,
.js .ring.is-in .ring-orbit,
.js .ring.is-in .ring-plinth {
  animation-play-state: running;
}

@keyframes ring-in {
  from {
    opacity: 0;
    transform: scale(0.7);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes ring-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes ring-spin-back {
  to {
    transform: rotate(-360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .js .ring-tile {
    opacity: 1;
    animation: none;
  }

  .js .ring-orbit,
  .js .ring-plinth {
    animation: none;
  }
}

/* --- Schritte ----------------------------------------------------------- */

/* Vier Geraete nebeneinander, in der Reihenfolge eines Morgens. Eine <ol>,
   weil es wirklich eine Reihenfolge ist — die Nummern sind keine Verzierung. */
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(14px, 2.4vw, 30px);
  margin-top: 8px;
  padding: 0;
  list-style: none;
}

/* Nummer und Titel stehen ueber dem Geraet: Wer die Reihe ueberfliegt, liest
   erst, worum es geht, und sieht dann das Bild dazu. */
.step-num {
  font-size: 12px;
  font-weight: 700;
  color: var(--indigo);
  letter-spacing: 0.08em;
  margin: 0 0 6px;
}

.step h3 {
  font-size: clamp(14px, 1.3vw, 16px);
  line-height: 1.35;
  margin: 0 0 16px;
  text-wrap: balance;
  /* Vier Titel unterschiedlicher Laenge wuerden die Geraete sonst auf vier
     verschiedenen Hoehen beginnen lassen. */
  min-height: 2.7em;
}

/* Auf dem Handy passen vier Geraete nicht nebeneinander, ohne dass jedes zum
   Daumennagel wird. Dann werden sie zu einem Streifen, den man wischt — und er
   laeuft bis an den Rand, damit sichtbar ist, dass rechts noch etwas kommt. */
@media (max-width: 760px) {
  .steps {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 58%;
    gap: 16px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    /* Ohne das rastet das erste Bild an der Bildschirmkante ein und nicht am
       Seitenrand. Das Einrasten kennt den Innenabstand sonst nicht. */
    scroll-padding-inline: var(--gutter);
    padding-bottom: 8px;
    overscroll-behavior-x: contain;
  }

  .step {
    scroll-snap-align: start;
  }
}

/* --- Bildschirmfotos ---------------------------------------------------- */

.shot {
  margin: 0;
}

/* Zwei Geräte im Kopfbereich, leicht gegeneinander gedreht.
   Beide liegen in derselben Rasterzelle und werden nur verschoben — so
   bestimmt das höhere von beiden die Höhe, und es braucht keine festen
   Masse, die auf einem schmalen Bildschirm brechen. */

.pair {
  display: flex;
  align-items: center;
  justify-content: center;
  justify-self: center;
  width: min(480px, 100%);
  margin-block: 18px;
}

.pair .shot {
  width: 48%;
  max-width: 230px;
}

/* Sie überlappen sich nur um rund ein Zehntel ihrer Breite. Genug, dass die
   beiden als Paar zusammengehören, und wenig genug, dass man auf jedem noch
   alles erkennt — das Vordere darf das Hintere nicht zudecken, sonst zeigt
   man zwei Geräte und kann nur eines lesen. */
.pair .shot:first-child {
  transform: rotate(-6deg) translateY(14px);
  margin-right: -5%;
  z-index: 1;
}

.pair .shot:last-child {
  transform: rotate(4deg);
  z-index: 2;
}

.shot img {
  width: 100%;
  height: auto;
  /* Die Bilder sind iPhone-Mockups mit eigenem Rahmen und durchsichtigem Grund,
     deshalb ohne Kante und ohne Schatten. Ein drop-shadow am Bild zeichnet in
     Safari zusammen mit der Maske einen hellen Kasten, einer am umgebenden
     Element wird in der wischbaren Reihe unten hart abgeschnitten. */
  /* Die Mockups enden unten mitten im Gerät. Ausgeblendet liest sich das als
     Absicht und nicht als abgeschnitten. */
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);
}

/* Ganze Bildschirmaufnahmen, das Gerät kommt aus dem CSS. Im Kopfbereich
   liegen zwei davon übereinander. Eine Ausblendung wie bei den Mockups liesse
   dort das hintere Gerät durch das vordere scheinen. */
.shot--framed img {
  -webkit-mask-image: none;
  mask-image: none;
  box-sizing: border-box;
  /* Die Rundung des Displays: 13 % der Breite, bei dieser Höhe gleich weit. */
  border-radius: 13% / 6%;
  border: 6px solid #0b0b0c;
  background: #000000;
  /* Eine feine helle Kante als Gehäuse, sonst verschwindet das dunkle Gerät
     auf dem dunklen Band. */
  box-shadow:
    0 0 0 1.5px #55555c,
    0 40px 80px -30px rgba(0, 0, 0, 0.7);
}

.shot figcaption {
  margin-top: 14px;
  font-size: 14px;
  color: var(--muted);
  max-width: 34ch;
}

.names {
  margin-top: 40px;
  font-size: 14px;
  color: var(--muted);
  max-width: none;
}

.split {
  display: grid;
  gap: clamp(36px, 6vw, 64px);
  align-items: center;
  grid-template-columns: 1fr;
}

.split--ring {
  margin-top: 52px;
}

.split--ring .ring {
  width: min(320px, 72vw);
}

@media (min-width: 860px) {
  .split {
    grid-template-columns: 1.1fr 0.9fr;
  }

  .split .shot {
    max-width: 300px;
    justify-self: end;
  }

  .split--ring {
    grid-template-columns: 1fr 1fr;
  }

  .split--ring .shot {
    max-width: 260px;
  }
}

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

footer {
  border-top: 1px solid var(--hair);
  padding-block: 48px 64px;
  font-size: 14px;
  color: var(--muted);
}

.foot-cols {
  display: grid;
  gap: 32px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

footer h2 {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}

footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

footer a {
  color: var(--ink);
  text-decoration-color: var(--hair);
  text-underline-offset: 3px;
}

.foot-note {
  margin-top: 40px;
  padding-top: 24px;
  border-top: 1px solid var(--hair);
  font-size: 13px;
  max-width: none;
}

/* --- Rechtsseiten ------------------------------------------------------- */

.doc {
  padding-block: clamp(56px, 8vw, 96px);
  max-width: calc(var(--measure) + 4ch);
}

.doc h1 {
  font-size: clamp(32px, 5vw, 46px);
}

.doc-meta {
  margin-top: 16px;
  font-size: 14px;
  color: var(--muted);
}

.doc section {
  border: 0;
  padding-block: 0;
  margin-top: 44px;
}

.doc h2 {
  font-size: 21px;
  letter-spacing: -0.01em;
  margin-bottom: 14px;
}

/* Nur das Impressum hat eine dritte Ebene: die Anschrift unter „Kontakt". */
.doc h3 {
  font-size: 16px;
  margin-top: 0;
  margin-bottom: 6px;
}

.doc p {
  margin-top: 14px;
  color: var(--muted);
  font-size: 16px;
}

.doc p:first-of-type {
  margin-top: 0;
}

/* --- Zugänglichkeit ----------------------------------------------------- */

a:focus-visible,
.cta:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: 3px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

/* --- Häufige Fragen ----------------------------------------------------- */

/* Aufklappbar mit <details>, ohne eine Zeile JavaScript. Der Text steht
   trotzdem im Dokument: Suchmaschinen lesen ihn, und der Browser findet ihn
   beim Suchen auf der Seite auch dann, wenn der Block zu ist. */

.faq-head {
  text-align: center;
}

.faq-head p,
.faq-head h2 {
  margin-inline: auto;
}

.faq {
  max-width: 720px;
  margin: 48px auto 0;
  border-top: 1px solid var(--hair);
}

.qa {
  border-bottom: 1px solid var(--hair);
}

.qa summary {
  list-style: none;
  cursor: pointer;
  padding: 22px 40px 22px 0;
  font-size: 17px;
  font-weight: 500;
  position: relative;
}

.qa summary::-webkit-details-marker {
  display: none;
}

/* Ein Kreuz, das beim Aufklappen zum Minus wird. Zwei Striche statt eines
   Zeichens, damit es in jeder Schrift gleich sitzt. */
.qa summary::before,
.qa summary::after {
  content: '';
  position: absolute;
  right: 4px;
  top: 50%;
  width: 13px;
  height: 2px;
  background: var(--muted);
  border-radius: 2px;
  transition: transform 200ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

.qa summary::before {
  transform: translateY(-50%);
}

.qa summary::after {
  transform: translateY(-50%) rotate(90deg);
}

.qa[open] summary::after {
  transform: translateY(-50%) rotate(0deg);
}

.qa[open] summary {
  color: var(--ink);
}

.qa-body {
  overflow: hidden;
  transition: height 260ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

.qa p {
  color: var(--muted);
  font-size: 16px;
  padding-bottom: 24px;
  max-width: none;
}
