/* ============================================================ MC-Vokabular
   Das Design der Infoseite (web/src/styles/tokens.css + mc.css), uebertragen
   auf den Tebex-Store. Farben, Abstaende und Schatten sind ZEICHENGLEICH mit
   dem Original - der Store soll nicht "aehnlich" aussehen, sondern gleich.

   Warum eine eigene Datei statt eines Imports: der Store laeuft auf fremder
   Infrastruktur (store.craftattack.me -> Tebex) und darf nicht davon abhaengen,
   dass craftattack.me gerade erreichbar ist. Wer drueben etwas an der Optik
   aendert, zieht es hier nach - die Stellen tragen denselben Klassennamen.

   Die Bildvariablen (--mc-*) stehen NICHT hier, sondern in _tokens.twig:
   ihre URLs kommen aus Tebex' asset(), und Twig laeuft in einer .css-Datei
   nicht. Diese Datei benutzt sie nur. */

/* ============================================================ Tokens
   Alles ausser den Bild-URLs. Quelle: web/src/styles/tokens.css */
:root {
  /* Grundtoene */
  --ink: #0b0b0e;
  --ink2: #141419;
  --gui: #c6c6c6;
  --slot: #8b8b8b;
  --edge: #373737;
  --txt: #3f3f3f;        /* Minecraft-Schriftfarbe auf hellen Panels */
  --txt-soft: #6b6b6b;
  --lt: #e9e9ec;
  --lt-soft: #a9a9b2;

  /* Minecraft-Chatfarben */
  --gold: #ffaa00;
  --yellow: #ffff55;
  --green: #55ff55;
  --aqua: #55ffff;
  --red: #ff5555;
  --purple: #c07bff;

  --f-pixel: 'Silkscreen', 'Courier New', monospace;
  --f-body: 'Inter', system-ui, -apple-system, sans-serif;
  --f-mono: 'JetBrains Mono', ui-monospace, monospace;

  --wrap: 1180px;
}

/* Der Tebex-Rechtsfuss laesst sich nicht ausblenden (Terms), aber faerben.
   Er sitzt unter unserem eigenen Fuss und soll dort nicht als Fremdkoerper
   aufblitzen - also dieselben Werte wie .foot-bot. */
:root {
  --tebex-legal-footer-background-color: #06060a;
  --tebex-legal-footer-text-color: #6a6a72;
  --tebex-legal-footer-border-color: rgba(255, 255, 255, 0.08);
  --tebex-legal-footer-max-width: 1180px;
  --tebex-legal-footer-logo-color: #6a6a72;
}

/* ============================================================ Basis */
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  position: relative;
  background: var(--ink);
  color: var(--lt);
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.6;
  /* Der Weltanschnitt ragt bewusst ueber die Seitenkante hinaus. */
  overflow-x: hidden;
}

img,
.px {
  image-rendering: pixelated;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 400;
  text-wrap: balance;
}

p {
  margin: 0;
}

a {
  color: inherit;
}

.wrap {
  width: min(var(--wrap), calc(100% - 40px));
  margin-inline: auto;
}

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 12px 18px;
  background: var(--ink2);
  color: var(--lt);
  font-family: var(--f-pixel);
  font-size: 13px;
  text-decoration: none;
}
.skip:focus {
  left: 8px;
  top: 8px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================ Weltanschnitt
   Senkrechter Schnitt durch eine Minecraft-Welt, von Gras bis Bedrock, mit der
   Seite mitscrollend. Ein Block misst 64px. Der Store ist kuerzer als die
   Infoseite - die Gesteinszonen wachsen ueber `flex` mit, die Uebergaenge
   behalten ihre feste Hoehe, damit sie sich nicht verzerren. */
.worldcut {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  display: flex;
  flex-direction: column;
}
/* Die Deckkraft sitzt an den Schichten, nicht am Anschnitt: die Erde ist
   Untergrund und darf nicht mit den hellen GUI-Fenstern konkurrieren. */
.worldcut .lay {
  display: block;
  image-rendering: pixelated;
  background-repeat: repeat;
  background-size: 2048px auto;
  opacity: 0.16;
}
.l-grass {
  flex: 0 0 64px;
  background-image: var(--mc-w-grass);
}
.l-dirt {
  flex: 1.5 1 0;
  min-height: 170px;
  background-image: var(--mc-w-dirt);
}
.l-dirt-stone {
  flex: 0 0 320px;
  background-image: var(--mc-w-dirt-stone);
}
.l-stone {
  flex: 1.7 1 0;
  min-height: 240px;
  background-image: var(--mc-w-stone);
}
.l-stone-deep {
  flex: 0 0 384px;
  background-image: var(--mc-w-stone-deep);
}
.l-deep {
  flex: 1.6 1 0;
  min-height: 240px;
  background-image: var(--mc-w-deep);
}
.l-deep-bed {
  flex: 0 0 320px;
  background-image: var(--mc-w-deep-bed);
}
.l-bedrock {
  flex: 0 0 256px;
  background-image: var(--mc-w-bedrock);
}
.worldcut-shade {
  position: fixed;
  inset: 0;
  z-index: 2;
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(255, 170, 0, 0.07), transparent 58%),
    radial-gradient(98% 78% at 50% 46%, rgba(11, 11, 14, 0.18), rgba(11, 11, 14, 0.6) 100%);
}

/* Alles Sichtbare liegt ueber dem Anschnitt. */
.aktion,
.topbar,
main,
footer {
  position: relative;
  z-index: 1;
}

/* ============================================================ Fenster
   Neun-Kachel-Rahmen aus dem echten Inventarfenster. */
.panel {
  border: 12px solid transparent;
  border-image: var(--mc-x-panel3) 12 fill repeat;
  color: var(--txt);
  font-family: var(--f-pixel);
}
.panel-dark {
  border: 12px solid transparent;
  border-image: var(--mc-x-panel-dark3) 12 fill repeat;
  color: var(--lt);
}
.panel-lg {
  border-width: 16px;
  border-image-source: var(--mc-x-panel4);
  border-image-slice: 16 fill;
}
.panel-dark.panel-lg {
  border-image-source: var(--mc-x-panel-dark4);
}

.gui-title {
  font-family: var(--f-pixel);
  font-size: 19px;
  color: var(--txt);
  letter-spacing: 0.02em;
  margin-bottom: 14px;
}
.gui-sub {
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--txt-soft);
  line-height: 1.55;
}

/* ============================================================ Slots */
.slot {
  width: var(--sl, 54px);
  height: var(--sl, 54px);
  display: grid;
  place-items: center;
  position: relative;
  background: var(--mc-x-slot) 0 0 / var(--sl, 54px) var(--sl, 54px);
  image-rendering: pixelated;
}
.icon {
  position: relative;
  z-index: 1;
  width: var(--is, 48px);
  height: var(--is, 48px);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  image-rendering: pixelated;
}
.count {
  position: absolute;
  right: 3px;
  bottom: 0;
  font-family: var(--f-pixel);
  font-size: 15px;
  color: #fff;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.75);
}
/* Nummernfeld: ein Inventarfeld, dessen Inhalt eine Zahl ist. */
.nrslot {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--ns, 64px);
  height: var(--ns, 64px);
  background: var(--mc-x-slot) 0 0 / var(--ns, 64px) var(--ns, 64px);
  image-rendering: pixelated;
  font-family: var(--f-pixel);
  font-size: var(--nf, 22px);
  line-height: 1;
  color: #fff;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
}

/* ============================================================ Knoepfe */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--f-pixel);
  font-size: 17px;
  letter-spacing: 0.02em;
  color: #e0e0e0;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.55);
  background: linear-gradient(#9a9a9a, #6d6d6d);
  padding: 16px 26px;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  box-shadow:
    inset 0 3px 0 rgba(255, 255, 255, 0.42),
    inset 3px 0 0 rgba(255, 255, 255, 0.22),
    inset -3px 0 0 rgba(0, 0, 0, 0.34),
    inset 0 -3px 0 rgba(0, 0, 0, 0.5),
    0 0 0 3px #000;
  transition:
    background 0.12s steps(2),
    color 0.12s;
}
.btn:hover,
.btn:focus-visible {
  background: linear-gradient(#93a8d6, #6f83b2);
  color: var(--yellow);
  outline: none;
}
.btn:focus-visible {
  box-shadow:
    inset 0 3px 0 rgba(255, 255, 255, 0.42),
    inset 3px 0 0 rgba(255, 255, 255, 0.22),
    inset -3px 0 0 rgba(0, 0, 0, 0.34),
    inset 0 -3px 0 rgba(0, 0, 0, 0.5),
    0 0 0 3px #000,
    0 0 0 6px var(--yellow);
}
.btn:active {
  transform: translateY(2px);
}
.btn-primary {
  background: linear-gradient(#4f9a4f, #31703a);
  color: #eaffea;
}
.btn-primary:hover,
.btn-primary:focus-visible {
  background: linear-gradient(#63b863, #3d8748);
  color: var(--yellow);
}
.btn-sm {
  font-size: 14px;
  padding: 11px 18px;
}
.btn .icon {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
}
/* Ein Knopf, den man nicht druecken kann, muss auch so aussehen. Im Store
   trifft das jedes Paket, das Tebex als nicht kaufbar meldet. */
.btn[disabled],
.btn[aria-disabled='true'] {
  background: linear-gradient(#5c5c5c, #454545);
  color: #97979d;
  cursor: not-allowed;
  pointer-events: none;
}

.mc-text {
  font-family: var(--f-pixel);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.62);
}

/* ============================================================ Aktionsbanner
   Ein Streifen über der Kopfleiste, an und aus in layout.html (AKTION_ENDE).
   Rot wie die Rabattmarke an den Paketen (.rabatt), damit Banner und
   durchgestrichener Preis als dieselbe Aussage gelesen werden; die Prozent-
   zahl steht als goldene Plakette davor - Gold ist auf der Seite die Farbe
   für „hier passiert etwas“. Die Kanten sind dieselben Lichtkanten wie an
   den Knöpfen, nur flacher: ein Streifen ist kein Bedienelement. */
.aktion {
  background: linear-gradient(#a83226, #7d221a);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.2),
    inset 0 -2px 0 rgba(0, 0, 0, 0.4);
  border-bottom: 3px solid #000;
}
.aktion-in {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 9px 0;
  /* Dieselbe Spalte wie die Kopfleiste darunter (.topbar-in). */
  width: min(1320px, calc(100% - 40px));
}
.aktion-marke {
  flex: 0 0 auto;
  padding: 4px 8px 3px;
  font-family: var(--f-pixel);
  font-size: 15px;
  line-height: 1.2;
  color: #2a1a00;
  white-space: nowrap;
  background: linear-gradient(#ffc640, #e08a00);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.45),
    inset 0 -2px 0 rgba(0, 0, 0, 0.3),
    0 0 0 2px #000;
}
.aktion-txt {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 12px;
  row-gap: 2px;
  font-family: var(--f-body);
  font-size: 14px;
  line-height: 1.4;
  color: #ffe9e4;
  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.45);
}
/* Die Frist bleibt beisammen: schmal fiel sonst das Datum allein in die
   nächste Zeile. */
.aktion-bis {
  white-space: nowrap;
}
.aktion-txt b {
  font-family: var(--f-pixel);
  font-size: 14px;
  font-weight: 400;
  color: var(--yellow);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.55);
}
@media (max-width: 640px) {
  /* Schmal untereinander statt nebeneinander: die Pixelschrift ist breit,
     und ein Umbruch mitten im Satz liest sich schlechter als zwei Zeilen. */
  .aktion-in {
    justify-content: flex-start;
    gap: 12px;
    padding: 8px 0;
  }
  .aktion-txt {
    flex-direction: column;
    font-size: 13px;
  }
  .aktion-txt b {
    font-size: 12px;
  }
}

/* ============================================================ Navigation */
.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  background: linear-gradient(rgba(9, 9, 12, 0.94), rgba(9, 9, 12, 0.82));
  border-bottom: 3px solid rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(6px);
}
.topbar-in {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 0;
  /* Dieselbe Breite wie drueben. Mit Start und den drei Regalen (Premium,
     Claimblöcke, Kampfmarken) passt die Leiste neben Marke, Anmeldung und
     Warenkorb ab rund 1240px in eine Zeile; darunter faellt sie in die
     zweite (Haltepunkt 1360px unten). Jede weitere Kategorie in Tebex ist
     ein Reiter mehr - wer welche ergaenzt, sieht in der Vorschau nach. */
  width: min(1320px, calc(100% - 40px));
}
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  flex: 0 0 auto;
}
.brand-mark {
  width: 40px;
  height: 40px;
  background: var(--logo) center / contain no-repeat;
}
.brand-txt {
  font-family: var(--f-pixel);
  font-size: 16px;
  color: var(--lt);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.6);
}
.brand-txt b {
  color: var(--gold);
  font-weight: 400;
}
/* Sagt, wo man ist - kein Ziel, deshalb als Marke abgesetzt statt eingereiht.
   Drueben steht hier "Server", hier "Store". */
.brand-bereich {
  display: inline-block;
  margin-left: 8px;
  padding: 3px 7px 2px;
  vertical-align: 2px;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #eaffea;
  background: linear-gradient(#4f9a4f, #31703a);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.28),
    inset 0 -2px 0 rgba(0, 0, 0, 0.42),
    0 0 0 2px #000;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}

.nav {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 2px;
}
/* Anmelden und Warenkorb stehen rechts NEBEN der Reiterleiste, nicht in ihr:
   sie fuehren nirgendwohin, sie zeigen einen Zustand. Deshalb auch nach dem
   Umbruch getrennt - die Reiter fallen in die zweite Zeile, der Korb bleibt
   oben beim Kopf. */
.kopf-rechts {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  padding: 2px;
}
.nav::-webkit-scrollbar {
  display: none;
}
.nv {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
  padding: 10px 14px;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--f-pixel);
  font-size: 13px;
  letter-spacing: 0.02em;
  color: #dcdce2;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.55);
  background: linear-gradient(#7c7c7c, #5a5a5a);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.36),
    inset 2px 0 0 rgba(255, 255, 255, 0.18),
    inset -2px 0 0 rgba(0, 0, 0, 0.32),
    inset 0 -2px 0 rgba(0, 0, 0, 0.48),
    0 0 0 2px #000;
  transition:
    background 0.12s steps(2),
    color 0.12s;
}
.nv:hover,
.nv:focus-visible {
  background: linear-gradient(#93a8d6, #6f83b2);
  color: var(--yellow);
  outline: none;
}
.nv:focus-visible {
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.36),
    inset 2px 0 0 rgba(255, 255, 255, 0.18),
    inset -2px 0 0 rgba(0, 0, 0, 0.32),
    inset 0 -2px 0 rgba(0, 0, 0, 0.48),
    0 0 0 2px #000,
    0 0 0 5px var(--yellow);
}
.nv.on {
  background: linear-gradient(#4f9a4f, #31703a);
  color: #eaffea;
}
.nv i {
  width: 22px;
  height: 22px;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  flex: 0 0 auto;
}
/* Namen duerfen bis 32 Zeichen lang sein (Bedrock: `.Gamertag`). Ungekuerzt
   schoebe ein langer Name die halbe Leiste aus dem Bild - der ganze Name steht
   im title- und aria-label-Attribut und im Warenkorb. */
.nv-name {
  max-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Die Beschriftung von Anmeldung und Warenkorb, damit sie schmal weichen kann.
   Der Knopf behaelt seinen Namen dabei ueber aria-label - ein Knopf, den nur
   ein Bild benennt, ist fuer eine Vorlesesoftware ein leerer Knopf. */
.nv-txt {
  display: inline-block;
  vertical-align: bottom;
}
/* Der Trenner setzt "Start" von den Regalen ab - Start ist ein Ort, die
   Regale sind Ware. Dieselbe Regel wie drueben in web/src/styles/mc.css. */
.nav-sep {
  flex: 0 0 auto;
  width: 3px;
  height: 28px;
  background: rgba(255, 255, 255, 0.18);
  margin: 0 9px;
}
/* Die Regalbilder sind gross gerechnet (das Schaufenster zeigt sie mit
   184 px) und werden hier glatt verkleinert statt `pixelated` - der naechste
   Nachbar schnitte aus 400 auf 26 px nur Treppen. Etwas groesser als die
   22-px-Symbole und mit negativem Rand, damit der Knopf nicht hoeher wird. */
.nv .nv-bild {
  width: 28px;
  height: 28px;
  margin: -4px 0;
  background-size: contain;
  background-position: center;
  image-rendering: auto;
  filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.55));
}

/* ============================================================ Abschnitte */
section {
  padding: 74px 0;
}
.sec-head {
  display: flex;
  align-items: flex-end;
  gap: 18px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}
.sec-eyebrow {
  font-family: var(--f-pixel);
  font-size: 12px;
  color: var(--gold);
  letter-spacing: 0.12em;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.6);
}
.sec-title {
  font-family: var(--f-pixel);
  font-size: clamp(22px, 3.4vw, 34px);
  color: var(--lt);
  text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.7);
  line-height: 1.2;
}
.sec-note {
  font-family: var(--f-body);
  font-size: 15px;
  color: var(--lt-soft);
  max-width: 60ch;
  margin-top: 6px;
}
.sec-head .spacer {
  flex: 1;
}

/* ============================================================ Seitenkopf
   Der Store hat keinen Hero mit Panoramabild - er ist ein Laden, kein
   Titelbildschirm. Geblieben ist der Pixel-Schriftzug in derselben Groesse und
   mit demselben Schatten, damit die Seite als dieselbe Marke gelesen wird. */
.kopfzeile {
  padding: 74px 0 0;
}
.kopfzeile-in {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}
.kopfzeile .marke {
  width: min(96px, 18vw);
  aspect-ratio: 1;
  flex: 0 0 auto;
  background: var(--logo) center / contain no-repeat;
  filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.55));
}
.kopf-wort {
  font-family: var(--f-pixel);
  font-size: clamp(28px, 5vw, 52px);
  line-height: 1;
  color: #fff;
  text-shadow: 5px 5px 0 rgba(0, 0, 0, 0.65);
  letter-spacing: -0.01em;
}
.kopf-wort b {
  color: var(--gold);
  font-weight: 400;
}
.kopf-claim {
  margin-top: 14px;
  max-width: 62ch;
  font-family: var(--f-body);
  font-size: 16px;
  line-height: 1.6;
  color: #dcdce4;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.7);
}

/* ============================================================ Hinweiskasten
   Uebernommen aus .disc der Infoseite: die Abgrenzung ganz oben auf der
   Serverseite. Hier traegt sie den Hinweis, wer verkauft und was ein Kauf
   nicht ist. */
.disc {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  padding: 20px 24px;
}
.disc-icon {
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  margin-top: 2px;
}
.disc b {
  display: block;
  font-family: var(--f-pixel);
  font-size: 15px;
  color: var(--lt);
  font-weight: 400;
  margin-bottom: 8px;
}
.disc span {
  display: block;
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--lt-soft);
  line-height: 1.6;
  max-width: 78ch;
}

/* Befehle, die man im Spiel eintippt. */
.cmd {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 0.92em;
  padding: 1px 6px;
  color: var(--yellow);
  background: #26262d;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.55);
  white-space: nowrap;
}

/* ============================================================ Meldungen
   Tebex meldet Erfolg und Fehler ueber store.userMessage. Als Inventar-Zeile
   mit Haken oder rotem Kreuz - dieselbe Bildsprache wie erlaubt/verboten im
   Regelwerk der Infoseite. */
.meldung {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px 20px;
  margin-bottom: 26px;
}
.meldung .disc-icon {
  width: 26px;
  height: 26px;
  margin-top: 1px;
}
.meldung-txt {
  font-family: var(--f-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--lt-soft);
}
.meldung-txt b {
  display: block;
  font-family: var(--f-pixel);
  font-size: 14px;
  font-weight: 400;
  margin-bottom: 6px;
  color: var(--lt);
}
.meldung.ist-fehler .meldung-txt b {
  color: var(--red);
}

/* ============================================================ Kategorien
   Uebernommen aus .fx-item: Karte mit Themensymbol links, Name und Zeile
   rechts. Das Symbol ist die Truhe - eine Kategorie ist ein Regal. */
.kats {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
}
.kat {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  padding: 16px 18px;
  text-decoration: none;
  transition: box-shadow 0.14s;
}
.kat:hover,
.kat:focus-visible {
  box-shadow: 0 0 0 3px rgba(255, 170, 0, 0.5);
  outline: none;
}
.kat .icon {
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
}
/* display:block, weil die Zeilen als <span> in einem <a> stehen - ein Link
   darf keine <div> enthalten, und inline flossen Name, Anzahl und
   Beschreibung sonst zu einem Absatz zusammen. */
.kat-name {
  display: block;
  font-family: var(--f-pixel);
  font-size: 15px;
  color: var(--txt);
}
.kat-zahl {
  display: block;
  font-family: var(--f-pixel);
  font-size: 12px;
  color: #5a7f5a;
  margin-top: 2px;
}
.kat-txt {
  display: block;
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--txt-soft);
  line-height: 1.55;
  margin-top: 8px;
}

/* ============================================================ Pakete
   Ein Paket ist ein Gegenstand: Bild im Inventarfeld, Name in Pixelschrift,
   Preis in Monospace wie die Serveradresse - Zahlen, die man vergleicht,
   gehoeren in eine Schrift mit fester Breite.

   Zwei Anordnungen, weil Tebex sie kennt (category.displayType): Raster fuer
   Ware mit Bild, Liste fuer lange Namen. Beide benutzen dieselbe Karte. */
.pakete {
  display: grid;
  gap: 16px;
}
.pakete.ist-raster {
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.pakete.ist-liste {
  grid-template-columns: 1fr;
}

.pkt {
  display: flex;
  flex-direction: column;
  padding: 18px 20px;
  gap: 14px;
}
/* In der Liste steht das Bild links neben dem Text statt darueber. */
.pakete.ist-liste .pkt {
  flex-direction: row;
  align-items: flex-start;
  gap: 20px;
}
.pakete.ist-liste .pkt-kopf {
  flex: 0 0 auto;
}
.pakete.ist-liste .pkt-body {
  flex: 1;
  min-width: 0;
}
.pakete.ist-liste .pkt-fuss {
  flex: 0 0 auto;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  align-self: center;
}

.pkt-kopf {
  display: flex;
  align-items: center;
  gap: 14px;
}
/* Das Paketbild sitzt im Inventarfeld. Hat Tebex keins, bleibt das Feld leer
   und traegt die Truhe - besser ein leeres Feld als ein gedehntes Platzhalter-
   bild, das nach kaputt aussieht. */
.pkt-bild {
  --sl: 72px;
  --is: 60px;
  flex: 0 0 auto;
}
.pkt-bild img {
  width: 60px;
  height: 60px;
  object-fit: contain;
  image-rendering: pixelated;
}
.pkt-name {
  font-family: var(--f-pixel);
  font-size: 15px;
  color: var(--txt);
  line-height: 1.35;
}
.pkt-txt {
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--txt-soft);
  line-height: 1.55;
}
/* Tebex liefert die Beschreibung als HTML aus dem Panel. Die Ueberschriften
   und Listen darin bekommen hier Masse, sonst sprengen sie die Karte. */
.pkt-txt h1,
.pkt-txt h2,
.pkt-txt h3,
.pkt-txt h4 {
  font-family: var(--f-pixel);
  font-size: 14px;
  color: var(--txt);
  margin: 12px 0 6px;
}
.pkt-txt p {
  margin: 0 0 8px;
}
.pkt-txt ul,
.pkt-txt ol {
  margin: 0 0 8px;
  padding-left: 20px;
}
.pkt-txt img {
  max-width: 100%;
  height: auto;
}
.pkt-txt a {
  color: #2f6f3a;
}
/* Auf der Karte reicht der Anfang - die ganze Beschreibung steht auf der
   Paketseite. Ohne die Kappung wird aus einer Rasterzeile eine Textwand. */
.pkt-txt.ist-kurz {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pkt-fuss {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: auto;
}
.preis {
  font-family: var(--f-mono);
  font-size: 20px;
  font-weight: 700;
  color: #2f6f3a;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* Der alte Preis steht daneben, nicht darunter: durchgestrichen liest man ihn
   nur im Vergleich. `nowrap` wie beim neuen Preis - Betrag und Waehrungscode
   sind eine Angabe, und in der schmalen Rasterspalte brach der Code sonst in
   die naechste Zeile. */
.preis-alt {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 14px;
  color: var(--txt-soft);
  text-decoration: line-through;
  margin-left: 8px;
  white-space: nowrap;
}
.preis-hinweis {
  font-family: var(--f-pixel);
  font-size: 11px;
  color: var(--txt-soft);
  margin-top: 4px;
}
/* Rabattmarke in Minecraft-Rot, wie die Warnfarbe im Chat. */
.rabatt {
  display: inline-block;
  padding: 3px 7px 2px;
  font-family: var(--f-pixel);
  font-size: 11px;
  color: #fff;
  background: linear-gradient(#c0392b, #922b21);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.24),
    inset 0 -2px 0 rgba(0, 0, 0, 0.38),
    0 0 0 2px #000;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}
.pkt-grund {
  font-family: var(--f-body);
  font-size: 13px;
  color: #8a4b4b;
  line-height: 1.5;
}

/* ============================================================ Rangvergleich
   Alle Ränge in EINER Tabelle, wie man Tarife vergleicht: die Spalte ist der
   Rang, die Zeile der Vorteil. Eine echte <table> statt nebeneinandergelegter
   Karten - nur so steht jede Zeile auf gleicher Höhe, gleich wie lang ihr
   Text ist, und ein Screenreader sagt zu jedem Haken, zu welchem Rang und
   welchem Vorteil er gehört.

   Schmal passen vier Ränge nicht in 350 px. Die Tabelle wird dann seitlich
   geschoben, statt in gestapelte Karten zu zerfallen: gestapelt stünde
   „Homes 2" drei Bildschirme über „Homes 10", und genau den Blick
   nebeneinander soll sie bieten. Die erste Spalte klebt dabei links, damit
   beim Schieben klar bleibt, welche Zeile man liest. */
.vergleich-rahmen {
  padding: 4px 2px;
}
.vergleich-scroll {
  overflow-x: auto;
}
.vergleich {
  width: 100%;
  min-width: 720px;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  font-family: var(--f-body);
  color: var(--txt);
}
.vergleich .vg-spalte-merkmal {
  width: 30%;
}
.vergleich th,
.vergleich td {
  padding: 10px 12px;
  text-align: center;
  vertical-align: middle;
}
/* Die klebende Spalte braucht eine deckende Fläche, sonst schieben sich die
   Haken der Nachbarspalten sichtbar unter ihr durch. --gui ist die Füllung
   des Fensterrahmens. */
.vergleich th[scope='row'],
.vergleich .vg-ecke {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--gui);
  text-align: left;
}
.vergleich th[scope='row'] {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
}

/* Der Rangname steht auf einem Namensschild, in der Farbe, in der er im Chat
   erscheint. Auf dem hellen Fenster direkt wäre Gelb unlesbar. */
.vg-rang {
  vertical-align: bottom;
}
.vg-schild {
  display: block;
  padding: 9px 8px 8px;
  background: #2a2a30;
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.12),
    inset 0 -2px 0 rgba(0, 0, 0, 0.4),
    0 0 0 2px #000;
  font-family: var(--f-pixel);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.3;
  overflow-wrap: anywhere;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.6);
}
.vg-laufzeit {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--txt-soft);
}

.vg-kauf > * {
  padding-top: 12px;
  padding-bottom: 16px;
}
.vg-kauf .preis {
  display: block;
  font-size: 18px;
}
.vg-kauf > td {
  vertical-align: top;
}
.vg-kauf .preis-alt {
  display: block;
  margin: 0 0 2px;
}
.vg-kauf .preis-alt.ist-leer {
  text-decoration: none;
}
.vg-kauf .btn {
  width: 100%;
  margin-top: 10px;
  padding: 10px 8px;
  font-size: 12px;
  line-height: 1.3;
}
.vg-kauf .btn .icon {
  width: 18px;
  height: 18px;
}
.vg-details {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--f-pixel);
  font-size: 11px;
  color: #2f6f3a;
}
.vg-kauf-unten > * {
  border-top: 3px solid rgba(0, 0, 0, 0.18);
}

.vg-gruppe th {
  padding: 22px 12px 8px;
  text-align: left;
  font-family: var(--f-pixel);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.06em;
  border-bottom: 3px solid rgba(0, 0, 0, 0.18);
}
/* Die Überschrift spannt über alle Spalten und wanderte beim Schieben mit
   hinaus - ihr Text klebt deshalb wie die erste Spalte. */
.vg-gruppe th span {
  position: sticky;
  left: 12px;
}
.vergleich tbody tr:not(.vg-gruppe) > * {
  border-bottom: 2px solid rgba(0, 0, 0, 0.08);
}
.vergleich tbody tr:not(.vg-gruppe):hover > * {
  background: #bababa;
}
.vg-befehl {
  display: block;
  margin-top: 2px;
  font-family: var(--f-mono);
  font-size: 12px;
  font-weight: 400;
  color: #2f6f3a;
}

.vg-ja,
.vg-nein {
  display: inline-block;
  width: 22px;
  height: 22px;
  vertical-align: middle;
  background-size: 100% 100%;
  image-rendering: pixelated;
}
.vg-ja {
  background-image: var(--mc-u-check);
}
/* Das Kreuz leiser als der Haken: gesucht wird, was ein Rang HAT. */
.vg-nein {
  background-image: var(--mc-u-cancel);
  opacity: 0.4;
}
.vg-wert {
  font-family: var(--f-pixel);
  font-size: 14px;
}
/* Zahlen, die mit dem Rang wachsen. Das Plus ist eine kleine Plakette in der
   Farbe des Rangabzeichens (--rf, aus LOGOS in _rangvergleich.twig), gebaut
   wie das Abzeichen selbst: weiße Pixelschrift, Lichtkante oben, Schatten
   unten, schwarzer Rand. Der Abstand zwischen den Spalten ist das, was man
   hier vergleicht - er soll ins Auge springen. Darunter klein die Summe. Ein
   „+0" bleibt graue Schrift ohne Plakette und tritt zurück wie das Kreuz. */
.vg-zahl {
  display: block;
  font-family: var(--f-pixel);
  font-size: 15px;
  line-height: 1;
  white-space: nowrap;
}
.vg-ohne {
  margin-right: 2px;
  color: var(--txt);
}
.vg-plus {
  display: inline-block;
  padding: 5px 7px 4px;
  background: var(--rf, #2f6f3a);
  color: #fff;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.35);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.28),
    inset 0 -2px 0 rgba(0, 0, 0, 0.3),
    0 0 0 2px #1d1d1d;
}
.vg-plus.ist-null {
  padding-inline: 0;
  background: none;
  color: var(--txt-soft);
  text-shadow: none;
  box-shadow: none;
  opacity: 0.6;
}
.vg-summe {
  display: block;
  margin-top: 7px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--txt);
}
/* Das Rangabzeichen aus dem Resourcepack, 13 Pixel hoch und je Rang anders
   breit (--b, gesetzt in _rangvergleich.twig). Vergrößert nur um ganze
   Faktoren - bei 2,5-fach verschwämmen die Pixelkanten. */
.vg-logo {
  display: inline-block;
  width: calc(var(--b) * 2px);
  height: 26px;
  vertical-align: middle;
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  image-rendering: pixelated;
}
@media (min-width: 1100px) {
  .vg-logo {
    width: calc(var(--b) * 3px);
    height: 39px;
  }
}
.vg-offen {
  color: var(--txt-soft);
}
/* Der Vorteil in der Tabelle ist ein Sprung ins Lexikon, sieht aber aus wie
   Text mit gepunkteter Unterkante - ein blauer Link zöge den Blick von den
   Haken weg. */
.vg-info {
  color: inherit;
  text-decoration: underline dotted rgba(0, 0, 0, 0.35);
  text-underline-offset: 3px;
}
.vg-info:hover,
.vg-info:focus-visible {
  text-decoration-color: currentColor;
}
.vg-bild {
  display: block;
  width: 60px;
  height: 60px;
  margin: 0 auto 8px;
  image-rendering: pixelated;
}
/* „im Monat" steht in jeder Spalte, auch leer: sonst rutscht der Knopf einer
   Abo-Spalte eine Zeile tiefer als seine Nachbarn. */
.vg-kauf .vg-laufzeit.ist-leer {
  visibility: hidden;
}
/* Kein Knopf zum Kaufen in der Übersicht, sondern der Weg zum Paket. */
.kauf .btn-ansehen {
  white-space: nowrap;
}
.vg-hinweis {
  margin: 0;
  font-family: var(--f-body);
  padding: 12px 14px 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--txt-soft);
}

/* ------------------------------------------------------------ Lexikon
   Ein dunkler Balken unter der hellen Tabelle - er soll als Knopf gelesen
   werden, nicht als weiteres Fenster. Aufgeklappt Karten in einem Raster:
   Fließtext statt Pixelschrift, weil hier Sätze stehen. */
.vg-lexikon {
  margin-top: 18px;
  background: #1c1c22;
  box-shadow:
    inset 0 3px 0 rgba(255, 255, 255, 0.08),
    inset 0 -3px 0 rgba(0, 0, 0, 0.45),
    0 0 0 3px #000;
}
.vg-lexikon-kopf {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 22px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.vg-lexikon-kopf::-webkit-details-marker {
  display: none;
}
.vg-lexikon-kopf:hover {
  background: rgba(255, 255, 255, 0.04);
}
.vg-lexikon-kopf:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: -3px;
}
.vg-lexikon-icon {
  flex: none;
  width: 36px;
  height: 36px;
  background: var(--mc-c-letter) center / 100% 100% no-repeat;
  image-rendering: pixelated;
}
.vg-lexikon-titel {
  flex: 1;
  min-width: 0;
  display: grid;
  gap: 4px;
}
.vg-lexikon-titel b {
  font-family: var(--f-pixel);
  font-size: 16px;
  font-weight: 400;
  color: var(--lt);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.6);
}
.vg-lexikon-titel span {
  font-family: var(--f-body);
  font-size: 13px;
  color: var(--lt-soft);
}
/* Ein Pfeil aus zwei Kanten, dreht beim Öffnen - ohne Zeichen aus der
   Pixelschrift, der fehlte das Minus. */
.vg-lexikon-pfeil {
  flex: none;
  width: 12px;
  height: 12px;
  margin-right: 6px;
  border-right: 3px solid var(--gold);
  border-bottom: 3px solid var(--gold);
  transform: rotate(45deg) translate(-3px, -3px);
  transition: transform 0.15s ease;
}
.vg-lexikon[open] .vg-lexikon-pfeil {
  transform: rotate(225deg) translate(-3px, -3px);
}
.vg-lexikon-inhalt {
  padding: 4px 22px 22px;
  border-top: 3px solid rgba(0, 0, 0, 0.5);
}
.vg-lexikon-gruppe {
  margin-top: 18px;
}
.vg-lexikon-gruppe-titel {
  margin: 0 0 10px;
  font-family: var(--f-pixel);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.08em;
  color: var(--gold);
}
.vorteile {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 10px;
}
.vorteil {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  background: #26262d;
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.06),
    0 0 0 2px #000;
  scroll-margin-top: 90px;
}
.vorteil.ist-ziel {
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.06),
    0 0 0 3px var(--gold);
}
.vorteil-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 10px;
}
.vorteil-name {
  margin: 0;
  font-family: var(--f-body);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--lt);
}
/* Die Stufe in der Farbe, in der der Rang im Chat steht. */
.vorteil-ab {
  flex: none;
  padding: 4px 7px 3px;
  font-family: var(--f-pixel);
  font-size: 10px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  background: #111115;
  box-shadow: 0 0 0 2px #000;
}
.vorteil-ab-klein,
.vorteil-ab-mittel {
  color: #ffaa00;
}
.vorteil-ab-gross {
  color: #ff55ff;
}
.vorteil-ab-ultra {
  color: #ffff55;
}
.vorteil-txt {
  margin: 0;
  font-family: var(--f-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--lt-soft);
}
.vorteil-cmd {
  align-self: flex-start;
  margin-top: auto;
}
@media (max-width: 640px) {
  .vg-lexikon-kopf {
    padding: 14px 16px;
    gap: 12px;
  }
  .vg-lexikon-icon {
    width: 28px;
    height: 28px;
  }
  .vg-lexikon-inhalt {
    padding: 0 12px 16px;
  }
  .vorteile {
    grid-template-columns: 1fr;
  }
}

/* Gadgets und Kosmetik: Karten wie die Kategorien, aber ohne Link - gekauft
   wird im Spiel, nicht hier. */
.spass {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 14px;
}
.spass-karte {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px 18px;
}
.spass-karte .slot {
  flex: none;
}
.spass-name {
  display: block;
  font-family: var(--f-pixel);
  font-size: 14px;
  color: var(--txt);
}
.spass-txt {
  display: block;
  font-family: var(--f-body);
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--txt-soft);
}
.spass-preis {
  display: inline-block;
  margin-top: 6px;
  font-family: var(--f-pixel);
  font-size: 11px;
  color: #8a1f1f;
}

/* ============================================================ Schaufenster
   Die drei Regale, fuer die fast alle kommen - Ränge, Land, Marken - ganz
   oben auf der Startseite. Dunkle Fenster statt heller, damit sie sich von
   der Ware darunter abheben, und die Farbe des Regals nur als Licht hinter
   dem Bild: das Bild traegt die Farbe, das Fenster bleibt ruhig.

   Bewegung gibt es genau eine, und langsam: das Bild schwebt um ein paar
   Pixel, versetzt je Fenster, damit die drei nicht im Takt nicken. Bei
   prefers-reduced-motion steht es still (Basisregel oben). */
.schaufenster-sec {
  padding: 34px 0 0;
}
.schaufenster {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
.fenster {
  --akzent: var(--gold);
  --schein: rgba(255, 170, 0, 0.26);
  --ring: rgba(255, 170, 0, 0.55);
  display: flex;
  flex-direction: column;
  padding: 4px 22px 22px;
  text-decoration: none;
  transition: box-shadow 0.18s;
}
.fenster.ist-claimblocks,
.kopfzeile-regal.ist-claimblocks {
  --akzent: var(--green);
  --schein: rgba(85, 255, 85, 0.17);
  --ring: rgba(85, 255, 85, 0.45);
}
.fenster.ist-marks,
.kopfzeile-regal.ist-marks {
  --akzent: var(--red);
  --schein: rgba(255, 85, 85, 0.22);
  --ring: rgba(255, 85, 85, 0.5);
}
.kopfzeile-regal.ist-premium {
  --schein: rgba(255, 170, 0, 0.26);
}
.fenster:hover,
.fenster:focus-visible {
  box-shadow: 0 0 0 3px var(--ring);
  outline: none;
}

/* Die Buehne: ein Lichtkreis in der Regalfarbe, darauf das Bild. Der Kreis
   liegt in ::before, damit er beim Zeigen wachsen kann, ohne das Bild zu
   verschieben. */
.fenster-buehne,
.kopf-buehne {
  position: relative;
  display: grid;
  place-items: center;
}
.fenster-buehne {
  height: 214px;
  margin: 0 -8px 4px;
}
.fenster-buehne::before,
.kopf-buehne::before {
  content: '';
  position: absolute;
  inset: 6% 12%;
  background: radial-gradient(closest-side, var(--schein), transparent);
  transition:
    transform 0.25s,
    opacity 0.25s;
  opacity: 0.85;
}
.fenster:hover .fenster-buehne::before,
.fenster:focus-visible .fenster-buehne::before {
  transform: scale(1.12);
  opacity: 1;
}
/* Die Bilder sind gross gerechnet und werden verkleinert gezeigt - glatt
   skaliert, nicht `pixelated`: beim Verkleinern wuerde der naechste Nachbar
   nur Treppen ins Pixelmuster schneiden. */
.fenster-bild {
  position: relative;
  width: 184px;
  height: 184px;
  background: center / contain no-repeat;
  filter: drop-shadow(0 14px 10px rgba(0, 0, 0, 0.5));
  animation: schweben 6s ease-in-out infinite;
  transition: transform 0.25s;
}
.fenster:nth-child(2) .fenster-bild {
  animation-delay: -2s;
}
.fenster:nth-child(3) .fenster-bild {
  animation-delay: -4s;
}
.fenster:hover .fenster-bild,
.fenster:focus-visible .fenster-bild {
  transform: scale(1.06);
}
@keyframes schweben {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -6px;
  }
}

.fenster-body {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.fenster-tag {
  font-family: var(--f-pixel);
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--akzent);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.6);
}
.fenster-titel {
  margin: 6px 0 8px;
  font-family: var(--f-pixel);
  font-size: 25px;
  line-height: 1.15;
  color: #fff;
  text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.7);
}
.fenster-txt {
  flex: 1;
  font-family: var(--f-body);
  font-size: 14px;
  line-height: 1.6;
  color: var(--lt-soft);
}
/* Art und Einstiegspreis in einer Zeile ueber dem Titel - der Preis steht
   nicht neben dem Knopf, weil dort jeder Knopftext anders lang ist und die
   drei Fenster sonst verschieden umbrechen. */
.fenster-zeile {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.fenster-ab {
  font-family: var(--f-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--lt);
  white-space: nowrap;
}
/* Der Knopf ist Teil des Links, nicht selbst einer: er zeigt, wohin das
   ganze Fenster fuehrt, und leuchtet mit, wenn man irgendwo darauf zeigt. */
.fenster-knopf {
  margin-top: 18px;
  white-space: nowrap;
}
.fenster:hover .btn,
.fenster:focus-visible .btn {
  background: linear-gradient(#93a8d6, #6f83b2);
  color: var(--yellow);
}

/* Kopf einer Regal-Kategorie: derselbe Lichtkreis mit dem Bild rechts neben
   dem Titel - wer aus dem Schaufenster kommt, erkennt das Regal wieder. */
.kopfzeile-regal {
  --akzent: var(--gold);
  --schein: rgba(255, 170, 0, 0.26);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
}
.kopf-buehne {
  flex: 0 0 auto;
  width: 200px;
  height: 170px;
}
.kopf-buehne .fenster-bild {
  width: 160px;
  height: 160px;
}

/* ============================================================ Staffel
   Mengenpakete - Claimblöcke, Kampfmarken. Die Menge steht gross, darunter,
   was sie bedeutet, und oben rechts die Ersparnis gegenüber dem kleinsten
   Paket: in Gruen und nicht im Rot der Rabattmarke, denn sie ist kein
   Angebot auf Zeit, sondern der Preis der Stufe. */
/* Schmal stehen die drei Saetze UNTER der Ware: untereinander gestapelt
   waeren sie sonst ein Bildschirm Text vor dem ersten Paket. */
.staffel-regal {
  display: flex;
  flex-direction: column;
}
@media (max-width: 640px) {
  .staffel-regal .fakten {
    order: 2;
    margin: 22px 0 0;
  }
}
.fakten {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin-bottom: 22px;
}
.fakt {
  padding: 16px 20px;
}
.fakt b {
  display: block;
  font-family: var(--f-pixel);
  font-size: 14px;
  font-weight: 400;
  color: var(--lt);
  margin-bottom: 6px;
}
.fakt > span {
  display: block;
  font-family: var(--f-body);
  font-size: 14px;
  line-height: 1.55;
  color: var(--lt-soft);
}

/* Feste drei Spalten statt auto-fill: eine Staffel hat sechs Stufen, und
   3 + 3 liest sich als Treppe, 4 + 2 als vergessener Rest. */
.staffel {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 900px) {
  .staffel {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 520px) {
  .staffel {
    grid-template-columns: 1fr;
  }
}
.staffel-karte {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 20px 18px 20px;
}
.staffel-vorteil {
  position: absolute;
  top: 2px;
  right: 2px;
  padding: 3px 7px 2px;
  font-family: var(--f-pixel);
  font-size: 11px;
  color: #fff;
  background: linear-gradient(#4f9a4f, #31703a);
  box-shadow:
    inset 0 2px 0 rgba(255, 255, 255, 0.24),
    inset 0 -2px 0 rgba(0, 0, 0, 0.38),
    0 0 0 2px #000;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}
.staffel-bild {
  display: grid;
  place-items: center;
  width: 140px;
  height: 140px;
  margin-bottom: 6px;
  /* Ein heller Hof statt eines Inventarfelds: das Bild ist hier gross, ein
     Feld darum saehe aus wie ein Gegenstand in einer Truhe von Riesen. */
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.5), transparent);
}
.staffel-bild img {
  width: 128px;
  height: 128px;
  object-fit: contain;
  image-rendering: auto;
  filter: drop-shadow(0 6px 4px rgba(0, 0, 0, 0.28));
  transition: transform 0.2s;
}
.staffel-bild .icon {
  --is: 64px;
}
.staffel-karte:hover .staffel-bild img {
  transform: translateY(-4px) scale(1.04);
}
.staffel-titel a {
  text-decoration: none;
}
.staffel-menge {
  display: block;
  font-family: var(--f-pixel);
  font-size: 27px;
  line-height: 1.1;
  color: var(--txt);
}
.staffel-einheit {
  display: block;
  margin-top: 4px;
  font-family: var(--f-pixel);
  font-size: 13px;
  color: var(--txt-soft);
}
.staffel-zeile {
  margin-top: 8px;
  font-family: var(--f-body);
  font-size: 13px;
  color: var(--txt-soft);
}
.staffel-fuss {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-top: auto;
  padding-top: 16px;
}
.staffel-fuss .btn {
  width: 100%;
}

/* Auf der Paketseite darf das Bild gross sein - dort ist es der einzige
   Gegenstand. In der Truhe bleibt es im kleinen Feld. */
.pkt.ist-ausfuehrlich .pkt-bild {
  --sl: 136px;
  --is: 96px;
}
.pkt.ist-ausfuehrlich .pkt-bild img {
  width: 120px;
  height: 120px;
  image-rendering: auto;
}

.vergleich-wisch {
  display: none;
  padding: 6px 12px 2px;
  font-family: var(--f-pixel);
  font-size: 11px;
  color: var(--txt-soft);
  text-align: center;
}

/* ============================================================ Warenkorb
   Faellt als Tafel unter die Leiste, wie das schmale Menue. Dunkel wie die
   Serverliste im Spiel: der Korb gehoert zum Kopf, nicht zum Inhalt. */
.korb-knopf {
  position: relative;
}
/* Die Stueckzahl sitzt am Knopf wie die Stapelgroesse am Inventarfeld. */
.korb-zahl {
  position: absolute;
  top: -8px;
  right: -8px;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  display: grid;
  place-items: center;
  font-family: var(--f-pixel);
  font-size: 12px;
  color: #fff;
  background: linear-gradient(#4f9a4f, #31703a);
  box-shadow: 0 0 0 2px #000;
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.6);
}
/* Absolut gegen .topbar (klebend, also positioniert), nicht gegen .topbar-in:
   die schmale Menuetafel haengt am selben Elternteil und muss randlos
   durchlaufen. Damit die Tafel trotzdem unter dem Warenkorbknopf sitzt und
   nicht am Fensterrand klebt, wird der Abstand nachgerechnet - dieselbe
   Spaltenbreite wie oben in .topbar-in. Wer die Breite dort aendert, aendert
   sie hier mit. */
.korb {
  position: absolute;
  top: 100%;
  right: max(20px, calc((100% - 1320px) / 2));
  z-index: 70;
  width: min(420px, calc(100vw - 24px));
  display: none;
  padding: 20px 22px;
  max-height: calc(100dvh - 100%);
  overflow-y: auto;
}
.korb[data-offen] {
  display: block;
}
.korb-leer {
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--txt-soft);
  line-height: 1.55;
}
.korb-liste {
  margin: 0 0 18px;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 12px;
}
.korb-zeile {
  display: flex;
  gap: 12px;
  align-items: center;
}
.korb-zeile .slot {
  --sl: 40px;
  --is: 32px;
  flex: 0 0 auto;
}
.korb-zeile img {
  width: 32px;
  height: 32px;
  object-fit: contain;
  image-rendering: pixelated;
}
.korb-body {
  flex: 1;
  min-width: 0;
}
.korb-name {
  display: block;
  font-family: var(--f-pixel);
  font-size: 13px;
  color: var(--txt);
  line-height: 1.35;
}
.korb-preis {
  display: block;
  font-family: var(--f-mono);
  font-size: 13px;
  color: #2f6f3a;
  margin-top: 3px;
}
/* Entfernen ist ein Kreuz, kein Wort: es steht in jeder Zeile und wuerde als
   Text den Namen daneben erschlagen. */
.korb-weg {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: var(--mc-u-cancel) center / 18px 18px no-repeat;
  image-rendering: pixelated;
  opacity: 0.75;
  transition: opacity 0.12s;
}
.korb-weg:hover,
.korb-weg:focus-visible {
  opacity: 1;
}
.korb-summe {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding-top: 14px;
  border-top: 2px solid rgba(0, 0, 0, 0.18);
  margin-bottom: 16px;
}
.korb-summe b {
  font-family: var(--f-pixel);
  font-size: 14px;
  font-weight: 400;
  color: var(--txt);
}
.korb .btn {
  width: 100%;
}

/* ============================================================ Formulare
   Nur zwei im Store: der Name beim Anmelden und die Auswahlfelder eines
   Pakets mit Optionen. Beide sehen aus wie ein Eingabefeld im Spiel: dunkel,
   heller Rahmen, keine runden Ecken. */
.feld {
  display: block;
  margin-bottom: 16px;
}
.feld > span {
  display: block;
  font-family: var(--f-pixel);
  font-size: 13px;
  color: var(--txt);
  margin-bottom: 8px;
}
.feld > small {
  display: block;
  font-family: var(--f-body);
  font-size: 13px;
  color: var(--txt-soft);
  line-height: 1.5;
  margin-bottom: 8px;
}
.feld input[type='text'],
.feld input[type='number'],
.feld select,
.feld textarea {
  width: 100%;
  padding: 12px 14px;
  font-family: var(--f-mono);
  font-size: 15px;
  color: var(--lt);
  background: #101014;
  border: 0;
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.16);
  transition: box-shadow 0.14s;
}
.feld input:focus,
.feld select:focus,
.feld textarea:focus {
  outline: none;
  box-shadow: inset 0 0 0 3px var(--green);
}
.feld select {
  /* Pfeil des Systems behalten, aber die Schrift angleichen. */
  font-family: var(--f-pixel);
  font-size: 14px;
}

/* ============================================================ Legende
   Kopf oder Nummernfeld links, Name und Zeile rechts. Fuer nummerierte
   Schritte - im Store: wie ein Kauf ablaeuft. */
.schritte {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 18px;
}
.leg {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.leg .nrslot {
  --ns: 34px;
  --nf: 15px;
  flex: 0 0 auto;
  margin-top: 2px;
}
.leg b {
  font-family: var(--f-pixel);
  font-size: 14px;
  color: var(--txt);
  font-weight: 400;
  display: block;
}
.leg span {
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--txt-soft);
  line-height: 1.5;
}

/* ============================================================ Verweis
   Der Kasten, der zurueck auf die Infoseite fuehrt. Uebernommen aus .hint. */
.hint {
  display: flex;
  gap: 22px;
  align-items: center;
  padding: 24px 26px;
  text-decoration: none;
  flex-wrap: wrap;
  transition: box-shadow 0.14s;
}
.hint:hover,
.hint:focus-visible {
  box-shadow: 0 0 0 3px rgba(255, 170, 0, 0.5);
  outline: none;
}
.hint-body {
  flex: 1;
  min-width: 240px;
  display: block;
}
.hint-tag {
  display: block;
  font-family: var(--f-pixel);
  font-size: 10px;
  color: var(--gold);
  letter-spacing: 0.12em;
  font-weight: 400;
  margin-bottom: 8px;
}
.hint-title {
  display: block;
  font-family: var(--f-pixel);
  font-size: 17px;
  color: var(--lt);
  font-weight: 400;
  margin-bottom: 9px;
}
.hint-txt {
  display: block;
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--lt-soft);
  line-height: 1.6;
  max-width: 62ch;
}
.hint-go {
  flex: 0 0 auto;
  font-family: var(--f-pixel);
  font-size: 13px;
  color: var(--gold);
}

/* ============================================================ Footer
   Schliesst die Seite buendig ab, damit unter ihm kein Streifen Bedrock
   hervorschaut. Darunter setzt Tebex seinen eigenen Rechtsfuss - der bleibt
   sichtbar (Pflicht), ist oben aber auf dieselben Farben gesetzt. */
footer {
  position: relative;
  margin-top: 40px;
}
.foot-in {
  position: relative;
  background: rgba(6, 6, 9, 0.88);
  padding: 52px 0 34px;
  border-top: 3px solid rgba(0, 0, 0, 0.7);
}
.foot-grid {
  display: grid;
  gap: 34px;
  grid-template-columns: 1.4fr repeat(3, 1fr);
}
.foot-brand {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.foot-brand .brand-mark {
  width: 52px;
  height: 52px;
}
.foot-brand p {
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--lt-soft);
  max-width: 34ch;
  line-height: 1.6;
}
.foot-col h2 {
  font-family: var(--f-pixel);
  font-size: 13px;
  color: var(--gold);
  margin: 0 0 14px;
  font-weight: 400;
}
.foot-col a {
  display: block;
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--lt-soft);
  text-decoration: none;
  padding: 4px 0;
  transition: color 0.12s;
}
.foot-col a:hover {
  color: var(--lt);
}
.foot-bot {
  margin-top: 34px;
  padding-top: 22px;
  border-top: 2px solid rgba(255, 255, 255, 0.08);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-family: var(--f-pixel);
  font-size: 11px;
  color: #6a6a72;
}
.foot-bot a {
  color: inherit;
  text-decoration: none;
  transition: color 0.12s;
}
.foot-bot a:hover,
.foot-bot a:focus-visible {
  color: var(--lt);
}

/* ============================================================ Anpassungen
   Dieselben Haltepunkte wie drueben. Der Store hat einen Reiter mehr als der
   Server-Bereich (Store selbst), die Leiste bricht darum eher um. */
@media (max-width: 1360px) {
  .topbar-in {
    flex-wrap: wrap;
    gap: 12px;
  }
  /* Die Reiter fallen in die zweite Zeile, Anmelden und Warenkorb bleiben
     oben neben der Marke. Ueber `order` statt ueber die Reihenfolge im
     Markup: dort steht der Korb hinter den Reitern, weil er breit auch dort
     hingehoert - und die Tastaturreihenfolge soll dem Sehen folgen, nicht
     dem Haltepunkt. */
  .kopf-rechts {
    order: 1;
    margin-left: auto;
  }
  .nav {
    order: 2;
    width: 100%;
    margin-left: 0;
    overflow-x: visible;
    flex-wrap: wrap;
    justify-content: center;
  }
}

@media (max-width: 820px) {
  .foot-grid {
    grid-template-columns: 1fr 1fr;
  }
  .nv {
    padding: 9px 11px;
    font-size: 12px;
    gap: 7px;
  }
  .nv i {
    width: 18px;
    height: 18px;
  }

  section {
    padding: 52px 0;
  }
  .kopfzeile {
    padding-top: 52px;
  }
  .kopf-wort {
    font-size: clamp(24px, 8vw, 38px);
  }
  .vergleich-wisch {
    display: block;
  }
}

@media (max-width: 640px) {
  /* Einreihig bleiben statt umbrechen: der Kopf klebt, jede zweite Reihe
     kostet dauerhaft Platz. Nachgemessen bei 390px (das schmalste gaengige
     Telefon, Spalte also 350px): Marke 40 + Reiter 140 + die beiden Knoepfe
     84 + zwei Luecken a 20 = 304px. Mit Wortmarke und Beschriftungen waeren es
     rund 640px gewesen, also zwei Reihen. Die Namen der beiden Knoepfe stehen
     im aria-label, gehen also nicht verloren. */
  .brand-txt {
    display: none;
  }
  .nv-txt {
    display: none;
  }
  .kopf-rechts .nv {
    gap: 0;
    padding: 9px;
  }
  /* Die Reiter als EINE Zeile zum Wischen statt zwei, drei umgebrochener:
     die Leiste klebt oben, jede weitere Reihe kostet dauerhaft Platz. Der
     Verlauf am rechten Rand zeigt, dass es weitergeht. Den Trenner braucht
     es hier nicht, die Reihe beginnt ohnehin bei Start. */
  .nav {
    flex-wrap: nowrap;
    overflow-x: auto;
    justify-content: flex-start;
    -webkit-mask-image: linear-gradient(to right, #000 88%, transparent);
    mask-image: linear-gradient(to right, #000 88%, transparent);
    padding-right: 28px;
  }
  .nav-sep {
    display: none;
  }

  .foot-grid {
    grid-template-columns: 1fr;
  }
  .pakete.ist-liste .pkt {
    flex-direction: column;
  }
  .pakete.ist-liste .pkt-fuss {
    flex-direction: row;
    align-items: center;
    align-self: stretch;
  }

  /* Die klebende erste Spalte darf auf dem Telefon nicht die halbe Breite
     belegen - sonst bleibt beim Schieben kaum eine Rangspalte sichtbar. */
  .vergleich {
    min-width: 600px;
  }
  .vergleich .vg-spalte-merkmal {
    width: 140px;
  }
  .vergleich th[scope='row'] {
    font-size: 13px;
  }
  .vg-kauf .btn .icon {
    display: none;
  }

  /* Drei Fenster untereinander, jedes so hoch wie auf dem Rechner, waeren
     drei Bildschirme Weg bis zur ersten Ware. Schmal liegt das Bild darum
     links neben dem Text, und der Satz faellt weg - Titel und Knopf sagen
     genug, der Satz steht im Kopf der Kategorie. */
  .fenster {
    flex-direction: row;
    align-items: center;
    gap: 12px;
    padding: 10px 14px 10px 6px;
  }
  .fenster-buehne {
    flex: 0 0 104px;
    height: 104px;
    margin: 0;
  }
  .fenster-bild {
    width: 96px;
    height: 96px;
  }
  .fenster-titel {
    font-size: 19px;
    margin: 4px 0 0;
  }
  .fenster-txt {
    display: none;
  }
  .fenster-knopf {
    margin-top: 10px;
    align-self: flex-start;
    padding: 9px 13px;
    font-size: 12px;
  }
  .kopfzeile-regal {
    gap: 12px;
  }
  .kopf-buehne {
    width: 104px;
    height: 104px;
  }
  .kopf-buehne .fenster-bild {
    width: 92px;
    height: 92px;
  }
}
/* Neben einem langen Titel („Kampfmarken") ist auf dem Telefon kein Platz
   mehr fuer das Bild - es steht ohnehin gleich darunter auf jeder Karte. */
@media (max-width: 460px) {
  .kopf-buehne {
    display: none;
  }
}

/* ============================================================ Kaufstatus
   Die Zeile unter einem Kaufknopf, die laden.js aus craftattack.me füllt.
   `.kauf` selbst ist nur ein Anker für das Skript und darf das Layout der
   Karte nicht verändern. */
.kauf {
  display: contents;
}

.kauf-status {
  display: block;
  margin-top: 8px;
  font-family: var(--f-body);
  font-size: 13px;
  line-height: 1.5;
  color: #4a4a4a;
}

.kauf-status[data-ton='warn'] {
  color: #8a4b4b;
}

.kauf-status[data-ton='gut'] {
  color: #31703a;
}
