/* ============================================================
   EmberwakeRPG — Design-System v1 „Glut erwacht"
   Tokens & Regeln: siehe DESIGN.md
   Motion-Prinzip: „Glut, nicht Blitz" — alles steigt wie Funken,
   Hover glüht, nichts blitzt. prefers-reduced-motion wird respektiert.
   ============================================================ */

/* ---------- Tokens ---------- */
:root {
  /* ------------------------------------------------------------------------
     Farbwelt „Glut & Ranke", abgeleitet aus dem Emblem.

     Die Werte sind nicht geschaetzt, sondern aus dem Logo gemessen (Bildpunkte
     in Farbeimer gelegt, kraeftigsten Vertreter je Familie genommen):

       #104050 / #108090   Nachthimmel, Petrol       (17 % der Flaeche)
       #f08020 / #c04010   Feuer und Glut
       #f0e0c0             Gold der Schrift
       #002030             Tiefschwarz mit Blaustich (Rahmen, Ranken)

     Der entscheidende Unterschied zur bisherigen Fassung: der Grund ist kein
     warmes Braunschwarz mehr, sondern ein kaltes Petrol. Das Logo zeigt eine
     kalte Nacht, in der es brennt — erst dieser Gegensatz laesst das Feuer
     leuchten. Auf warmem Grund verschwimmt es damit.
     ------------------------------------------------------------------------ */

  /* Grund: kalte Nacht, drei Stufen */
  --bg:    #07131a;
  --bg-2:  #0c1e27;
  --bg-3:  #123039;

  /* Schrift: warmes Pergament gegen den kalten Grund */
  --ink:       #ece3d4;
  --ink-dim:   #a9bcc2;
  /* #71888f trug auf dem alten warmen Braunschwarz noch, auf dem helleren
     kalten Kartengrund --bg-3 aber nur 3,73:1 — zu wenig fuer die Kleinschrift
     (Fussnoten, Pruefsummen, Ablageorte). Nachgerechnet nach WCAG 2.1:
     #8da2a8 liegt auf --bg bei 7,04:1, auf --bg-2 bei 6,39:1 und auf --bg-3
     bei 5,22:1 — auf allen drei Gruenden ueber 4,5:1. */
  --ink-faint: #8da2a8;

  /* Feuer */
  --ember:   #f08020;
  --ember-2: #ffb347;
  --glut:    #c04010;

  /* Gold der Schrift im Emblem */
  --gold:   #d9a84e;
  --gold-2: #f0e0c0;

  /* Blattwerk und Himmel — ersetzt das fruehere Moosgruen, das im Logo
     nirgends vorkommt. */
  --moss:      #108090;
  --moss-2:    #4fb3bf;
  --moss-line: rgba(79, 179, 191, .18);

  /* Linien: Gold gedaempft, wie die Ornamentkanten im Emblem */
  --line:        rgba(217, 168, 78, .16);
  --line-strong: rgba(217, 168, 78, .38);

  --grad-ember: linear-gradient(135deg, #c04010, #f08020 45%, #ffb347);

  --font-display: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, "Times New Roman", serif;
  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ease-ember: cubic-bezier(.22, .61, .36, 1);
  --dur-1: .22s;
  --dur-2: .7s;
  --radius: 14px;
  --nav-h: 72px;
}

/* ---------- Reset & Basis ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16.5px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; height: auto; }

::selection { background: rgba(240, 128, 32, .35); color: var(--gold-2); }

a { color: var(--gold-2); text-decoration: none; transition: color var(--dur-1) var(--ease-ember); }
a:hover { color: var(--ember-2); }

:focus-visible {
  outline: 2px solid var(--ember-2);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Fuer Statusmeldungen und den Sprunglink: visuell ruhig, fuer Tastatur und
   Screenreader aber voll erreichbar. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; top: .7rem; left: max(.7rem, env(safe-area-inset-left));
  z-index: 120; padding: .65rem 1rem; border-radius: 8px;
  background: var(--gold-2); color: var(--bg); font-weight: 700;
  transform: translateY(calc(-100% - 1rem));
  transition: transform var(--dur-1) var(--ease-ember);
}
.skip-link:focus { color: var(--bg); transform: none; }

/* Dezenter Asche-Scrollbalken (WebKit) */
::-webkit-scrollbar { width: 12px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: 8px; border: 3px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: #1c4753; }

/* ---------- Seitenübergänge: sanftes Überblenden (progressive enhancement) ---------- */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: ew-fade-out .28s var(--ease-ember) both; }
::view-transition-new(root) { animation: ew-fade-in .38s var(--ease-ember) both; }
@keyframes ew-fade-out { to { opacity: 0; } }
@keyframes ew-fade-in { from { opacity: 0; } }

/* Fallback: weiches Erscheinen beim Laden */
@keyframes ew-page-in { from { opacity: 0; } to { opacity: 1; } }
body { animation: ew-page-in .5s var(--ease-ember) both; }

/* ---------- Typografie ---------- */
h1, h2, h3 { font-family: var(--font-display); font-weight: 600; line-height: 1.15; margin: 0 0 .5em; }

.kicker {
  display: inline-flex;
  align-items: center;
  gap: .75rem;
  font-size: .78rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.kicker::before {
  content: "";
  width: 34px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold));
  transform-origin: left center;
}
.reveal.in .kicker::before { animation: ew-line-grow .8s var(--ease-ember) both; }
@keyframes ew-line-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.section-title {
  font-size: clamp(1.7rem, 4vw, 2.6rem);
  letter-spacing: .04em;
}
.section-lead { color: var(--ink-dim); max-width: 620px; margin: 0 0 2.5rem; }

/* Glut-Schimmer für hervorgehobene Worte */
.glow-text {
  background: linear-gradient(110deg, var(--gold-2) 0%, #fff3d6 22%, var(--ember-2) 45%, var(--gold-2) 70%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: ew-shimmer 6.5s linear infinite;
}
@keyframes ew-shimmer {
  0% { background-position: 0% 0; }
  100% { background-position: 220% 0; }
}

/* ---------- Layout-Helfer ---------- */
.container { width: min(1120px, calc(100% - 3rem)); margin-inline: auto; }
section { position: relative; padding: clamp(4rem, 9vw, 7.5rem) 0; }

/* Ornament-Trenner: Goldlinie mit Raute */
.ornament {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  color: var(--gold); opacity: .55; margin: 0 auto;
  width: min(420px, 70%);
}
.ornament::before, .ornament::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold));
}
.ornament::after { background: linear-gradient(90deg, var(--gold), transparent); }
.ornament svg { flex: none; width: 48px; height: 20px; }

/* ---------- Navigation ---------- */
.site-nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--nav-h);
  transition: background var(--dur-1) var(--ease-ember), border-color var(--dur-1) var(--ease-ember), backdrop-filter var(--dur-1) var(--ease-ember);
  border-bottom: 1px solid transparent;
}
/* Auf Seiten ohne Hero (Nutzerbereich, Fehlermeldung, Verwaltung) setzt
   top.php die Klasse „seite-flach" auf den Body: dort beginnt der Inhalt
   direkt unter der festen Leiste und schob beim Scrollen ungebremst durch sie
   hindurch — gemessen background-color rgba(0,0,0,0) bei scrollY 600 auf
   /app, /bug und /admin, waehrend /de/ dort rgba(7,19,26,.82) trug. Die
   Rechtstexte loesen dasselbe seit je mit class="site-nav scrolled" im
   Markup; hier haengt es an der Seite, damit main.js die Fuellung am
   Seitenanfang nicht wieder abraeumt. */
.site-nav.scrolled,
.seite-flach .site-nav {
  background: rgba(7, 19, 26, .82);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom-color: var(--line);
}
.nav-inner {
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
}
.brand { display: inline-flex; align-items: center; gap: .7rem; color: var(--ink); }
/* flex:none — sonst gibt das Emblem als Flex-Kind nach, wenn rechts viel
   steht: auf /app bei 360 px mass es nur noch 36 statt 40 px. */
.brand img { flex: none; width: 40px; height: 40px; transition: filter var(--dur-1) var(--ease-ember); }
.brand:hover img { filter: drop-shadow(0 0 8px rgba(240, 128, 32, .6)); }
.brand-name {
  font-family: var(--font-display);
  font-size: 1.12rem; letter-spacing: .12em; text-transform: uppercase;
}
.brand-name b { color: var(--gold); font-weight: 600; }

/* Sieben Eintraege, dazu Konto- und Sprachknopf. Die Inhaltsspalte waechst
   ueber 1120px nicht mehr mit (--container), der enge Satz ist also kein
   Sonderfall breiter Fenster, sondern der Normalfall — er gehoert deshalb in
   die Grundregel und nicht erst in eine Media-Query. Mit 1.9rem fuellte die
   deutsche Fassung die Spalte auf den Pixel genau aus (Marke 231 + Links 731
   + Knoepfe 110 + 2x24 = 1120): kein Umbruch, aber auch keine Luft. Mit
   1.35rem bleiben je 50px Abstand. */
.nav-links {
  display: flex; gap: 1.35rem; list-style: none; margin: 0; padding: 0;
}
.nav-links a {
  position: relative; color: var(--ink-dim);
  font-size: .92rem; letter-spacing: .06em;
  padding: .35rem 0;
}
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0; height: 1px;
  background: var(--grad-ember);
  transition: right var(--dur-1) var(--ease-ember);
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after { right: 0; }

.nav-right { display: flex; align-items: center; gap: 1rem; }

/* ---------- Kontoknopf: der Weg in den eigenen Bereich (/app) ----------
   Das Profilbild oder Kontosymbol misst 34 px, die Beruehrflaeche aber volle 44 px. Ein
   kleineres Ziel ist auf dem Telefon nicht sicher zu treffen, deshalb sitzt
   das runde Bild mittig in einem groesseren, unsichtbaren Rahmen — der
   Knopf beansprucht Platz nach der 44er-Regel, sieht aber leicht aus. */
.avatar-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none;
  width: 44px; height: 44px;
  border-radius: 50%;
}
.avatar-btn img,
.avatar-btn .account-symbol {
  width: 34px; height: 34px;
  border-radius: 50%;
  /* Gedaempfte Goldkante wie an allen Rahmen der Seite */
  border: 1px solid var(--line);
  background: var(--bg-2);
  transition: border-color var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.avatar-btn img { object-fit: cover; }
.avatar-btn .account-symbol {
  box-sizing: border-box; padding: 6px; color: var(--gold-2);
}
.avatar-btn:hover img,
.avatar-btn:focus-visible img,
.avatar-btn:hover .account-symbol,
.avatar-btn:focus-visible .account-symbol {
  border-color: var(--line-strong);
  box-shadow: 0 0 14px rgba(217, 168, 78, .3);
}

.lang-switch {
  font-size: .8rem; letter-spacing: .14em;
  border: 1px solid var(--line-strong); border-radius: 999px;
  padding: .38rem .85rem; color: var(--ink-dim);
  transition: border-color var(--dur-1) var(--ease-ember), color var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.lang-switch:hover {
  color: var(--gold-2); border-color: var(--gold);
  box-shadow: 0 0 14px rgba(217, 168, 78, .25);
}
/* Mit dem Finger bedient misst die Pille nur 50x35 px. Sie waechst deshalb
   dort — und nur dort — auf 44 px Hoehe; mit Maus bleibt der schlanke Satz. */
@media (pointer: coarse) {
  .lang-switch { display: inline-flex; align-items: center; min-height: 44px; }
  /* Der Weg zurueck auf die Startseite haengt am 40 px hohen Emblem. Die
     Leiste ist 72 px hoch, die vier fehlenden Pixel sind also frei zu haben. */
  .brand { min-height: 44px; }
}

/* Der Kontoeintrag im Menue erscheint erst, wenn der Knopf oben verschwindet. */
.nav-konto,
.nav-abmelden { display: none; }

/* 42x38 lag unter der 44er-Regel und war auf dem Telefon der einzige Weg in
   die Navigation. Der Rahmen bleibt optisch gleich schlank, die Flaeche
   waechst. */
.nav-toggle {
  display: none; background: none; border: 1px solid var(--line-strong); border-radius: 8px;
  width: 44px; height: 44px; cursor: pointer; color: var(--ink);
  align-items: center; justify-content: center;
}

/* ---------- Hero ---------- */
.hero {
  min-height: 100svh;
  display: grid; place-items: center; text-align: center;
  padding: calc(var(--nav-h) + 3rem) 0 5rem;
  overflow: hidden;
  isolation: isolate;
}
/* Warme Glut-Aura + Vignette */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -2;
  background:
    /* Glut des brennenden Dorfes: warm, tief, aus dem Petrol heraus */
    radial-gradient(ellipse 70% 48% at 50% 62%, rgba(240, 128, 32, .16), transparent 70%),
    radial-gradient(ellipse 45% 32% at 50% 70%, rgba(255, 179, 71, .11), transparent 70%),
    /* Nachthimmel des Emblems: kalter Petrolschleier ueber der Szene */
    radial-gradient(ellipse 95% 55% at 50% 0%, rgba(16, 128, 144, .13), transparent 72%),
    /* Vignette: kalte Tiefe statt des frueheren warmen Brauns */
    radial-gradient(ellipse 120% 90% at 50% 0%, rgba(2, 8, 12, .55), transparent 60%);
  animation: ew-aura 9s ease-in-out infinite alternate;
}
@keyframes ew-aura {
  from { opacity: .85; transform: scale(1); }
  to { opacity: 1; transform: scale(1.05); }
}
/* Feine Asche-Textur */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .05;
  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='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
}
/* ---------- Hero-Aufnahme: das Dorf bei Nacht hinter der Glut ----------
   Liegt unter Aura (-2) und Asche (-1). Der Verlauf darueber loescht das Bild
   zum Seitengrund hin aus, damit der Uebergang zur naechsten Sektion
   nahtlos bleibt und die Schrift nie gegen Wolken oder Dorflichter kaempft. */
.hero-shot {
  position: absolute; inset: 0; z-index: -3; pointer-events: none;
  overflow: hidden;
}
.hero-shot img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: 70% 76%;
  opacity: .62; filter: saturate(.95) contrast(1.02);
}
.hero-shot::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 62% 46% at 50% 44%, rgba(7, 19, 26, .7), transparent 72%),
    linear-gradient(to bottom, rgba(7, 19, 26, .74) 0%, rgba(7, 19, 26, .46) 40%, rgba(7, 19, 26, .6) 76%, var(--bg) 97%);
}

#embers { position: absolute; inset: 0; z-index: -1; pointer-events: none; }

.hero-emblem {
  width: clamp(120px, 18vw, 176px);
  margin-bottom: 1.6rem;
  filter: drop-shadow(0 0 26px rgba(240, 128, 32, .42));
  /* Die Intro-Animation gilt bis 1,1 s; erst danach uebernimmt das Schweben.
     So konkurrieren nicht zwei Animationen gleichzeitig um transform. */
  animation: ew-emblem-in 1.1s var(--ease-ember) both, ew-float 7s ease-in-out 1.1s infinite;
}
@keyframes ew-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-9px); }
}
@keyframes ew-emblem-in {
  from { opacity: 0; transform: translateY(26px) scale(.92); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.hero-kicker {
  font-size: .82rem; letter-spacing: .34em; text-transform: uppercase;
  color: var(--gold); opacity: 0;
  animation: ew-rise var(--dur-2) var(--ease-ember) .25s both;
}
.hero-title {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 9vw, 5.4rem);
  letter-spacing: .1em;
  margin: .35em 0 .2em;
}
/* Titel-Silben steigen versetzt auf — „Funkenflug" */
.hero-title span {
  display: inline-block; opacity: 0;
  animation: ew-rise var(--dur-2) var(--ease-ember) both;
  animation-delay: var(--d, .4s);
}
/* Schimmer-Silbe im Hero: erst aufsteigen, dann dauerhaft glimmen */
.hero-title .glow-text {
  animation: ew-rise var(--dur-2) var(--ease-ember) both, ew-shimmer 6.5s linear infinite;
  animation-delay: var(--d, .4s), 1.3s;
}
.hero-sub {
  max-width: 640px; margin: 0 auto 2.4rem;
  color: var(--ink-dim); font-size: clamp(1rem, 2vw, 1.16rem);
  opacity: 0; animation: ew-rise var(--dur-2) var(--ease-ember) .95s both;
}
.hero-cta {
  display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;
  opacity: 0; animation: ew-rise var(--dur-2) var(--ease-ember) 1.15s both;
}
@keyframes ew-rise {
  from { opacity: 0; transform: translateY(24px); }
  to { opacity: 1; transform: translateY(0); }
}

.scroll-hint {
  position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%);
  color: var(--ink-faint); font-size: 1.4rem; line-height: 1;
  animation: ew-hint 2.2s ease-in-out infinite;
  opacity: 0; animation-delay: 1.8s;
  animation-name: ew-hint; animation-fill-mode: both;
}
@keyframes ew-hint {
  0%, 100% { opacity: .35; transform: translate(-50%, 0); }
  50% { opacity: .9; transform: translate(-50%, 8px); }
}

/* ---------- Buttons ---------- */
.btn {
  position: relative; display: inline-flex; align-items: center; gap: .6rem;
  padding: .85rem 1.7rem; border-radius: 999px;
  font-size: .95rem; letter-spacing: .05em; font-weight: 600;
  overflow: hidden; cursor: pointer;
  transition: transform var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember), border-color var(--dur-1) var(--ease-ember), color var(--dur-1) var(--ease-ember);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn-primary {
  background: linear-gradient(135deg, #dc6016, var(--ember) 45%, var(--ember-2));
  color: var(--bg); border: none;
  box-shadow: 0 4px 22px rgba(240, 128, 32, .34);
}
.btn-primary:hover { box-shadow: 0 6px 32px rgba(240, 128, 32, .55); color: var(--bg); }
/* Schein-Sweep */
.btn-primary::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .45) 50%, transparent 70%);
  transform: translateX(-110%);
  transition: transform .55s var(--ease-ember);
}
.btn-primary:hover::after { transform: translateX(110%); }

.btn-ghost {
  background: transparent; color: var(--ink);
  border: 1px solid var(--line-strong);
}
.btn-ghost:hover {
  border-color: var(--gold); color: var(--gold-2);
  box-shadow: 0 0 18px rgba(217, 168, 78, .22);
}

/* ---------- Leitprinzipien-Streifen ---------- */
.principles {
  border-block: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(18, 48, 57, .45), transparent);
  padding: 3rem 0;
}
.principles .container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.5rem; }
.principle h3 {
  font-size: 1.06rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold-2); margin-bottom: .35em;
}
.principle p { margin: 0; color: var(--ink-dim); font-size: .95rem; }

/* ---------- Feature-Karten ---------- */
.features-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.3rem;
}
.card {
  position: relative;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.7rem 1.5rem 1.5rem;
  /* 3D-Tilt: --rx/--ry setzt main.js aus der Zeigerposition */
  transform: perspective(750px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--lift, 0px));
  transition: transform .18s ease-out, border-color var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
  overflow: hidden;
}
/* Glanzlicht wandert mit dem Zeiger über die Karte */
.card::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 179, 71, .10), transparent 65%);
  opacity: 0; transition: opacity var(--dur-1) var(--ease-ember);
}
.card:hover::after { opacity: 1; }
/* Glut-Linie am oberen Rand glimmt bei Hover auf */
.card::before {
  content: ""; position: absolute; top: 0; left: 12%; right: 12%; height: 1px;
  background: var(--grad-ember); opacity: 0;
  transition: opacity var(--dur-1) var(--ease-ember), left var(--dur-1) var(--ease-ember), right var(--dur-1) var(--ease-ember);
}
.card:hover {
  --lift: -4px;
  border-color: var(--line-strong);
  box-shadow: 0 14px 38px rgba(0, 0, 0, .55), 0 0 24px rgba(240, 128, 32, .11);
}
.card:hover::before { opacity: 1; left: 4%; right: 4%; }

.card .icon {
  width: 44px; height: 44px; margin-bottom: 1rem;
  color: var(--gold);
  transition: color var(--dur-1) var(--ease-ember), filter var(--dur-1) var(--ease-ember), transform var(--dur-1) var(--ease-ember);
}
.card:hover .icon {
  color: var(--ember-2);
  filter: drop-shadow(0 0 8px rgba(240, 128, 32, .65));
  transform: translateY(-2px);
}
.card h3 { font-size: 1.12rem; letter-spacing: .03em; }
.card p { margin: 0; color: var(--ink-dim); font-size: .92rem; line-height: 1.6; }

/* ---------- Welt-Reihen (Text + Bild im Wechsel) ---------- */
.world-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  margin-bottom: clamp(3.5rem, 7vw, 6rem);
}
.world-row:last-child { margin-bottom: 0; }
.world-row.flip .world-text { order: 2; }
.world-text h3 { font-size: clamp(1.4rem, 3vw, 1.9rem); }
.world-text p { color: var(--ink-dim); }
.world-text ul { color: var(--ink-dim); padding-left: 1.2rem; margin: 1rem 0 0; }
.world-text li { margin-bottom: .45rem; }
.world-text li::marker { color: var(--moss-2); }

/* „Die Welt": leiser Flora-Schimmer — Natur als Gegengewicht zur Glut */
#world::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 55% 38% at 88% 12%, rgba(16, 128, 144, .11), transparent 70%),
    radial-gradient(ellipse 48% 34% at 8% 85%, rgba(79, 179, 191, .07), transparent 70%);
}

/* ---------- Aufnahmen aus dem Spiel ----------
   Wo es einen echten Screenshot gibt, tritt er an die Stelle der
   Funktionsgrafik: dieselbe Rahmung, aber die Bildunterschrift sitzt unter
   dem Bild statt darueber — ueber einem Screenshot waere sie unlesbar. */
.shot-panel {
  margin: 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-2);
  box-shadow: inset 0 1px rgba(255, 255, 255, .025), 0 18px 45px rgba(0, 0, 0, .3);
  transition: border-color var(--dur-1) var(--ease-ember), transform var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.shot-panel:hover {
  border-color: var(--line-strong); transform: translateY(-3px);
  box-shadow: inset 0 1px rgba(255, 255, 255, .035), 0 22px 52px rgba(0, 0, 0, .4), 0 0 25px rgba(16, 128, 144, .08);
}
.shot-panel picture, .shot picture { display: block; }
.shot-panel img, .shot img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 3 / 2; object-fit: cover;
  background: var(--bg-3);
}
.shot-panel figcaption {
  margin: 0; padding: .85rem 1.15rem 1rem;
  border-top: 1px solid var(--line);
  color: var(--ink-faint); font-size: .78rem; line-height: 1.5;
}

/* ---------- Galerie ---------- */
.shot-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.1rem, 2.4vw, 1.7rem);
  margin-top: clamp(2.2rem, 4vw, 3rem);
}
.shot {
  margin: 0; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-2);
  box-shadow: inset 0 1px rgba(255, 255, 255, .025), 0 18px 45px rgba(0, 0, 0, .3);
  transition: border-color var(--dur-1) var(--ease-ember), transform var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.shot:hover, .shot:focus-within {
  border-color: var(--line-strong); transform: translateY(-3px);
  box-shadow: inset 0 1px rgba(255, 255, 255, .035), 0 22px 52px rgba(0, 0, 0, .4), 0 0 25px rgba(240, 128, 32, .08);
}
.shot-open {
  display: block; position: relative; width: 100%; padding: 0;
  border: 0; background: none; color: var(--ink); font: inherit;
}
/* Lupe und Zeiger versprechen nur dort etwas, wo das Skript sie einloest —
   ohne JavaScript bleibt die Aufnahme sichtbar, nur eben nicht vergroesserbar. */
html.js .shot-open { cursor: zoom-in; }
.shot-open:focus-visible { outline: 2px solid var(--ember); outline-offset: -2px; }
/* Die Lupe glimmt erst auf, wenn die Karte angesteuert wird — Glut, nicht Blitz */
.shot-zoom {
  position: absolute; right: .7rem; bottom: .7rem;
  display: grid; place-items: center; width: 2.1rem; height: 2.1rem;
  border: 1px solid var(--line-strong); border-radius: 50%;
  background: rgba(7, 19, 26, .78); color: var(--gold-2);
  opacity: 0; transform: translateY(4px);
  transition: opacity var(--dur-1) var(--ease-ember), transform var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.shot-zoom svg { width: 1.05rem; height: 1.05rem; }
html.js .shot:hover .shot-zoom, html.js .shot:focus-within .shot-zoom {
  opacity: 1; transform: none; box-shadow: 0 0 18px rgba(240, 128, 32, .22);
}
.shot figcaption {
  margin: 0; padding: .85rem 1.15rem 1rem;
  border-top: 1px solid var(--line);
  color: var(--ink-faint); font-size: .78rem; line-height: 1.5;
}
.shot figcaption b {
  display: block; margin-bottom: .18rem;
  color: var(--ink); font-weight: 600; font-size: .93rem; letter-spacing: .01em;
}

/* ---------- Lightbox: natives <dialog>, Fokusfalle und ESC vom Browser ----------
   Der Dialog spannt den ganzen Viewport auf und zentriert die Aufnahme darin.
   Die Groesse dem Dialog selbst zu ueberlassen scheitert: seine shrink-to-fit-
   Breite entsteht aus der vollen Bildbreite, bevor die Hoehenbegrenzung greift —
   neben dem Bild bliebe ein leerer Panelstreifen stehen. */
.shot-view {
  width: 100vw; max-width: 100vw; height: 100svh; max-height: 100svh;
  margin: 0; padding: 0; border: 0; background: none; box-shadow: none;
  overflow: hidden;
}
.shot-view[open] { display: flex; align-items: center; justify-content: center; }
.shot-view::backdrop { background: rgba(3, 10, 14, .86); backdrop-filter: blur(3px); }
.shot-view picture { display: block; }
.shot-view img {
  display: block; width: auto; height: auto;
  max-width: 94vw; max-height: 88svh;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--bg-2);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
}
.shot-view-close {
  position: fixed; top: 1rem; right: 1rem; z-index: 2;
  width: 2.4rem; height: 2.4rem; padding: 0; line-height: 1;
  border: 1px solid var(--line-strong); border-radius: 50%;
  background: rgba(7, 19, 26, .86); color: var(--gold-2);
  font-size: 1.4rem; cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.shot-view-close:hover, .shot-view-close:focus-visible {
  border-color: var(--ember); box-shadow: 0 0 18px rgba(240, 128, 32, .28);
}
.shot-view[open] img { animation: ew-shot-in var(--dur-2) var(--ease-ember); }
@keyframes ew-shot-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---------- Systembilder: echte Funktionsgrafiken statt Screenshot-Dummies ---------- */
.system-panel {
  position: relative; margin: 0; aspect-ratio: 4 / 3; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background:
    radial-gradient(circle at 50% 34%, rgba(16, 128, 144, .16), transparent 43%),
    linear-gradient(145deg, rgba(18, 48, 57, .9), rgba(7, 19, 26, .96));
  box-shadow: inset 0 1px rgba(255, 255, 255, .025), 0 18px 45px rgba(0, 0, 0, .3);
  transition: border-color var(--dur-1) var(--ease-ember), transform var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.system-panel::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .32;
  background:
    linear-gradient(rgba(79, 179, 191, .08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(79, 179, 191, .08) 1px, transparent 1px);
  background-size: 38px 38px;
  -webkit-mask-image: radial-gradient(circle at 50% 45%, #000, transparent 76%);
  mask-image: radial-gradient(circle at 50% 45%, #000, transparent 76%);
}
.system-panel:hover {
  border-color: var(--line-strong); transform: translateY(-3px);
  box-shadow: inset 0 1px rgba(255, 255, 255, .035), 0 22px 52px rgba(0, 0, 0, .4), 0 0 25px rgba(16, 128, 144, .08);
}
.system-diagram { position: absolute; inset: 1rem 1rem 4.7rem; }
.system-panel figcaption {
  position: absolute; inset: auto 1.15rem 1.1rem; margin: 0;
  color: var(--ink-faint); font-size: .78rem; line-height: 1.45;
}
.system-node {
  position: absolute; z-index: 2; min-width: 5rem; padding: .42rem .68rem;
  border: 1px solid var(--line-strong); border-radius: 999px;
  background: rgba(7, 19, 26, .9); color: var(--gold-2);
  font-size: .67rem; line-height: 1.2; letter-spacing: .08em; text-align: center;
  box-shadow: 0 7px 18px rgba(0, 0, 0, .28);
}
.system-node.node-main {
  left: 50%; top: 43%; transform: translate(-50%, -50%);
  border-color: rgba(240, 128, 32, .62); color: var(--ember-2);
}
.system-link {
  position: absolute; z-index: 1; left: 50%; top: 43%; width: 34%; height: 1px;
  transform-origin: left; background: linear-gradient(90deg, var(--gold), rgba(79, 179, 191, .26));
}
.system-link::after {
  content: ""; position: absolute; right: -2px; top: -2px; width: 5px; height: 5px;
  border-radius: 50%; background: var(--moss-2);
}
.system-link.link-a { transform: rotate(-145deg); }
.system-link.link-b { transform: rotate(-28deg); }
.system-link.link-c { transform: rotate(55deg); width: 31%; }
.village-panel .node-a { left: 4%; top: 9%; }
.village-panel .node-b { right: 2%; top: 16%; }
.village-panel .node-c { right: 5%; bottom: 3%; }

.magic-ring {
  position: absolute; left: 50%; top: 43%; aspect-ratio: 1; border-radius: 50%;
  transform: translate(-50%, -50%); border: 1px solid rgba(217, 168, 78, .34);
}
.magic-ring::before, .magic-ring::after {
  content: ""; position: absolute; width: 6px; height: 6px; border-radius: 50%;
  background: var(--ember-2); box-shadow: 0 0 12px rgba(240, 128, 32, .7);
}
.magic-ring::before { left: 9%; top: 22%; }
.magic-ring::after { right: 3%; bottom: 29%; background: var(--moss-2); box-shadow: 0 0 12px rgba(79, 179, 191, .6); }
.magic-ring.ring-outer { width: 54%; }
.magic-ring.ring-inner { width: 32%; border-color: rgba(79, 179, 191, .4); }
.magic-core {
  position: absolute; left: 50%; top: 43%; transform: translate(-50%, -50%);
  color: var(--ember-2); font-size: 2.2rem; line-height: 1;
  text-shadow: 0 0 22px rgba(240, 128, 32, .75);
}
.magic-panel .node-a { left: 1%; top: 5%; }
.magic-panel .node-b { right: 0; top: 18%; }
.magic-panel .node-c { left: 8%; bottom: 0; }

.airship-balloon {
  position: absolute; left: 50%; top: 9%; width: 56%; height: 35%;
  transform: translateX(-50%); border: 1px solid rgba(217, 168, 78, .56);
  border-radius: 50%; background:
    linear-gradient(90deg, transparent 48%, rgba(217, 168, 78, .28) 49% 51%, transparent 52%),
    radial-gradient(ellipse at 50% 70%, rgba(240, 128, 32, .2), transparent 58%),
    rgba(12, 30, 39, .78);
  box-shadow: inset 0 -10px 24px rgba(240, 128, 32, .08), 0 0 30px rgba(217, 168, 78, .08);
}
.airship-rig { position: absolute; z-index: 1; top: 40%; width: 1px; height: 27%; background: rgba(217, 168, 78, .48); }
.airship-rig.rig-a { left: 37%; transform: rotate(-12deg); }
.airship-rig.rig-b { right: 37%; transform: rotate(12deg); }
.airship-hull {
  position: absolute; z-index: 2; left: 50%; top: 62%; width: 42%; height: 13%;
  transform: translateX(-50%); display: flex; align-items: center; justify-content: center; gap: 10%;
  border: 1px solid rgba(217, 168, 78, .58); border-radius: 5px 5px 50% 50%;
  background: linear-gradient(180deg, #6e3a1f, #301c17); box-shadow: 0 10px 18px rgba(0, 0, 0, .34);
}
.airship-hull i { width: 7px; height: 7px; border-radius: 2px; background: var(--ember-2); box-shadow: 0 0 9px rgba(240, 128, 32, .65); }
.airship-panel .node-a { left: 1%; bottom: 0; }
.airship-panel .node-b { right: 1%; bottom: 0; }

/* ---------- BlueMap: Zugang, Datenschutz und Aktualitaet auf einen Blick ---------- */
.map-section::before {
  content: ""; position: absolute; inset: 8% 0; pointer-events: none;
  background: radial-gradient(ellipse 48% 55% at 82% 48%, rgba(16, 128, 144, .13), transparent 72%);
}
.map-card {
  position: relative; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(360px, .95fr);
  overflow: hidden; border: 1px solid var(--line); border-radius: calc(var(--radius) + 4px);
  background: linear-gradient(145deg, rgba(12, 30, 39, .98), rgba(7, 19, 26, .98));
  box-shadow: 0 25px 70px rgba(0, 0, 0, .42), inset 0 1px rgba(255, 255, 255, .025);
}
.map-card::before {
  content: ""; position: absolute; z-index: 2; left: 7%; right: 48%; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--ember), var(--gold), transparent);
}
.map-copy { position: relative; z-index: 2; padding: clamp(2rem, 5vw, 3.6rem); }
.map-copy h3 { font-size: clamp(1.55rem, 3vw, 2.2rem); margin-bottom: .55rem; }
.map-copy > p:not(.map-access) { max-width: 52ch; margin: 0; color: var(--ink-dim); }
.map-access {
  display: inline-flex; align-items: center; gap: .48rem; margin: 0 0 1.2rem;
  padding: .34rem .72rem; border: 1px solid var(--line-strong); border-radius: 999px;
  color: var(--gold); background: rgba(217, 168, 78, .055);
  font-size: .68rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.map-access svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.map-facts { display: grid; gap: .8rem; margin: 1.65rem 0 1.8rem; }
.map-facts p { display: grid; grid-template-columns: 32px 1fr; gap: .78rem; align-items: start; margin: 0; color: var(--ink-faint); font-size: .84rem; line-height: 1.45; }
.map-facts svg {
  width: 32px; height: 32px; padding: 6px; border: 1px solid var(--line); border-radius: 9px;
  fill: none; stroke: var(--moss-2); stroke-width: 1.65; stroke-linecap: round; stroke-linejoin: round;
  background: rgba(16, 128, 144, .07);
}
.map-facts strong { display: block; margin-bottom: .08rem; color: var(--ink); font-size: .88rem; }
.map-button { gap: .72rem; }
.map-button span { font-size: 1.12em; transition: transform var(--dur-1) var(--ease-ember); }
.map-button:hover span { transform: translateX(3px); }

.map-visual {
  position: relative; min-height: 440px; overflow: hidden; border-left: 1px solid var(--line);
  background:
    radial-gradient(circle at 71% 26%, rgba(217, 168, 78, .17), transparent 9%),
    radial-gradient(ellipse 38% 30% at 69% 27%, rgba(62, 106, 75, .46), transparent 70%),
    radial-gradient(ellipse 46% 36% at 32% 72%, rgba(34, 93, 92, .62), transparent 73%),
    radial-gradient(ellipse 27% 34% at 88% 78%, rgba(67, 83, 57, .46), transparent 74%),
    linear-gradient(155deg, #102e36, #0a1e27 52%, #101b22);
}
.map-visual::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(7, 19, 26, .58), transparent 18%, transparent 82%, rgba(7, 19, 26, .38));
}
.map-visual-head {
  position: absolute; z-index: 4; top: 1.25rem; left: 1.25rem; right: 1.25rem;
  display: flex; justify-content: space-between; align-items: baseline;
  color: var(--ink-faint); font-size: .62rem; letter-spacing: .14em; text-transform: uppercase;
}
.map-visual-head b { color: var(--gold); font-family: var(--font-display); font-size: .78rem; letter-spacing: .18em; }
.map-lines { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; }
.map-lines .contour { fill: none; stroke: rgba(79, 179, 191, .2); stroke-width: 1.2; }
.map-lines .map-route { fill: none; stroke: rgba(240, 224, 192, .5); stroke-width: 2; stroke-dasharray: 5 6; }
.map-marker {
  position: absolute; z-index: 3; display: flex; align-items: center; gap: .42rem;
  padding: .3rem .55rem .3rem .38rem; border: 1px solid rgba(217, 168, 78, .35); border-radius: 999px;
  background: rgba(7, 19, 26, .88); color: var(--gold-2); font-size: .65rem; letter-spacing: .06em;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .4); transition: border-color var(--dur-1) var(--ease-ember), transform var(--dur-1) var(--ease-ember);
}
.map-marker i { width: 8px; height: 8px; border-radius: 50%; background: var(--ember-2); box-shadow: 0 0 10px rgba(240, 128, 32, .75); }
.map-marker.marker-town { left: 17%; top: 66%; }
.map-marker.marker-area { right: 14%; top: 23%; }
.map-marker.marker-area i { background: var(--moss-2); box-shadow: 0 0 10px rgba(79, 179, 191, .72); }
.map-marker.marker-market { right: 21%; bottom: 19%; }
.map-visual:hover .map-marker { border-color: rgba(217, 168, 78, .58); }
.map-compass {
  position: absolute; z-index: 3; right: 1.3rem; bottom: 1.2rem; display: grid; place-items: center;
  width: 34px; height: 34px; border: 1px solid var(--line-strong); border-radius: 50%;
  color: var(--ember-2); background: rgba(7, 19, 26, .72); font: 600 .72rem var(--font-display);
}
.map-compass::before { content: ""; position: absolute; top: -7px; border: 4px solid transparent; border-bottom-color: var(--ember-2); }

/* ---------- Emberwake 3D: optionale Zusatzpakete ---------- */
/* Voraussetzungs-Hinweis: Glutkante links, damit er vor den Karten gelesen wird */
.req-note {
  display: flex; align-items: flex-start; gap: .9rem;
  max-width: 780px; margin: 0 0 2.6rem;
  padding: 1.1rem 1.3rem;
  background: linear-gradient(180deg, rgba(18, 48, 57, .8), rgba(12, 30, 39, .5));
  border: 1px solid var(--line);
  border-left: 2px solid var(--ember);
  border-radius: var(--radius);
  color: var(--ink-dim); font-size: .93rem;
}
.req-note strong { color: var(--ink); }
/* Glimmt langsam auf und ab — „Glut, nicht Blitz" */
.req-flame {
  flex: none; color: var(--ember-2); font-size: .72rem; line-height: 2.3;
  animation: ew-req-glow 4.5s ease-in-out infinite alternate;
}
@keyframes ew-req-glow {
  from { opacity: .45; filter: none; }
  to { opacity: 1; filter: drop-shadow(0 0 7px rgba(240, 128, 32, .75)); }
}

.dl-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.3rem; margin-bottom: 2.6rem; }
.dl-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.7rem 1.5rem 1.5rem;
  overflow: hidden;
  transition: border-color var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
/* Glut-Linie am oberen Rand glimmt bei Hover auf — wie bei .card */
.dl-card::before {
  content: ""; position: absolute; top: 0; left: 12%; right: 12%; height: 1px;
  background: var(--grad-ember); opacity: 0;
  transition: opacity var(--dur-1) var(--ease-ember), left var(--dur-1) var(--ease-ember), right var(--dur-1) var(--ease-ember);
}
.dl-card:hover {
  border-color: var(--line-strong);
  box-shadow: 0 14px 38px rgba(0, 0, 0, .55), 0 0 24px rgba(240, 128, 32, .11);
}
.dl-card:hover::before { opacity: 1; left: 4%; right: 4%; }
.dl-card h3 { font-size: 1.12rem; letter-spacing: .03em; }
.dl-card p { margin: 0 0 1rem; color: var(--ink-dim); font-size: .92rem; line-height: 1.6; }
/* Der Ablageort steht direkt über dem Knopf, der Knopf schiebt sich nach unten */
.dl-card .dl-target { margin-bottom: 1.1rem; color: var(--ink-faint); font-size: .86rem; }
.dl-card .btn { align-self: flex-start; margin-top: auto; }
.dl-card .btn.is-disabled {
  opacity: .58;
  cursor: not-allowed;
  pointer-events: none;
}
.dl-card .dl-license {
  margin: .8rem 0 0;
  font-size: .78rem;
}
.dl-card .dl-license a { color: var(--gold-2); text-decoration: underline; text-underline-offset: .18em; }
.dl-card .dl-warning {
  padding: .72rem .8rem;
  color: var(--ink-dim);
  background: rgba(240, 128, 32, .07);
  border: 1px solid rgba(240, 128, 32, .22);
  border-radius: 8px;
}
.dl-card .dl-warning strong { color: var(--gold-2); }
.tag.tag-warning { color: #ffd2a3; border-color: rgba(240, 128, 32, .38); }
#downloads code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .88em; color: var(--gold-2);
  background: var(--bg-3); border: 1px solid var(--line); border-radius: 6px;
  padding: .08rem .4rem;
  overflow-wrap: anywhere;
}
/* Prüfsumme: darf umbrechen, sprengt auf Mobil nie das Layout */
.dl-card .dl-hash {
  margin: 1.1rem 0 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .68rem; line-height: 1.55; color: var(--ink-faint);
  overflow-wrap: anywhere; word-break: break-all;
}
.dl-card .dl-hash b {
  display: block; font-weight: 600;
  font-size: .62rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold); word-break: normal;
}
/* Installationsschritte — gleiche Optik wie .join-steps, aber vier Kacheln */
.dl-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.3rem; text-align: left; }

/* ---------- Roadmap ---------- */
.roadmap { position: relative; max-width: 720px; margin-inline: auto; padding-left: 2.2rem; }
/* Die Zeitlinie „zieht sich" beim Erscheinen nach unten */
.roadmap::before {
  content: ""; position: absolute; left: 8px; top: 6px; bottom: 6px; width: 1px;
  background: linear-gradient(180deg, var(--gold), var(--moss) 55%, rgba(79, 179, 191, .06));
  transform: none; transform-origin: top;
  transition: transform 1.4s var(--ease-ember) .2s;
}
html.js .roadmap::before { transform: scaleY(0); }
html.js .roadmap.in::before { transform: scaleY(1); }
.roadmap-item { position: relative; padding-bottom: 2.2rem; }
.roadmap-item:last-child { padding-bottom: 0; }
.roadmap-item::before {
  content: ""; position: absolute; left: calc(-2.2rem + 4px); top: 8px;
  width: 9px; height: 9px; transform: rotate(45deg);
  background: var(--bg); border: 1px solid var(--gold);
  transition: background var(--dur-1) var(--ease-ember), box-shadow var(--dur-1) var(--ease-ember);
}
.roadmap-item:hover::before {
  background: var(--ember); box-shadow: 0 0 12px rgba(240, 128, 32, .75);
}
.roadmap-item h3 { font-size: 1.15rem; margin-bottom: .2em; }
.roadmap-item p { margin: 0; color: var(--ink-dim); font-size: .94rem; }
.tag {
  display: inline-block; font-size: .64rem; letter-spacing: .14em; text-transform: uppercase;
  border: 1px solid var(--line-strong); border-radius: 999px;
  padding: .16rem .6rem; margin-left: .6rem; vertical-align: 2px;
  color: var(--gold);
}

/* ---------- Mitspielen / Join ---------- */
.join { text-align: center; }
.join-card {
  max-width: 560px; margin: 0 auto 2.6rem;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 2.2rem 2rem;
  position: relative; overflow: hidden;
}
.join-card::before {
  content: ""; position: absolute; inset: -40% -20% auto; height: 80%;
  background: radial-gradient(ellipse 60% 60% at 50% 0%, rgba(240, 128, 32, .14), transparent 70%);
  pointer-events: none;
}
.join-card h3 { margin: .8rem 0 .55rem; }
.join-access-copy {
  max-width: 32rem; margin: 0 auto; color: var(--ink-dim); font-size: .92rem;
}
.join-actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .7rem;
  margin: 1.25rem 0 .8rem;
}
.join-note { font-size: .8rem; color: var(--ink-faint); margin-top: .4rem; }
.eyebrow {
  margin: 0;
  color: var(--ink-faint);
  font-size: .78rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.join-steps {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.3rem;
  max-width: 860px; margin-inline: auto; text-align: left;
}
.join-step { position: relative; padding: 1.4rem 1.3rem 1.2rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg-2); }
.join-step b {
  display: block; font-family: var(--font-display); font-size: 1.9rem;
  /* .5 ergab auf dem neuen Kartengrund nur 2,89:1 und verfehlte damit die
     3:1 fuer grosse Schrift (1.9rem). .6 bringt 3,63:1 und laesst die Ziffer
     trotzdem zurueckhaltend. */
  color: var(--gold); opacity: .6; line-height: 1; margin-bottom: .5rem;
}
.join-step p { margin: 0; font-size: .92rem; color: var(--ink-dim); }

/* ---------- Fehler melden ---------- */
.report { text-align: center; }
.report-cta { margin: 0; }
.report-hint {
  margin: 1.4rem auto 0; max-width: 560px;
  font-size: .82rem; color: var(--ink-faint);
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--line);
  padding: 3.2rem 0 2.4rem;
  background: linear-gradient(180deg, rgba(18, 48, 57, .35), var(--bg));
  font-size: .88rem; color: var(--ink-faint);
}
.footer-grid {
  display: flex; flex-wrap: wrap; gap: 2rem; justify-content: space-between; align-items: flex-start;
  margin-bottom: 2rem;
}
.footer-brand { display: flex; align-items: center; gap: .7rem; color: var(--ink-dim); }
.footer-brand img { width: 34px; height: 34px; }
.footer-links { display: flex; gap: 1.6rem; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.footer-links a { color: var(--ink-faint); }
.footer-links a:hover { color: var(--gold-2); }
.disclaimer {
  border-top: 1px solid var(--line);
  padding-top: 1.6rem;
  font-size: .78rem; line-height: 1.7;
  max-width: 760px;
}

/* ---------- Oeffentliche Minimal-Vorschau ---------- */
.preview-hero { min-height: min(820px, 92svh); }
.preview-status { padding-top: clamp(3.5rem, 7vw, 6rem); padding-bottom: 0; text-align: center; }
.preview-status .join-card { margin-bottom: 0; max-width: 720px; }
.preview-community { border-top: 1px solid var(--line); }
.social-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .8rem;
  margin: 1.8rem auto 1rem;
}

/* ---------- Rechtstexte (Prose) ---------- */
.prose {
  max-width: 760px; margin-inline: auto;
  padding-top: calc(var(--nav-h) + 3rem);
}
.prose h1 { font-size: clamp(1.9rem, 5vw, 2.6rem); margin-bottom: 1.2rem; }
.prose h2 {
  font-size: 1.25rem; margin-top: 2.4em; letter-spacing: .03em;
  padding-bottom: .4rem; border-bottom: 1px solid var(--line);
}
.prose p, .prose li { color: var(--ink-dim); }
.prose strong { color: var(--ink); }
.prose .todo {
  display: inline-block;
  background: rgba(240, 128, 32, .14);
  border: 1px dashed rgba(240, 128, 32, .55);
  border-radius: 6px; padding: 0 .45rem;
  color: var(--ember-2); font-style: normal;
}
.prose .back { display: inline-block; margin: 2.5rem 0 4rem; }

/* ---------- Der Abbrand: Ranken-Schleier (vines.js, DESIGN.md §4.8) ---------- */
.vine-veil {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0;
  opacity: .3;
  /* Ranken rahmen die Sektion an den Raendern, statt Text zu durchkreuzen. */
  -webkit-mask-image: linear-gradient(90deg, #000 0, rgba(0,0,0,.7) 13%, transparent 34%, transparent 66%, rgba(0,0,0,.7) 87%, #000 100%);
  mask-image: linear-gradient(90deg, #000 0, rgba(0,0,0,.7) 13%, transparent 34%, transparent 66%, rgba(0,0,0,.7) 87%, #000 100%);
}
#world, #map { isolation: isolate; }
#world > .container, #map > .container { position: relative; z-index: 1; }
.vine-veil svg { display: block; width: 100%; height: 100%; }
/* Nach vollem Abbrand bleibt nur ein Asche-Hauch zurück */
.vine-veil.done svg { opacity: .24; transition: opacity 1s var(--ease-ember); }
.vl {
  transform-box: fill-box; transform-origin: 0% 50%;
}
/* Die Glutfront entzündet das Blatt: aufglühen → verkohlen → abfallen */
.vl.burning { animation: ew-leaf-burn 1.1s var(--ease-ember) forwards; }
@keyframes ew-leaf-burn {
  0% { fill: #4fb3bf; opacity: 1; transform: none; }
  28% { fill: #ffb347; filter: drop-shadow(0 0 6px rgba(240, 128, 32, .9)); opacity: 1; }
  100% { fill: #33454c; filter: none; opacity: 0; transform: translate(3px, 15px) rotate(28deg) scale(.6); }
}

/* ---------- Zündschnur: Scroll-Fortschritt als brennende Lunte ---------- */
.fuse { position: fixed; inset: 0 0 auto 0; height: 3px; z-index: 90; pointer-events: none; }
.fuse-burn {
  height: 100%; transform-origin: 0 50%; transform: scaleX(0);
  background: linear-gradient(90deg, rgba(217, 168, 78, .2), var(--gold) 55%, var(--ember) 88%, var(--ember-2));
}
.fuse-tip {
  position: absolute; top: 50%; left: 0; width: 7px; height: 7px; margin: -3.5px 0 0 -5px;
  border-radius: 50%; background: #ffd984; opacity: 0;
  box-shadow: 0 0 10px 2px rgba(240, 128, 32, .9), 0 0 24px 7px rgba(192, 64, 16, .5);
  animation: ew-tip-flicker 1.4s ease-in-out infinite;
}
@keyframes ew-tip-flicker {
  50% { box-shadow: 0 0 7px 1px rgba(240, 128, 32, .75), 0 0 16px 4px rgba(192, 64, 16, .35); }
}

/* ---------- Cursor-Glut: warmes Glühen folgt dem Zeiger im Hero ---------- */
.glow-cursor {
  position: absolute; top: 0; left: 0; width: 340px; height: 340px;
  border-radius: 50%; pointer-events: none; z-index: -1; opacity: 0;
  transition: opacity .6s var(--ease-ember); mix-blend-mode: screen; will-change: transform;
  background: radial-gradient(circle, rgba(240, 128, 32, .16), rgba(240, 128, 32, .05) 45%, transparent 70%);
}
@media (pointer: coarse) { .glow-cursor { display: none; } }

/* ---------- Scroll-Reveals ---------- */
.reveal {
  opacity: 1; transform: none;
  transition: opacity var(--dur-2) var(--ease-ember), transform var(--dur-2) var(--ease-ember);
  transition-delay: var(--d, 0s);
}
html.js .reveal { opacity: 0; transform: translateY(24px); }
html.js .reveal.in { opacity: 1; transform: none; }

/* ---------- Responsive ---------- */
/* Sieben Nav-Eintraege: erst enger setzen, dann aufs Burger-Menue umschalten */
@media (max-width: 1240px) {
  .nav-links { gap: 1.15rem; }
  .nav-links a { font-size: .88rem; }
}
/* 1080 -> 1100: unterhalb von 1100px sank der Abstand zwischen Marke und
   Links unter 30px, weil der Kontoknopf die rechte Gruppe um 60px verbreitert
   hat. Gemessen bei 1100px: 27px Rest. Das Burger-Menue uebernimmt daher
   etwas frueher, statt Eintraege zu streichen. */
@media (max-width: 1100px) {
  .nav-links {
    position: fixed; inset: var(--nav-h) 0 auto 0;
    flex-direction: column; gap: 0;
    background: rgba(7, 19, 26, .97);
    border-bottom: 1px solid var(--line);
    /* Die Seitenpolster tragen die sicheren Bereiche mit: im Querformat eines
       Geraets mit Aussparung sass der erste Buchstabe sonst unter der
       Kamera-Insel. Ohne Aussparung sind die env()-Werte 0 — dann bleiben es
       die urspruenglichen .6rem 1.5rem 1.2rem. */
    padding: .6rem
             calc(1.5rem + env(safe-area-inset-right))
             calc(1.2rem + env(safe-area-inset-bottom))
             calc(1.5rem + env(safe-area-inset-left));
    /* Auf flachen Fenstern scrollt das Menue, statt unter den Rand zu laufen */
    max-height: calc(100svh - var(--nav-h)); overflow-y: auto;
    transform: translateY(-8px); opacity: 0; visibility: hidden; pointer-events: none;
    transition: transform var(--dur-1) var(--ease-ember), opacity var(--dur-1) var(--ease-ember), visibility 0s linear var(--dur-1);
  }
  .nav-links.open {
    transform: none; opacity: 1; visibility: visible; pointer-events: auto;
    transition-delay: 0s;
  }
  .nav-links a { display: block; padding: .8rem 0; font-size: 1.05rem; }

  /* Sobald das Klappmenue uebernimmt, gehoeren „Mein Bereich" und „Abmelden"
     HINEIN — genau dafuer sind .nav-konto und .nav-abmelden im Markup
     angelegt. Hier stand aber ein zweites Mal wortgleich display:none, also
     dieselbe Regel wie in der Grundeinstellung: die beiden Eintraege wurden
     nie sichtbar (nachgemessen bei 360, 390, 414, 768 und 1100 px jeweils
     display:none). Ohne sie fuehrte im geschlossenen Bereich kein Weg aus dem
     Menue heraus zum eigenen Konto. */
  .nav-konto,
  .nav-abmelden { display: list-item; }
  .nav-konto a { display: flex; align-items: center; gap: .65rem; }
  .nav-konto img,
  .nav-konto .account-symbol {
    flex: none; width: 28px; height: 28px; border-radius: 50%;
    border: 1px solid var(--line); background: var(--bg-2);
  }
  .nav-konto img { object-fit: cover; }
  .nav-konto .account-symbol {
    box-sizing: border-box; padding: 5px; color: var(--gold-2);
  }
  /* Abmelden ist ein Formularknopf. Ohne diese Regeln stuende mitten in der
     Liste ein grauer Browserknopf; so liest er sich wie die Links daneben.
     --ink-dim auf dem Menuegrund rgba(7,19,26,.97) traegt 9,7:1. */
  .nav-abmelden form { margin: 0; }
  .nav-abmelden button {
    display: block; width: 100%; text-align: left;
    padding: .8rem 0; border: 0; background: none; cursor: pointer;
    font: inherit; font-size: 1.05rem; letter-spacing: .06em;
    color: var(--ink-dim);
    transition: color var(--dur-1) var(--ease-ember);
  }
  .nav-abmelden button:hover { color: var(--ink); }

  /* Der Abmelden-Knopf oben ist mit 136 px das breiteste Stueck der rechten
     Gruppe; bei 360 px blieben Marke und Emblem dadurch nur noch 36 px breit.
     Solange das Menue da ist, steht dieselbe Handlung dort — oben also weg. */
  .nav-abmelden-oben { display: none; }

  .nav-toggle { display: inline-flex; }
}

@media (max-width: 980px) {
  .features-grid { grid-template-columns: repeat(2, 1fr); }
  .principles .container { grid-template-columns: 1fr; gap: 1.6rem; }
  .dl-grid, .dl-steps { grid-template-columns: repeat(2, 1fr); }
  .dl-grid .dl-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .map-card { grid-template-columns: 1fr; }
  .map-card::before { right: 7%; }
  .map-visual { min-height: 340px; border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 760px) {
  .world-row { grid-template-columns: 1fr; }
  .world-row.flip .world-text { order: 0; }
  .system-panel { aspect-ratio: 16 / 10; }
  .shot-grid { grid-template-columns: 1fr; }
  .join-steps { grid-template-columns: 1fr; }
  .dl-grid, .dl-steps { grid-template-columns: 1fr; }
  .dl-grid .dl-card:last-child:nth-child(odd) { grid-column: auto; }
}
@media (max-width: 560px) {
  .features-grid { grid-template-columns: 1fr; }
  .req-note { flex-direction: column; gap: .4rem; }
  .system-panel { min-height: 290px; aspect-ratio: auto; }
  .shot figcaption, .shot-panel figcaption { font-size: .74rem; padding-inline: .95rem; }
  .system-node { min-width: 4.3rem; padding-inline: .5rem; font-size: .61rem; }
  .system-panel figcaption { font-size: .73rem; }
  .map-copy { padding: 1.7rem 1.25rem 2rem; }
  .map-access { font-size: .6rem; letter-spacing: .09em; }
  .map-visual { min-height: 285px; }
  .map-marker { font-size: .59rem; }

  /* Die Kopfzeile trug auf schmalen Geraeten zu viel nebeneinander: der
     Schriftzug „EMBERWAKERPG" allein misst rund 190px, dazu Kontoknopf,
     Sprach- bzw. Abmelden-Knopf und der Menuegriff. Gemessen bei 360px
     Fensterbreite reichte die rechte Gruppe bis 431px — der Menuegriff
     (389..431) lag vollstaendig ausserhalb des Bildes, auf den PHP-Seiten
     ebenso der Abmelden-Knopf (bis 459px). Sichtbar wurde das nie, weil
     body{overflow-x:hidden} den Ueberstand abschneidet; treffen liess sich
     der Knopf trotzdem nicht.
     Unterhalb von 560px bleibt darum nur das Emblem stehen. Der Link fuehrt
     unveraendert nach Hause und traegt sein aria-label, es geht also keine
     Beschriftung fuer Hilfsmittel verloren. Rechnung bei 360px: Spalte 312,
     Emblem 40 + 24 Abstand + rechte Gruppe (168 auf den statischen, 196 auf
     den PHP-Seiten) = 232 bzw. 260 — beides passt. */
  .brand-name { display: none; }
  /* Fuer den Fall, dass rechts noch etwas hinzukommt: die Gruppe darf enger
     ruecken, statt aus dem Bild zu laufen. Seit der Abmelden-Knopf unterhalb
     von 1100 px ins Menue gewandert ist, bleibt rechts nur noch Kontoknopf +
     Menuegriff: 44 + 11 + 44 = 99 px. Rechnung bei 360 px: Spalte 312, Emblem
     40 + 16 Abstand + 99 = 155 — reichlich Luft, das Emblem wird nicht mehr
     gestaucht. */
  .nav-inner { gap: 1rem; }
  .nav-right { gap: .7rem; }
}

/* Touch-Oberflaechen bekommen keinen klebenden Pseudo-Hover. Der sichtbare
   Fokus bleibt ueber :focus-visible weiterhin eindeutig. */
@media (hover: none), (pointer: coarse) {
  .brand:hover img { filter: none; }
  .btn:hover { transform: none; }
  .btn-primary:hover { box-shadow: 0 4px 22px rgba(240, 128, 32, .34); }
  .btn-primary:hover::after { transform: translateX(-110%); }
  .btn-ghost:hover { border-color: var(--line-strong); color: var(--ink); box-shadow: none; }
  .card:hover { --lift: 0px; border-color: var(--line); box-shadow: none; }
  .card:hover::before, .card:hover::after { opacity: 0; }
  .card:hover .icon { color: var(--gold); filter: none; transform: none; }
  .system-panel:hover { border-color: var(--line); transform: none; box-shadow: inset 0 1px rgba(255, 255, 255, .025), 0 18px 45px rgba(0, 0, 0, .3); }
  .map-button:hover span { transform: none; }
  .dl-card:hover { border-color: var(--line); box-shadow: none; }
  .dl-card:hover::before { opacity: 0; }
  .roadmap-item:hover::before { background: var(--bg); box-shadow: none; }
}

/* ---------- Geraete mit Aussparung (Notch, Dynamic Island, Home-Leiste) ----
   Bei randloser Browserdarstellung kann Inhalt bis unter Status- und
   Navigationsleisten reichen. Die sicheren Bereiche halten Kopfzeile und
   Fuss auch dann ausserhalb von Kamera-Insel und Home-Leiste.

   Ohne Aussparung — also in jedem Browserfenster am Schreibtisch — sind alle
   vier Werte 0; die Regeln aendern dort nichts. Nachgemessen: 1440 px vorher
   und nachher identisch. */
.container {
  /* border-box: die Aussenbreite bleibt, nur die Inhaltsspalte rueckt ein. */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}
.site-nav {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}
.site-footer { padding-bottom: calc(2.4rem + env(safe-area-inset-bottom)); }

/* ---------- Reduzierte Bewegung: alles ruhig, nur weiche Opacity ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }
  html.js .reveal { opacity: 1; transform: none; }
  html.js .roadmap::before { transform: none; }
  #embers { display: none; }
  /* Keine Schleier über Inhalten, keine Zeiger-Effekte — die Lunte bleibt als stille Fortschrittslinie */
  .vine-veil, .glow-cursor { display: none; }
  .card, .card:hover, .system-panel:hover { transform: none; }
  .shot-panel:hover, .shot:hover, .shot:focus-within { transform: none; }
  /* Die Lupe bleibt sichtbar statt aufzuglimmen — sonst waere sie nie zu sehen */
  html.js .shot-zoom { opacity: 1; transform: none; }
  .shot-view[open] img { animation: none; }
  .map-button:hover span { transform: none; }
  /* Der Glut-Punkt am Voraussetzungs-Hinweis hoert auf zu glimmen */
  .req-flame { animation: none; opacity: 1; }
  /* Das Emblem blieb hier unsichtbar: „ew-emblem-in" beginnt bei opacity 0,
     und in Verbindung mit dem endlosen „ew-float" haelt der Browser den
     Anfangs- statt den Endzustand fest (nachgemessen in Chrome: opacity 0,
     Bild vollstaendig geladen). Da die Regeln oben ohnehin jede Bewegung
     stillegen, wird das Emblem hier ausdruecklich sichtbar gesetzt — wie
     .reveal weiter oben auch. */
  .hero-emblem, .ash-emblem { animation: none; opacity: 1; transform: none; }
}
