/* Self-hosted fonts (no Google Fonts connection, DSGVO-friendly).
   Cinzel is a variable font covering weights 400-900 in one file. */

@font-face {
  font-family: "Cinzel";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("fonts/cinzel.woff2") format("woff2");
}

@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/spectral-300.woff2") format("woff2");
}

@font-face {
  font-family: "Spectral";
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url("fonts/spectral-300-italic.woff2") format("woff2");
}

@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/spectral-400.woff2") format("woff2");
}

@font-face {
  font-family: "Spectral";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/spectral-500.woff2") format("woff2");
}

/* Mathemagie design system — "arcane observatory"
   Palette from the magicmath "mage-wars-arena" art direction:
   deep arcane azure, regal violet shadows, warm gold accents on night blue.
   Type: Cinzel (engraved display caps) + Spectral (bookish body serif). */

:root {
  --bg: #080a16;
  --bg-raised: #0e1124;
  --card: rgba(19, 23, 48, 0.55);
  --ink: #0f0c1d;

  --hairline: rgba(232, 176, 75, 0.16);
  --hairline-strong: rgba(232, 176, 75, 0.4);
  --border: rgba(255, 255, 255, 0.07);

  --azure: #4f7cff;
  --cyan: #4fc8ff;
  --violet: #8b5cf6;
  --violet-soft: #b5a0f5;
  --gold: #e8b04b;
  --gold-soft: #f3cd8a;
  --gold-deep: #b97f2a;

  /* Glow-Varianten der Akzentfarben; stehen hier, damit Farbe und Schein
     zusammen gepflegt werden und nicht auseinanderlaufen. */
  --azure-glow: rgba(79, 124, 255, 0.35);
  --cyan-glow: rgba(79, 200, 255, 0.3);
  --violet-glow: rgba(139, 92, 246, 0.3);
  --gold-glow: rgba(232, 176, 75, 0.3);

  --text: #ece9f4;
  --text-muted: #a7a5c0;
  --text-faint: #8583a8;

  --font-display: "Cinzel", "Times New Roman", serif;
  --font-body: "Spectral", Georgia, serif;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

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

html {
  scroll-behavior: smooth;
}

body {
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 300;
  line-height: 1.7;
  min-height: 100vh;
  overflow-x: hidden;
  background-image:
    radial-gradient(ellipse 75% 55% at 18% -8%, rgba(79, 124, 255, 0.13) 0%, transparent 60%),
    radial-gradient(ellipse 65% 50% at 88% 2%, rgba(139, 92, 246, 0.12) 0%, transparent 60%),
    radial-gradient(ellipse 55% 45% at 50% 115%, rgba(232, 176, 75, 0.07) 0%, transparent 60%);
  background-attachment: fixed;
}

/* Film grain over everything, very faint */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
}

.wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

a {
  color: var(--violet-soft);
  text-decoration: none;
  transition: color 0.25s var(--ease);
}

a:hover {
  color: var(--gold-soft);
}

::selection {
  background: rgba(139, 92, 246, 0.4);
  color: #fff;
}

/* ---------- Topbar ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(8, 10, 22, 0.82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hairline);
}

.topbar .inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0.95rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.logo {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.logo img {
  width: 32px;
  height: 32px;
}

.logo:hover {
  color: var(--gold-soft);
}

.nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

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

.nav a:hover {
  color: var(--gold-soft);
}

/* ---------- Erster Block ----------

   Die Seite faengt mit dem Rad an; der Kopf davor ist in dessen Ueberschrift
   aufgegangen. Was vom Kopf bleibt, ist sein Sternenhimmel. */

/* Beide Klassen im Selektor: section.block setzt padding als Kurzform und steht
   weiter unten im Stylesheet. Mit nur einer Klasse bliebe der Abstand nach oben
   wirkungslos, mit section.block-oben stuende es gleich und die spaetere Regel
   gewaenne. */
.block.block-oben {
  position: relative;
  padding-top: 4.5rem;
  overflow: hidden;
}

.block-oben::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    radial-gradient(circle 1.4px at 12% 22%, rgba(255, 255, 255, 0.7) 0%, transparent 100%),
    radial-gradient(circle 1px at 28% 68%, rgba(255, 255, 255, 0.45) 0%, transparent 100%),
    radial-gradient(circle 1.8px at 44% 12%, rgba(243, 205, 138, 0.7) 0%, transparent 100%),
    radial-gradient(circle 1px at 61% 80%, rgba(255, 255, 255, 0.4) 0%, transparent 100%),
    radial-gradient(circle 1.3px at 76% 30%, rgba(181, 160, 245, 0.7) 0%, transparent 100%),
    radial-gradient(circle 1px at 88% 64%, rgba(255, 255, 255, 0.5) 0%, transparent 100%),
    radial-gradient(circle 1.6px at 7% 84%, rgba(181, 160, 245, 0.55) 0%, transparent 100%),
    radial-gradient(circle 1px at 94% 10%, rgba(243, 205, 138, 0.6) 0%, transparent 100%);
}

.block-oben .wrap {
  position: relative;
  z-index: 1;
}

/* ---------- Bewegung ---------- */

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

@keyframes pulse {
  0%,
  100% {
    opacity: 0.5;
    transform: scale(1);
  }
  50% {
    opacity: 0.9;
    transform: scale(1.05);
  }
}

/* ---------- Buttons ---------- */

.btn {
  /* inline-flex statt inline-block wegen des .btn-arrow neben dem Label;
     die Buttons umschliessen ihren Inhalt, die Zentrierung aendert darum
     nichts an ihrer Darstellung. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  padding: 0.85rem 2rem;
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  transition: all 0.3s var(--ease);
}

.btn-primary {
  color: var(--ink);
  background: linear-gradient(160deg, var(--gold-soft) 0%, var(--gold) 45%, var(--gold-deep) 100%);
  border: 1px solid rgba(243, 205, 138, 0.5);
  box-shadow: 0 4px 28px rgba(232, 176, 75, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.btn-arrow {
  display: inline-block;
  transition: transform 0.3s var(--ease);
  line-height: 1;
}

.drop-cta:hover .btn-arrow {
  transform: translateX(5px);
}

.btn-primary:hover {
  color: var(--ink);
  transform: translateY(-2px);
  box-shadow: 0 8px 36px rgba(232, 176, 75, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.btn-ghost {
  color: var(--text);
  border: 1px solid rgba(139, 92, 246, 0.45);
  background: rgba(139, 92, 246, 0.06);
}

.btn-ghost:hover {
  color: var(--gold-soft);
  border-color: var(--hairline-strong);
  background: rgba(232, 176, 75, 0.06);
}

/* ---------- Rune divider ---------- */

.rune-divider {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1.5rem;
  color: var(--gold);
  font-size: 1rem;
}

.rune-divider::before,
.rune-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline-strong), transparent);
}

/* ---------- Sections ---------- */

section.block {
  padding: 5.5rem 0;
}

.section-head {
  max-width: 620px;
  margin: 0 0 3.5rem;
}

.section-head .num {
  font-family: var(--font-display);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--gold);
  display: block;
  margin-bottom: 0.9rem;
}

.section-head h2 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.5vw, 2.6rem);
  font-weight: 500;
  margin-bottom: 0.9rem;
}

/* Nur der erste Block traegt den Namen der Seite; .section-head selbst bleibt
   neutral, andere Seiten teilen ihn sich. */
.block-oben .section-head h1 {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 5vw, 3.8rem);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: 0.015em;
  margin-bottom: 1.1rem;
}

.block-oben .section-head h1 .gradient {
  background: linear-gradient(100deg, var(--gold-soft) 0%, var(--gold) 40%, var(--violet-soft) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.section-head p {
  color: var(--text-muted);
  font-size: 1.08rem;
}

.section-head p em {
  color: var(--gold-soft);
  font-style: italic;
}

/* Der Hinweis steht fuer sich, damit er nicht mit dem Satz davor zu einem
   langen goldenen Block verlaeuft. */
.wheel-hint {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.98rem;
}

.section-head-center {
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* ---------- Rad der vier Welten ----------

   Ein Kreis aus vier Wassertropfen um eine glaeserne Kugel. Alle Positionen
   sind Prozentwerte von inset, nicht Transformationen: das Rad muss auch
   stehen, wenn prefers-reduced-motion jede Transformation abschaltet. */

.wheel {
  --orbit-time: 110s;
  position: relative;
  width: min(820px, 100%);
  margin: 0 auto;
  aspect-ratio: 1;
}

.wheel-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.wheel-aura,
.wheel-runes-ring {
  transform-origin: 400px 400px;
}

.wheel-aura {
  animation: spin 240s linear infinite;
}

.wheel-runes-ring {
  animation: spin 150s linear infinite reverse;
}

.wheel-runes {
  font-family: Georgia, serif;
  font-size: 19px;
  letter-spacing: 7px;
  fill: rgba(243, 205, 138, 0.5);
}

/* ---------- Die Kugel in der Mitte ---------- */

.wheel-hub {
  position: absolute;
  inset: 25%;
  z-index: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  padding: 12%;
  text-align: center;
  background:
    radial-gradient(circle at 32% 24%, rgba(255, 255, 255, 0.16) 0%, transparent 45%),
    radial-gradient(circle at 72% 82%, rgba(79, 124, 255, 0.2) 0%, transparent 60%),
    radial-gradient(circle at 50% 45%, rgba(24, 28, 58, 0.9) 0%, rgba(8, 10, 22, 0.97) 100%);
  border: 1px solid rgba(232, 176, 75, 0.24);
  box-shadow:
    inset 0 3px 30px rgba(255, 255, 255, 0.12),
    inset 0 -36px 70px rgba(0, 0, 0, 0.55),
    inset 0 0 0 1px rgba(255, 255, 255, 0.04),
    0 34px 90px rgba(0, 0, 0, 0.55),
    0 0 100px rgba(139, 92, 246, 0.16);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  color: var(--text);
  text-decoration: none;
}

/* Glanzlicht wie auf einer Glaskugel */
.wheel-hub::before {
  content: "";
  position: absolute;
  left: 16%;
  top: 10%;
  width: 34%;
  height: 20%;
  border-radius: 50%;
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0));
  filter: blur(6px);
  pointer-events: none;
}

.hub-face {
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: opacity 0.45s var(--ease);
}

.hub-emblem {
  width: clamp(104px, 19vw, 152px);
  height: clamp(104px, 19vw, 152px);
  filter: drop-shadow(0 0 30px rgba(232, 176, 75, 0.25));
}

.hub-star {
  transform-origin: 100px 100px;
  animation: spin 180s linear infinite;
}

.hub-pulse {
  transform-origin: 100px 100px;
  animation: pulse 7s ease-in-out infinite;
}

.hub-sigil {
  font-family: Georgia, serif;
  font-size: 74px;
  font-style: italic;
  fill: url(#hubCore);
}

/* Der Weg zur Galerie. Steht tief in der Kugel, damit er auch dann sichtbar
   bleibt, wenn in ihrer Mitte gerade die Tafel eines Spiels liegt. */
.hub-gallery {
  position: absolute;
  bottom: 9%;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
  transition: color 0.3s var(--ease);
}

.wheel-hub:hover .hub-gallery {
  color: var(--gold-soft);
}

.wheel-hub:hover .btn-arrow {
  transform: translateX(4px);
}

.wheel-hub:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 6px;
}

/* ---------- Die Tropfen ---------- */

.wheel-drops {
  position: absolute;
  inset: 0;
  z-index: 3;
  list-style: none;
  /* Die Listenelemente liegen deckungsgleich ueber dem ganzen Rad, damit ihre
     Texttafeln in der Kugelmitte sitzen koennen. Klickbar ist darum nur, was
     pointer-events wieder einschaltet. */
  pointer-events: none;
}

.drop {
  position: absolute;
  inset: 0;
}

/* Die Bahn: diese Ebene deckt das ganze Rad ab und dreht sich um dessen Mitte,
   der Tropfen darin dreht sich gegenlaeufig zurueck und bleibt so aufrecht.
   Gedreht wird ueber rotate statt transform, damit der Tropfen daneben noch
   frei skalieren kann. Die vier Bahnen starten gemeinsam und halten damit
   ihren Abstand von einer Vierteldrehung. */
.drop-orbit {
  position: absolute;
  inset: 0;
  animation: orbit var(--orbit-time) linear infinite;
}

.drop-bubble {
  animation: orbit-back var(--orbit-time) linear infinite;
}

/* Wer sich dem Rad naehert, haelt es an: auf ein wanderndes Ziel zu klicken
   waere eine Zumutung. */
.wheel:hover .drop-orbit,
.wheel:hover .drop-bubble,
.wheel:focus-within .drop-orbit,
.wheel:focus-within .drop-bubble {
  animation-play-state: paused;
}

@keyframes orbit {
  to {
    rotate: 360deg;
  }
}

@keyframes orbit-back {
  to {
    rotate: -360deg;
  }
}

.drop-bubble {
  --accent: var(--hairline-strong);
  --accent-glow: rgba(139, 92, 246, 0.18);
  /* Luftblasen im Wasser; liegen als oberste Ebene ueber der Welt des Spiels
     und stehen hier, damit jede Kugel dieselben bekommt. */
  --bubbles:
    radial-gradient(circle 4px at 71% 27%, rgba(255, 255, 255, 0.5) 0%, transparent 100%),
    radial-gradient(circle 2.5px at 63% 39%, rgba(255, 255, 255, 0.38) 0%, transparent 100%),
    radial-gradient(circle 3px at 33% 72%, rgba(255, 255, 255, 0.26) 0%, transparent 100%),
    radial-gradient(circle 2px at 47% 85%, rgba(255, 255, 255, 0.22) 0%, transparent 100%);
  position: absolute;
  border-radius: 50%;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 12%;
  text-align: center;
  color: var(--text);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow:
    inset 0 3px 18px rgba(255, 255, 255, 0.3),
    inset 0 -22px 40px rgba(0, 0, 0, 0.45),
    0 20px 45px rgba(0, 0, 0, 0.5),
    0 0 45px var(--accent-glow);
  transition: scale 0.45s var(--ease), box-shadow 0.45s var(--ease),
    opacity 0.45s var(--ease), filter 0.45s var(--ease);
}

/* Glanzlicht */
.drop-bubble::before {
  content: "";
  position: absolute;
  left: 17%;
  top: 13%;
  width: 32%;
  height: 20%;
  border-radius: 50%;
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0));
  filter: blur(3px);
  pointer-events: none;
}

/* Welle, die beim Zeigen aus dem Tropfen laeuft. Ohne Animation bleibt sie
   unsichtbar, damit bei reduzierter Bewegung kein starrer Ring stehenbleibt. */
.drop-bubble::after {
  content: "";
  position: absolute;
  inset: -8px;
  border: 1px solid var(--accent);
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
}

.drop-bubble:hover::after,
.drop-bubble:focus-visible::after {
  animation: ripple 2.4s var(--ease) infinite;
}

.drop-bubble:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 6px;
}

@keyframes ripple {
  0% {
    opacity: 0.55;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(1.22);
  }
}

/* Die Welt im Tropfen: Bildschirme aus dem Build des Spiels, vom Skript
   nachgereicht und gegeneinander ausgeblendet. Ohne Skript oder ohne
   hochgeladene Bilder bleibt es beim Farbverlauf darunter. */
.drop-shot {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-position: 50% 30%;
  background-size: cover;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.4s var(--ease);
  /* Zum Rand hin auslaufen, damit das Bild in der Kugel schwebt, statt sie
     auszufuellen und ihre Glaskante zu ueberdecken. */
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 42%, transparent 76%);
  mask-image: radial-gradient(circle at 50% 50%, #000 42%, transparent 76%);
}

.drop-shot.is-on {
  opacity: 0.62;
}

/* Schleier, damit Zeichen und Name auf jedem Bildschirm lesbar bleiben. */
.drop-shot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(circle at 50% 50%, rgba(8, 10, 22, 0.55) 0%, rgba(8, 10, 22, 0.15) 70%);
}

.drop-glyph,
.drop-name {
  position: relative;
  z-index: 1;
}

.drop-glyph {
  font-family: Georgia, serif;
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  line-height: 1;
  color: rgba(255, 255, 255, 0.95);
  text-shadow: 0 0 34px rgba(243, 205, 138, 0.55), 0 4px 24px rgba(0, 0, 0, 0.5);
}

.drop-name {
  font-family: var(--font-display);
  font-size: clamp(0.7rem, 1.1vw, 0.82rem);
  font-weight: 600;
  letter-spacing: 0.18em;
  line-height: 1.35;
  text-transform: uppercase;
  -webkit-hyphens: auto;
  hyphens: auto;
}

/* Vier Plaetze auf dem Rad: der Tropfen ist 27% gross und sitzt 31% neben der
   Mitte, seine Mitte damit genau auf dem Reif. */
.drop-magicmath .drop-bubble {
  inset: 5.5% 67.5% 67.5% 5.5%;
}

.drop-mathinvaders .drop-bubble {
  inset: 5.5% 5.5% 67.5% 67.5%;
}

.drop-akademie .drop-bubble {
  inset: 67.5% 5.5% 5.5% 67.5%;
}

.drop-kreaturenjaeger .drop-bubble {
  inset: 67.5% 67.5% 5.5% 5.5%;
}

/* Die Welt im Tropfen: gleiche Farbwelt wie im jeweiligen Spiel. */
.drop-magicmath .drop-bubble {
  --accent: var(--azure);
  --accent-glow: var(--azure-glow);
  background:
    var(--bubbles),
    radial-gradient(ellipse 80% 70% at 28% 18%, rgba(255, 255, 255, 0.25) 0%, transparent 55%),
    radial-gradient(ellipse 85% 85% at 78% 84%, rgba(79, 124, 255, 0.55) 0%, transparent 62%),
    linear-gradient(150deg, #2b2060 0%, #45287f 55%, #170f38 100%);
}

.drop-mathinvaders .drop-bubble {
  --accent: var(--cyan);
  --accent-glow: var(--cyan-glow);
  background:
    var(--bubbles),
    radial-gradient(ellipse 80% 70% at 28% 18%, rgba(255, 255, 255, 0.25) 0%, transparent 55%),
    radial-gradient(ellipse 85% 85% at 76% 86%, rgba(79, 200, 255, 0.42) 0%, transparent 60%),
    linear-gradient(160deg, #12245a 0%, #1d2c6e 55%, #090f2b 100%);
}

.drop-akademie .drop-bubble {
  --accent: var(--gold);
  --accent-glow: var(--gold-glow);
  background:
    var(--bubbles),
    radial-gradient(ellipse 80% 70% at 28% 18%, rgba(255, 255, 255, 0.25) 0%, transparent 55%),
    radial-gradient(ellipse 85% 85% at 74% 84%, rgba(232, 176, 75, 0.45) 0%, transparent 60%),
    linear-gradient(145deg, #17324f 0%, #123b52 55%, #0a1728 100%);
}

.drop-kreaturenjaeger .drop-bubble {
  --accent: var(--violet);
  --accent-glow: var(--violet-glow);
  background:
    var(--bubbles),
    radial-gradient(ellipse 80% 70% at 28% 18%, rgba(255, 255, 255, 0.25) 0%, transparent 55%),
    radial-gradient(ellipse 85% 85% at 76% 84%, rgba(150, 74, 130, 0.45) 0%, transparent 60%),
    linear-gradient(150deg, #2c1840 0%, #3a1c3f 55%, #120a1e 100%);
}

/* ---------- Die Tafel in der Kugel ---------- */

/* Der Text sitzt in einem Quadrat, das der Kugel einbeschrieben ist: bei einer
   Kugel von 50% Raddurchmesser passt hoechstens ein Feld von 35%. */
.drop-detail {
  position: absolute;
  inset: 32.5%;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  text-align: center;
}

.detail-name {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.9vw, 1.35rem);
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.25;
  -webkit-hyphens: auto;
  hyphens: auto;
}

.drop-detail p {
  color: var(--text-muted);
  font-size: clamp(0.86rem, 1.3vw, 0.95rem);
  line-height: 1.55;
}

/* ---------- Choreografie am grossen Schirm ----------

   Nur fuer Zeigegeraete, die ueberfahren koennen. Ein Tablet im Querformat ist
   breit genug fuer das Rad, hat aber kein Ueberfahren: dort wuerde die Tafel
   nie erscheinen, und die Beschreibungen waeren unerreichbar. Diese Abfrage und
   die des aufgerollten Rads schliessen einander genau aus. */

@media (min-width: 861px) and (hover: hover) and (pointer: fine) {
  .drop-cta {
    display: none;
  }

  .drop-detail {
    opacity: 0;
    pointer-events: none;
    /* Die kurze Verzoegerung gilt dem Verschwinden: rutscht der Zeiger von der
       Kugel ab, ist der Text nicht sofort weg. Den langen Nachlauf uebernimmt
       weiter unten das Skript. */
    transition: opacity 0.4s var(--ease) 0.35s;
  }

  /* Ohne Skript zeigt die Kugel ihre Welt, solange der Zeiger auf ihr liegt. */
  .drop:hover .drop-detail,
  .drop:focus-within .drop-detail {
    opacity: 1;
    transition-delay: 0s;
  }

  .wheel-drops:hover .drop:focus-within .drop-detail {
    opacity: 0;
  }

  .wheel-drops:hover .drop:hover .drop-detail {
    opacity: 1;
  }

  /* Der gezeigte Tropfen tritt hervor, die anderen treten zurueck. */
  .wheel-drops:hover .drop-bubble,
  .wheel-drops:focus-within .drop-bubble {
    opacity: 0.4;
  }

  .drop:hover .drop-bubble,
  .drop:focus-within .drop-bubble {
    opacity: 1;
    scale: 1.07;
    filter: brightness(1.08);
    box-shadow:
      inset 0 3px 18px rgba(255, 255, 255, 0.35),
      inset 0 -22px 40px rgba(0, 0, 0, 0.4),
      0 26px 60px rgba(0, 0, 0, 0.55),
      0 0 70px var(--accent-glow);
  }

  /* Das Wappen weicht der Tafel des gezeigten Spiels. */
  .wheel-drops:hover ~ .wheel-hub .hub-face,
  .wheel-drops:focus-within ~ .wheel-hub .hub-face,
  .wheel.hat-aktiv .hub-face {
    opacity: 0;
  }

  /* ---------- Nachlauf, sobald das Skript laeuft ----------

     Die gewaehlte Welt bleibt fuenf Sekunden stehen, auch wenn der Zeiger die
     Kugel laengst verlassen hat. Welche das ist, merkt sich das Skript in einer
     Klasse; als blosse Verzoegerung im Uebergang ging es nicht: laeuft beim
     Scrollen eine zweite Kugel unter den Zeiger, bricht das Ausblenden der
     ersten auf halbem Weg ab und friert sichtbar ein. */
  .wheel.js .drop .drop-detail {
    opacity: 0;
  }

  .wheel.js .drop.is-aktiv .drop-detail {
    opacity: 1;
    transition-delay: 0s;
  }

  .wheel.js .drop-bubble {
    opacity: 1;
    scale: none;
    filter: none;
  }

  .wheel.js.hat-aktiv .drop-bubble {
    opacity: 0.4;
  }

  .wheel.js .drop.is-aktiv .drop-bubble {
    opacity: 1;
    scale: 1.07;
    filter: brightness(1.08);
  }

  /* Das Rad haelt an, solange eine Welt gewaehlt ist. */
  .wheel.hat-aktiv .drop-orbit,
  .wheel.hat-aktiv .drop-bubble {
    animation-play-state: paused;
  }
}

/* ---------- Aufgerolltes Rad am kleinen Schirm ----------

   Aufgerollt wird auch auf breiten Geraeten ohne feines Zeigegeraet: dort
   fuehrt jede Beruehrung einer Kugel sofort ins Spiel, die Tafel in der Mitte
   bekaeme niemand zu sehen.

   Die Abfrage ist wortwoertlich die Verneinung der Choreografie oben, nicht
   deren Aufzaehlung. Ein Geraet, das weder fein noch grob zeigt (pointer:
   none, etwa reine Tastatursteuerung), faellt sonst durch beide Raster und
   stuende vor dem Rad mit allen vier Tafeln uebereinander. */

@media not all and (min-width: 861px) and (hover: hover) and (pointer: fine) {
  .wheel {
    width: 100%;
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
  }

  .wheel-frame {
    display: none;
  }

  /* Ohne die Kante des Rads bezieht sich ein Innenabstand in Prozent auf die
     ganze Spaltenbreite und treibt die Kugel zum Ei; hier zaehlt ein fester
     Wert. */
  .wheel-hub {
    /* relative statt static: der Weg zur Galerie haengt am unteren Rand der
       Kugel und braucht sie als Bezug. */
    position: relative;
    inset: auto;
    order: -1;
    width: min(260px, 62%);
    aspect-ratio: 1;
    margin: 0 auto 1.5rem;
    padding: 1.75rem;
  }

  /* Auf einem breiten Tastgeraet stuenden die Zeilen sonst ueber die volle
     Seitenbreite. */
  .wheel-drops {
    position: static;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
    pointer-events: auto;
  }

  .drop {
    position: static;
    display: flex;
    align-items: flex-start;
    gap: 1.25rem;
    padding: 1.4rem;
    background: var(--card);
    border: 1px solid var(--hairline);
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.5);
  }

  /* Aufgereiht gibt es keine Bahn mehr; der Rahmen wird zum Platzhalter des
     Tropfens in der Zeile. */
  .drop-orbit {
    position: static;
    inset: auto;
    flex: 0 0 88px;
    height: 88px;
    animation: none;
  }

  /* Zwei Klassen tief, damit die Platzierung der einzelnen Tropfen auf dem Rad
     (auch zwei Klassen tief) hier wirklich zurueckgenommen wird. */
  .drop .drop-bubble {
    position: relative;
    inset: auto;
    animation: none;
    flex: 0 0 88px;
    width: 88px;
    height: 88px;
    padding: 0;
  }

  .drop-glyph {
    font-size: 2.1rem;
  }

  /* Der Name steht auf der Tafel; im Tropfen bleibt er nur als Linkbeschriftung. */
  .drop-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .drop-detail {
    position: static;
    inset: auto;
    align-items: flex-start;
    text-align: left;
    gap: 0.75rem;
  }

  /* Ohne Zeigegeraet gibt es nichts zu ueberfahren: hier steht ohnehin alles
     untereinander. */
  .wheel-hint {
    display: none;
  }
}

@media (max-width: 520px) {
  .drop {
    flex-direction: column;
    align-items: center;
  }

  .drop-detail {
    align-items: center;
    text-align: center;
  }
}

/* ---------- Marken und Schlagworte ---------- */

.badge {
  font-family: var(--font-display);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 0.35rem 0.8rem;
  white-space: nowrap;
}

.badge-wip {
  color: var(--gold-soft);
  background: rgba(232, 176, 75, 0.08);
  border: 1px solid rgba(232, 176, 75, 0.35);
}

.badge-live {
  color: #8fe9ae;
  background: rgba(36, 180, 100, 0.1);
  border: 1px solid rgba(36, 180, 100, 0.4);
}

.game-meta {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  justify-content: center;
}

.tag {
  font-family: var(--font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  border: 1px solid var(--border);
  padding: 0.3rem 0.7rem;
}

/* ---------- Matheeule cross-link ---------- */

.crosslink {
  position: relative;
  background: var(--card);
  border: 1px solid var(--hairline);
  padding: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  flex-wrap: wrap;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.5);
}

.crosslink::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid rgba(232, 176, 75, 0.1);
  pointer-events: none;
}

.crosslink h2 {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 500;
  margin-bottom: 0.6rem;
}

.crosslink p {
  color: var(--text-muted);
  max-width: 36rem;
}

/* ---------- Content pages (Impressum, Datenschutz) ---------- */

.page {
  padding: 4.5rem 0 5rem;
  max-width: 760px;
  margin: 0 auto;
}

.page h1 {
  font-family: var(--font-display);
  font-size: 2.4rem;
  font-weight: 500;
  margin-bottom: 0.6rem;
}

.page .lede {
  color: var(--text-muted);
  margin-bottom: 2.75rem;
  font-size: 1.05rem;
}

.page h2 {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  margin: 2.25rem 0 0.65rem;
  color: var(--gold-soft);
}

.page p {
  color: var(--text-muted);
  margin-bottom: 0.85rem;
}

.page p strong {
  color: var(--text);
}

/* Wer verarbeitet was: eine Zeile je App auf der App-Datenschutzseite.
   Scrollt fuer sich, damit vier Spalten ein Telefon nicht sprengen. */
.datatable {
  width: 100%;
  border-collapse: collapse;
  margin: 1.25rem 0 1.75rem;
  font-size: 0.95rem;
  display: block;
  overflow-x: auto;
}

.datatable th,
.datatable td {
  padding: 0.6rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
  white-space: nowrap;
}

.datatable thead th {
  color: var(--gold-soft);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--hairline-strong);
}

.datatable tbody th {
  color: var(--text);
  font-weight: 500;
}

/* ---------- Footer ---------- */

.foot {
  border-top: 1px solid var(--hairline);
  margin-top: 4.5rem;
  padding: 2.25rem 0;
  font-size: 0.92rem;
  color: var(--text-faint);
}

.foot .inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.foot a {
  color: var(--text-muted);
}

.foot a:hover {
  color: var(--gold-soft);
}

.foot-links {
  display: flex;
  gap: 1.75rem;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ---------- Entrance reveals ---------- */

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.block-oben h1,
.block-oben .section-head p {
  animation: rise 0.9s var(--ease) both;
}

.block-oben .section-head p {
  animation-delay: 0.16s;
}

/* ---------- Responsive & motion ---------- */

@media (max-width: 860px) {
  .block.block-oben {
    padding-top: 2.5rem;
  }

  .nav {
    gap: 1rem;
    font-size: 0.68rem;
  }

  .crosslink {
    padding: 2rem 1.75rem;
  }
}

@media (max-width: 480px) {
  .topbar .inner {
    padding: 0.8rem 1rem;
    gap: 0.6rem;
  }

  .logo {
    font-size: 0.85rem;
    letter-spacing: 0.14em;
    gap: 0.45rem;
  }

  .logo img {
    width: 26px;
    height: 26px;
  }

  .nav {
    gap: 0.75rem;
    font-size: 0.62rem;
    letter-spacing: 0.12em;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  /* Pauschal statt als Selektorliste, damit spaeter hinzukommende Effekte
     nicht von Hand nachgetragen werden muessen. transform dient in diesem
     Stylesheet ausschliesslich der Bewegung (Hover-Versatz, Keyframe-Schritte,
     Sheen), nie dem Layout: das Rad setzt seine Tropfen ueber inset, nicht
     ueber transform, darum ist das Abschalten hier gefahrlos. */
  *,
  *::before,
  *::after {
    animation: none !important;
    transform: none !important;
    rotate: none !important;
    scale: none !important;
    translate: none !important;
    /* Nur die Bewegung faellt weg. Farb- und Schattenwechsel duerfen weiter
       ueberblenden, sonst blitzt der Hover-Schatten hart auf, was genauso
       unruhig ist wie die Bewegung, die hier abgestellt wird. */
    transition-property: color, background-color, border-color, box-shadow, opacity !important;
  }
}

/* ---------- Galerie ---------- */

.gal-filter {
  display: flex;
  gap: 0.5rem;
  margin: -2rem 0 3rem;
}

.chip {
  font-family: var(--font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  background: none;
  border: 1px solid var(--border);
  padding: 0.45rem 0.9rem;
  cursor: pointer;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.chip:hover {
  color: var(--text-muted);
  border-color: var(--hairline);
}

.chip.is-on {
  color: var(--gold-soft);
  border-color: var(--hairline-strong);
}

.gal-status {
  color: var(--text-faint);
  font-style: italic;
}

.gal-app + .gal-app {
  margin-top: 4.5rem;
}

.gal-app-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 0.9rem;
  margin-bottom: 1.8rem;
}

.gal-app-head h3 {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 3vw, 1.9rem);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--gold-soft);
}

/* Hoch- und Querformat stehen nebeneinander in derselben Reihe. Die feste
   Zeilenhoehe bestimmt die Groesse, die Breite ergibt sich aus dem Bild,
   sonst muesste das Raster je Spiel anders aussehen. */
.gal-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem;
}

.gal-shot {
  --shot-h: 320px;
  margin: 0;
  cursor: zoom-in;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.gal-shot:hover,
.gal-shot:focus-visible {
  border-color: var(--hairline-strong);
  box-shadow: 0 0 0 1px var(--hairline), 0 14px 40px rgba(0, 0, 0, 0.5);
  outline: none;
}

.gal-shot img {
  display: block;
  height: var(--shot-h);
  /* Breite aus der Geraeteform und nicht aus dem Bild. Die Spiele fotografieren
     den ganzen Bildschirm, nicht nur das sichtbare Fenster, und so eine
     Aufnahme ist mehrere Bildschirme hoch. Liesse man die feste Hoehe die
     Breite bestimmen, schrumpfte die Kachel zu einem Streifen von zwanzig
     Pixeln. Stattdessen behaelt die Kachel die Form des Geraets und zeigt den
     oberen Teil der Seite; das Ganze steht in der Lightbox. */
  /* Die Form setzt das Skript je Bild aus dem Manifest; der Rueckfallwert
     gilt nur, wenn ein Eintrag keine Masse mitbringt. */
  width: calc(var(--shot-h) * var(--shot-ar, 0.45));
  max-width: 100%;
  object-fit: cover;
  object-position: top center;
}

/* Sagt, dass die Seite weiterlaeuft, damit ein abgeschnittener Rand nicht wie
   ein Fehler aussieht. */
.gal-shot[data-tall='1'] {
  position: relative;
}

.gal-shot[data-tall='1']::after {
  content: 'weiter';
  position: absolute;
  right: 0.5rem;
  top: calc(var(--shot-h) - 1.6rem);
  padding: 0.05rem 0.5rem;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text-faint);
  font-size: 0.68rem;
}

.gal-shot figcaption {
  font-size: 0.82rem;
  color: var(--text-faint);
  padding: 0.55rem 0.8rem;
  border-top: 1px solid var(--border);
}

@media (max-width: 640px) {
  .gal-shot {
    --shot-h: 220px;
  }
}

/* ---------- Lightbox ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(4, 5, 12, 0.92);
  backdrop-filter: blur(6px);
}

.lightbox[hidden] {
  display: none;
}

.lb-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  min-width: 0;
}

.lb-figure img {
  max-width: min(100%, 1100px);
  max-height: 82vh;
  width: auto;
  height: auto;
  border: 1px solid var(--hairline);
}

/* Eine Aufnahme des ganzen Bildschirms ist um ein Vielfaches hoeher als breit.
   In die Hoehe des Fensters gepasst faellt sie zu einem Streifen von wenigen
   Dutzend Pixeln zusammen, und dann ist nichts davon zu lesen. Sie wird
   deshalb auf lesbare Breite gezeigt und im Rahmen gerollt. */
.lb-figure[data-tall='1'] {
  max-height: 82vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.lb-figure[data-tall='1'] img {
  max-height: none;
  width: min(100%, 420px);
}

.lb-figure figcaption {
  font-family: var(--font-display);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: center;
}

.lb-close,
.lb-prev,
.lb-next {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 1.6rem;
  line-height: 1;
  padding: 0.4rem 0.8rem;
  cursor: pointer;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.lb-close:hover,
.lb-prev:hover,
.lb-next:hover {
  color: var(--gold-soft);
  border-color: var(--hairline-strong);
}

.lb-close {
  position: absolute;
  top: clamp(1rem, 3vw, 2rem);
  right: clamp(1rem, 3vw, 2rem);
}

@media (max-width: 640px) {
  .lb-prev,
  .lb-next {
    position: absolute;
    bottom: 1.2rem;
  }

  .lb-prev {
    left: 1.2rem;
  }

  .lb-next {
    right: 1.2rem;
  }
}
