/*!
 * TimeTales · base.css
 * Tokens, Reset, Typografie, Layout und alle gemeinsamen Bausteine.
 * Reihenfolge im <head>: fonts.css, base.css, world-<welt>.css (nur Weltseiten), page-<seite>.css.
 *
 * INHALT
 *   1  Tokens (:root)            README Abschnitt 4, dazu Helfer-Tokens (unten markiert)
 *   2  Reset und Grundlagen      box-sizing, Auswahl, Scrollbar, Fokus, Skip-Link, .sr-only
 *   3  Typografie                .tt-display .tt-h1 .tt-h2 .tt-h3 .tt-h4 .tt-lead .tt-meta .tt-kicker .tt-prose .tt-link
 *   4  Layout                    .tt-wrap .tt-section .tt-grid .tt-stack .tt-rule .tt-hero .tt-pagehead
 *   5  .tt-nav                   NUR HUB: feste Leiste, mobil Vollbild-Menü (Welt-Sites bauen eigene Köpfe)
 *      [data-autohide]           Grundverhalten für jede eigene Leiste (core.js setzt is-scrolled, is-hidden)
 *   6  .tt-btn                   --primary --ghost --text, Größen --sm --lg, --block, .is-disabled
 *   7  .tt-chip                  --live --wip --soon
 *   8  .tt-status                Live-Anzeige, gesteuert über data-status (core.js)
 *   9  .tt-footer                NUR HUB
 *  10  .tt-media                 Bildrahmen, parallaxfähig
 *  11  Zustände für core.js      .tt-rv (Reveal), .tt-tilt, SplitText, Scroll-Sperre
 *  12  Reduzierte Bewegung, Druck
 *
 * GEGEN RUCKELN (README Abschnitt 8): kein Filmkorn, kein backdrop-filter, kein filter, kein mix-blend-mode,
 * keine View Transitions. Animiert werden nur transform, translate, scale und opacity.
 *
 * REGELN
 *   - Farben, Abstände, Radien, Zeiten und z-index nur über Tokens.
 *   - Farbabstufungen des Akzents immer direkt mit color-mix(in srgb, var(--accent) N%, transparent)
 *     bilden, nicht als abgeleitetes Token: so folgt die Abstufung, wenn eine Seite --accent in einem
 *     Abschnitt überschreibt. --accent und --accent-ink sind als <color> registriert und lassen sich
 *     deshalb per CSS-Transition oder GSAP weich umblenden.
 *   - Versteckte Startzustände setzt ausschließlich core.js (Klasse .tt-rv). Nie von Hand vergeben.
 *   - Welt-Look: world-*.css überschreibt nur Tokens und das Aussehen der Bausteine hier.
 *
 * ROLLEN-TOKENS (überschreibt world-*.css, Seiten dürfen sie lesen)
 *   --display-family/-weight/-stretch/-tracking/-leading/-case/-scale/-cap/-pad   große Überschriften
 *   --heading-weight/-stretch/-tracking/-leading                                  h2 bis h4
 *   --em-style                                                                    <em> in Überschriften
 *   --meta-family/-weight/-size/-tracking/-case                                   .tt-meta, Chips, Fußzeilen-Titel
 *   --navlink-family/-weight/-size/-stretch/-tracking/-case                       Links in der Leiste
 *   --btn-family/-weight/-size/-stretch/-tracking/-case                           Buttons
 */

/* ============================================================
   1  TOKENS
   ============================================================ */

@property --accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #e8c26a;
}

@property --accent-ink {
  syntax: "<color>";
  inherits: true;
  initial-value: #141006;
}

/* Ersatzschriften mit angepassten Metriken: Solange die Webfont lädt, läuft der Text in einer lokalen
   Schrift mit derselben Laufweite und Grundlinie. Dadurch springt beim Eintreffen nichts um.
   Werte im Browser gegen die echten Schriften gemessen (Arial, Times New Roman, Courier New bzw. die
   metrikgleichen Liberation-Schriften). Archivo hat je Breite eine eigene Ersatzschrift. */
@font-face {
  font-family: "tt-archivo-fb";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  font-weight: 100 900;
  size-adjust: 119.9%;
  ascent-override: 73.4%;
  descent-override: 17.5%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "tt-archivo-narrow-fb";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  font-weight: 100 900;
  size-adjust: 76.3%;
  ascent-override: 115.3%;
  descent-override: 27.5%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "tt-archivo-wide-fb";
  src: local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"), local("LiberationSans-Bold");
  font-weight: 100 900;
  size-adjust: 129.1%;
  ascent-override: 68.2%;
  descent-override: 16.3%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "tt-manrope-fb";
  src: local("Arial"), local("ArialMT"), local("Liberation Sans"), local("LiberationSans");
  font-weight: 100 900;
  size-adjust: 102.4%;
  ascent-override: 104.5%;
  descent-override: 29.3%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "tt-cormorant-fb";
  src: local("Times New Roman Bold"), local("TimesNewRomanPS-BoldMT"), local("Liberation Serif Bold"), local("LiberationSerif-Bold");
  font-weight: 100 900;
  size-adjust: 92.3%;
  ascent-override: 99.7%;
  descent-override: 31.4%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "tt-plex-fb";
  src: local("Courier New"), local("CourierNewPSMT"), local("Liberation Mono"), local("LiberationMono");
  font-weight: 100 900;
  size-adjust: 100%;
  ascent-override: 103%;
  descent-override: 28%;
  line-gap-override: 0%;
}

:root {
  /* Flächen */
  --ink-0: #06070a;
  --ink-1: #0b0d12;
  --ink-2: #12151d;
  --ink-3: #1b1f2a;

  /* Linien */
  --line: rgb(255 255 255 / .09);
  --line-strong: rgb(255 255 255 / .18);

  /* Text. Achtung: --text-3 nur auf --ink-0 bis --ink-2 für kleinen Text verwenden (Kontrast AA). */
  --text: #eef0f5;
  --text-2: #a9afc0;
  --text-3: #7d8499;

  /* Akzent */
  --accent: #e8c26a;
  --accent-ink: #141006;

  /* Status */
  --ok: #5fd08a;
  --warn: #e8a33d;
  --info: #6fb8ff;

  /* Radius */
  --radius: 2px;
  --radius-pill: 999px;

  /* Layout */
  --gutter: clamp(1.25rem, 4vw, 4rem);
  --wrap: 1320px;

  /* Abstände */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-9: 96px;
  --s-10: 128px;
  --s-11: 192px;

  /* Bewegung */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --dur-1: .2s;
  --dur-2: .45s;
  --dur-3: .9s;

  /* Ebenen */
  --z-nav: 100;
  --z-menu: 200;
  --z-dialog: 300;
  --z-transition: 500;

  /* Schrift */
  --font-display: "Archivo", "tt-archivo-fb", Arial, sans-serif;                /* Breite um 115 % */
  --font-display-narrow: "Archivo", "tt-archivo-narrow-fb", Arial, sans-serif;  /* Breite 62 bis 75 % */
  --font-display-wide: "Archivo", "tt-archivo-wide-fb", Arial, sans-serif;      /* Breite 125 % */
  --font-body: "Manrope", "tt-manrope-fb", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", "tt-plex-fb", ui-monospace, Consolas, "Courier New", monospace;
  --font-serif: "Cormorant Garamond", "tt-cormorant-fb", "Times New Roman", Georgia, serif;

  /* Größen, fließend zwischen 360 und 1440 px Viewportbreite */
  --step--1: clamp(.8125rem, .7917rem + .0926vw, .875rem);   /* 13 bis 14 */
  --step-0: clamp(1rem, .9583rem + .1852vw, 1.125rem);       /* 16 bis 18 */
  --step-1: clamp(1.25rem, 1.1667rem + .3704vw, 1.5rem);     /* 20 bis 24 */
  --step-2: clamp(1.625rem, 1.4167rem + .9259vw, 2.25rem);   /* 26 bis 36 */
  --step-3: clamp(2.125rem, 1.6667rem + 2.037vw, 3.5rem);    /* 34 bis 56 */
  --step-4: clamp(2.75rem, 1.8333rem + 4.0741vw, 5.5rem);    /* 44 bis 88 */
  --step-5: clamp(3.25rem, 1.3333rem + 8.5185vw, 9rem);      /* 52 bis 144, Hero */

  /* ---------- Helfer-Tokens (Ergänzung zum README) ---------- */
  --nav-h: 68px;
  /* Abstand, mit dem Ankerziele unter einer festen Leiste landen. Welt-Sites überschreiben ihn
     (Leiste unten oder keine feste Leiste: 24px). */
  --anchor-offset: calc(var(--nav-h) + var(--s-5));
  /* Mindestbreite für Live-Zahlen (data-status-field), damit ein Ziffernwechsel nichts verschiebt */
  --num-w: 2ch;
  --section-y: clamp(4.5rem, 2.5rem + 8vw, 11rem);
  --grid-gap: clamp(1rem, .5rem + 1.6vw, 2rem);

  /* lokale Ebenen innerhalb eines Bausteins (kein Wert außerhalb der --z-Tokens) */
  --z-below: -1;
  --z-1: 1;
  --z-2: 2;
  --z-3: 3;

  /* Rollen: große Überschriften */
  --display-family: var(--font-display);
  --display-weight: 800;
  --display-stretch: 115%;
  --display-tracking: -.022em;
  --display-leading: .95;
  --display-case: none;
  --display-scale: 1;        /* Größenausgleich je Schrift (Cormorant läuft klein) */
  --display-cap: 12.5vw;     /* Obergrenze von .tt-display auf schmalen Geräten */
  --display-pad: 0em;        /* Platz unter der Zeile für kursive Unterlängen */

  /* Rollen: h2 bis h4 */
  --heading-weight: 760;
  --heading-stretch: 110%;
  --heading-tracking: -.014em;
  --heading-leading: 1.04;

  /* Rolle: Betonung in Überschriften (<em>) */
  --em-style: normal;

  /* Rolle: Meta-Text */
  --meta-family: var(--font-mono);
  --meta-weight: 500;
  --meta-size: .75rem;
  --meta-tracking: .08em;
  --meta-case: uppercase;

  /* Rolle: Links in der Leiste */
  --navlink-family: var(--font-body);
  --navlink-weight: 500;
  --navlink-size: .875rem;
  --navlink-stretch: 100%;
  --navlink-tracking: 0em;
  --navlink-case: none;

  /* Rolle: Buttons */
  --btn-family: var(--font-body);
  --btn-weight: 650;
  --btn-size: .9375rem;
  --btn-stretch: 100%;
  --btn-tracking: .005em;
  --btn-case: none;
}

/* ============================================================
   2  RESET UND GRUNDLAGEN
   ============================================================ */

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

* {
  margin: 0;
}

html {
  color-scheme: dark;
  background: var(--ink-0);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  tab-size: 2;
  /* Platz für die Bildlaufleiste bleibt reserviert: nichts springt, wenn ein Menü das Scrollen sperrt */
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-3) var(--ink-0);
  /* Effekte (Reveal, Parallax, Tilt) dürfen nie einen Querbalken erzeugen. Nur am html-Element,
     damit position: sticky überall weiter funktioniert. */
  overflow-x: hidden;
  overflow-x: clip;
}

@supports not (scrollbar-color: auto) {
  ::-webkit-scrollbar {
    width: 10px;
    height: 10px;
  }

  ::-webkit-scrollbar-track {
    background: var(--ink-0);
  }

  ::-webkit-scrollbar-thumb {
    background: var(--ink-3);
    border: 2px solid var(--ink-0);
  }
}

body {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.65;
  color: var(--text);
  background: var(--ink-0);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none;
  font-kerning: normal;
}

:where(img, picture, video, canvas, svg) {
  display: block;
  max-width: 100%;
}

:where(img, video) {
  height: auto;
}

:where(input, button, textarea, select) {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

:where(button) {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

:where(a) {
  color: inherit;
  text-decoration: none;
}

:where(ul, ol)[class] {
  list-style: none;
  padding: 0;
}

:where(h1, h2, h3, h4, h5, h6) {
  font-size: inherit;
  font-weight: inherit;
  text-wrap: balance;
}

:where(p, li, dd, figcaption) {
  text-wrap: pretty;
  overflow-wrap: break-word;
}

:where(address) {
  font-style: normal;
}

:where(b, strong) {
  font-weight: 700;
}

[hidden] {
  display: none !important;
}

/* Ankerziele: nativer Sprung, Ziel landet unter der Leiste */
:where([id]) {
  scroll-margin-top: var(--anchor-offset);
}

::selection {
  background: var(--accent);
  color: var(--accent-ink);
  text-shadow: none;
}

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

:focus:not(:focus-visible),
[tabindex="-1"]:focus {
  outline: none;
}

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

/* Skip-Link: erstes Element im <body>, Ziel #inhalt */
.tt-skip {
  position: fixed;
  top: var(--s-3);
  left: var(--s-3);
  z-index: calc(var(--z-nav) + 1);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--s-4);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: .875rem;
  font-weight: 700;
  border-radius: var(--radius);
  transform: translateY(-200%);
}

.tt-skip:focus {
  transform: none;
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

/* ============================================================
   3  TYPOGRAFIE
   ============================================================ */

.tt-display,
.tt-h1,
.tt-h2,
.tt-h3,
.tt-h4 {
  font-family: var(--display-family);
  font-stretch: var(--heading-stretch);
  font-weight: var(--heading-weight);
  letter-spacing: var(--heading-tracking);
  line-height: var(--heading-leading);
  text-transform: var(--display-case);
  padding-bottom: var(--display-pad);
  color: var(--text);
  text-wrap: balance;
  overflow-wrap: break-word;
  hyphens: manual;
}

/* Hero-Zeile. Höchstens zwei Zeilen, siehe README. */
.tt-display {
  font-size: min(calc(var(--step-5) * var(--display-scale)), var(--display-cap));
  font-stretch: var(--display-stretch);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: var(--display-leading);
}

.tt-h1 {
  font-size: min(calc(var(--step-4) * var(--display-scale)), calc(var(--display-cap) * .88));
  font-stretch: var(--display-stretch);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: calc(var(--display-leading) + .05);
}

.tt-h2 {
  font-size: min(calc(var(--step-3) * var(--display-scale)), calc(var(--display-cap) * .8));
}

.tt-h3 {
  font-size: calc(var(--step-2) * var(--display-scale));
  line-height: calc(var(--heading-leading) + .08);
}

.tt-h4 {
  font-size: calc(var(--step-1) * var(--display-scale));
  line-height: calc(var(--heading-leading) + .16);
}

/* Betonung in Überschriften: Hub, SCP und SWTOR färben, WizardRP setzt kursiv (world-wizard.css). */
:is(.tt-display, .tt-h1, .tt-h2, .tt-h3, .tt-h4) em {
  font-style: var(--em-style);
  color: var(--accent);
}

.tt-lead {
  max-width: 58ch;
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--text-2);
  text-wrap: pretty;
}

.tt-meta,
.tt-kicker {
  font-family: var(--meta-family);
  font-size: var(--meta-size);
  font-weight: var(--meta-weight);
  letter-spacing: var(--meta-tracking);
  text-transform: var(--meta-case);
  line-height: 1.5;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}

/* Eyebrow über einer Überschrift. Sparsam: höchstens eine je drei Abschnitte. */
.tt-kicker {
  display: block;
  color: var(--accent);
}

/* Fließtext-Block: Absatzabstände, Linkstil, Listen */
.tt-prose {
  max-width: 68ch;
  color: var(--text-2);
}

.tt-prose > * + * {
  margin-top: 1.1em;
}

.tt-prose :where(strong, b) {
  color: var(--text);
  font-weight: 650;
}

.tt-prose :where(ul, ol):not([class]) {
  padding-left: 1.2em;
}

.tt-prose :where(li) + li {
  margin-top: .4em;
}

.tt-prose :where(p, li) {
  hyphens: auto;
  hyphenate-limit-chars: 10 4 4;
}

.tt-prose a:not([class]),
.tt-link {
  color: var(--text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: color-mix(in srgb, var(--accent) 70%, transparent);
  transition: color var(--dur-1) ease, text-decoration-color var(--dur-1) ease;
}

@media (hover: hover) {
  .tt-prose a:not([class]):hover,
  .tt-link:hover {
    color: var(--accent);
    text-decoration-color: currentColor;
  }
}

/* Technische Angaben im Fließtext, zum Beispiel die Serveradresse */
.tt-mono {
  font-family: var(--font-mono);
  font-size: .92em;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

/* ============================================================
   4  LAYOUT
   ============================================================ */

.tt-wrap {
  width: min(100% - var(--gutter) * 2, var(--wrap));
  margin-inline: auto;
}

.tt-wrap--narrow {
  --wrap: 880px;
}

.tt-wrap--wide {
  --wrap: 1680px;
}

.tt-section {
  position: relative;
  padding-block: var(--section-y);
}

.tt-section--tight {
  --section-y: clamp(3rem, 2rem + 4vw, 6rem);
}

.tt-section--flush-top {
  padding-top: 0;
}

.tt-section--flush-bottom {
  padding-bottom: 0;
}

/* Raster: 12 Spalten ab 900px, darunter eine Spalte.
   Kinder steuern sich über Variablen: style="--span:7" und optional "--start:6". */
.tt-grid {
  display: grid;
  grid-template-columns: repeat(var(--cols, 12), minmax(0, 1fr));
  gap: var(--grid-gap);
}

.tt-grid > * {
  grid-column: 1 / -1;
  min-width: 0;
}

@media (min-width: 900px) {
  .tt-grid > * {
    grid-column: var(--start, auto) / span var(--span, 12);
  }
}

/* Vertikaler Rhythmus: Abstand zwischen direkten Kindern, style="--stack: var(--s-6)" */
.tt-stack > * + * {
  margin-top: var(--stack, var(--s-5));
}

.tt-rule {
  display: block;
  width: 100%;
  height: 1px;
  border: 0;
  background: var(--line);
}

/* Hero-Rahmen. Höhe über svh (stabil, springt nicht mit der Adressleiste), nie 100vh allein.
   Inhalt und Ausrichtung bestimmt die Seite. */
.tt-hero {
  position: relative;
  isolation: isolate;
  display: grid;
  min-height: 100vh;
  min-height: 100svh;
  padding-top: var(--nav-h);
  overflow: hidden;
  overflow: clip;
}

.tt-hero--dvh {
  min-height: 100vh;
  min-height: 100dvh;
}

/* Vollflächige Bild-, Video- oder Canvas-Ebene hinter dem Hero-Inhalt */
.tt-hero__media {
  position: absolute;
  inset: 0;
  z-index: var(--z-below);
}

.tt-hero__media :is(picture, img, video, canvas) {
  width: 100%;
  height: 100%;
}

.tt-hero__media :is(img, video) {
  object-fit: cover;
}

/* Seitenkopf für Unterseiten ohne Hero (Impressum, Regeln, Guide ...) */
.tt-pagehead {
  padding-top: calc(var(--nav-h) + clamp(3.5rem, 2rem + 7vw, 8rem));
  padding-bottom: clamp(2.5rem, 1.5rem + 4vw, 5rem);
  border-bottom: 1px solid var(--line);
}

/* ============================================================
   5  NAVIGATION  .tt-nav
   ------------------------------------------------------------
   Zustände (setzt core.js am <header class="tt-nav">):
     .is-scrolled   Seite ist nicht mehr ganz oben: deckende Fläche, Haarlinie
     .is-hidden     beim Runterscrollen ausgeblendet (nur transform)
     .is-open       mobiles Menü offen
   Aufbau: __brand (Link __home mit __emblem und __word, optional Link __world),
           __burger, __menu (Liste __list mit __link, danach Button __cta).
   Unter 900px wird __menu mit JS zum Vollbild-Overlay, ohne JS zur einfachen Linkliste.
   Wichtig: Der <header> darf im Ruhezustand weder transform noch filter tragen, sonst
   hängt das fixierte Overlay am Header statt am Viewport. Die Fläche liegt deshalb auf ::before.
   Kein backdrop-filter: die Fläche ist deckend.
   Markup-Haken: <header class="tt-nav" data-autohide data-menu-root> und am Burger
   data-menu-toggle="#tt-menu".
   ============================================================ */

.tt-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.4vw, 2.5rem);
  height: var(--nav-h);
  padding-inline: var(--gutter);
  color: var(--text);
  transition: transform var(--dur-2) var(--ease-out);
}

/* Fläche im gescrollten Zustand */
.tt-nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--z-below);
  background: var(--ink-0);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transition: opacity var(--dur-2) ease;
  pointer-events: none;
}

/* Verlauf ganz oben auf der Seite: hält die Leiste über hellen Hero-Bildern lesbar */
.tt-nav::after {
  content: "";
  position: absolute;
  inset: 0 0 -70% 0;
  z-index: var(--z-below);
  background: linear-gradient(to bottom, color-mix(in srgb, var(--ink-0) 72%, transparent), transparent);
  opacity: 1;
  transition: opacity var(--dur-2) ease;
  pointer-events: none;
}

.tt-nav.is-scrolled::before {
  opacity: 1;
}

.tt-nav.is-scrolled::after {
  opacity: 0;
}

/* Lange Leseseiten (Regelwerk): deckende Leiste, damit kein Fließtext durchscheint.
   Aktivieren mit <html data-nav="solid">. */
html[data-nav="solid"] .tt-nav::before {
  background: var(--ink-0);
}

/* Grundverhalten für jede Leiste mit data-autohide (auch eigene Köpfe der Welt-Sites):
   core.js setzt .is-hidden beim Runterscrollen. Bewegt wird nur transform.
   data-autohide="bottom" für Leisten am unteren Rand. Eigene Leisten dürfen das überschreiben. */
[data-autohide] {
  transition: transform var(--dur-2) var(--ease-out);
}

[data-autohide].is-hidden {
  transform: translateY(-102%);
}

[data-autohide="bottom"].is-hidden {
  transform: translateY(102%);
}

[data-autohide].is-open {
  transform: none;
  transition: none;
}

.tt-nav.is-hidden {
  transform: translateY(-102%);
}

.tt-nav.is-open {
  transform: none;
  transition: none;
}

html:not(.js) .tt-nav::before {
  opacity: 1;
}

html:not(.js) .tt-nav::after {
  opacity: 0;
}

/* Marke */
.tt-nav__brand {
  position: relative;
  z-index: var(--z-2);
  display: flex;
  align-items: center;
  flex: none;
  min-width: 0;
}

.tt-nav__home {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.tt-nav__emblem {
  flex: none;
  width: 30px;
  height: 30px;
  object-fit: contain;
}

/* Wortmarke: immer Archivo breit in Versalien, unabhängig von der Welt */
.tt-nav__word {
  font-family: var(--font-display);
  font-stretch: 122%;
  font-weight: 800;
  font-size: .8125rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
}

/* Weltname hinter einer Haarlinie, in der Schrift der Welt */
.tt-nav__world {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-left: var(--s-3);
  padding-left: var(--s-3);
  font-family: var(--display-family);
  font-stretch: var(--heading-stretch);
  font-weight: var(--heading-weight);
  font-size: .9375rem;
  letter-spacing: var(--heading-tracking);
  text-transform: var(--display-case);
  line-height: 1;
  white-space: nowrap;
  color: var(--text);
  background: linear-gradient(var(--line-strong), var(--line-strong)) left center / 1px 18px no-repeat;
}

/* Menü (Desktop: in der Leiste) */
.tt-nav__menu {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  gap: clamp(1rem, 2vw, 2rem);
}

.tt-nav__list {
  display: flex;
  align-items: center;
  gap: clamp(.9rem, 2.1vw, 2rem);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.tt-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 44px;
  font-family: var(--navlink-family);
  font-size: var(--navlink-size);
  font-stretch: var(--navlink-stretch);
  font-weight: var(--navlink-weight);
  letter-spacing: var(--navlink-tracking);
  text-transform: var(--navlink-case);
  line-height: 1;
  white-space: nowrap;
  color: var(--text-2);
  transition: color var(--dur-1) ease;
}

/* Unterstrich zeichnet sich per scaleX */
.tt-nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 9px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform var(--dur-2) var(--ease-out);
}

@media (hover: hover) {
  .tt-nav__link:hover {
    color: var(--text);
  }

  .tt-nav__link:hover::after {
    transform: scaleX(1);
    transform-origin: 0 50%;
  }
}

.tt-nav__link[aria-current="page"] {
  color: var(--text);
}

.tt-nav__link[aria-current="page"]::after {
  background: var(--accent);
  transform: scaleX(1);
}

/* kleines Pfeil-Icon an externen Links (Phosphor arrow-up-right) */
.tt-ext {
  flex: none;
  width: .72em;
  height: .72em;
  fill: currentColor;
  opacity: .6;
}

.tt-nav__cta {
  flex: none;
}

/* Burger: nur unter 900px und nur mit JS sichtbar */
.tt-nav__burger {
  position: relative;
  z-index: var(--z-2);
  display: none;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  margin-left: auto;
  padding: 0;
  color: var(--text);
  font-family: var(--meta-family);
  font-size: var(--meta-size);
  font-weight: var(--meta-weight);
  letter-spacing: var(--meta-tracking);
  text-transform: var(--meta-case);
  line-height: 1.5;
}

.tt-nav__burger-text {
  display: grid;
  height: 1.5em;
  overflow: hidden;
  overflow: clip;
  text-align: right;
}

.tt-nav__burger-text > span {
  grid-area: 1 / 1;
  transition: translate var(--dur-2) var(--ease-out), opacity var(--dur-1) ease;
}

.tt-nav__burger-text > span:last-child {
  translate: 0 100%;
  opacity: 0;
}

.tt-nav.is-open .tt-nav__burger-text > span:first-child {
  translate: 0 -100%;
  opacity: 0;
}

.tt-nav.is-open .tt-nav__burger-text > span:last-child {
  translate: 0 0;
  opacity: 1;
}

.tt-nav__burger-icon {
  position: relative;
  flex: none;
  width: 26px;
  height: 14px;
}

.tt-nav__burger-icon::before,
.tt-nav__burger-icon::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-2) var(--ease-out);
}

.tt-nav__burger-icon::before {
  top: 3px;
}

.tt-nav__burger-icon::after {
  bottom: 3px;
}

.tt-nav.is-open .tt-nav__burger-icon::before {
  transform: translateY(3.25px) rotate(45deg);
}

.tt-nav.is-open .tt-nav__burger-icon::after {
  transform: translateY(-3.25px) rotate(-45deg);
}

/* Enge Desktop-Breiten: Wortmarke auf Weltseiten weglassen, damit alles in einer Zeile bleibt */
@media (min-width: 900px) and (max-width: 1239.98px) {
  .tt-nav__brand:has(.tt-nav__world) .tt-nav__word {
    display: none;
  }

  .tt-nav__list {
    gap: clamp(.75rem, 1.6vw, 1.5rem);
  }
}

/* ---------- unter 900px ---------- */
@media (max-width: 899.98px) {
  /* Mit JS: Marke links, Burger rechts, Menü als Vollbild-Overlay */
  .js .tt-nav__burger {
    display: inline-flex;
  }

  .js .tt-nav__menu {
    position: fixed;
    inset: 0;
    z-index: var(--z-1);
    flex-direction: column;
    align-items: stretch;
    gap: var(--s-6);
    padding: calc(var(--nav-h) + var(--s-6)) var(--gutter) max(var(--s-6), env(safe-area-inset-bottom));
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    visibility: hidden;
    pointer-events: none;
    transition: visibility 0s linear var(--dur-2);
  }

  /* Vorhang: fährt per scaleY von oben herunter */
  .js .tt-nav__menu::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: var(--z-below);
    background: var(--ink-0);
    transform: scaleY(0);
    transform-origin: 50% 0;
    transition: transform .32s var(--ease-out);
  }

  .js .tt-nav.is-open {
    z-index: var(--z-menu);
  }

  .js .tt-nav.is-open::before,
  .js .tt-nav.is-open::after {
    opacity: 0;
  }

  .js .tt-nav.is-open .tt-nav__menu {
    visibility: visible;
    pointer-events: auto;
    transition-delay: 0s;
  }

  .js .tt-nav.is-open .tt-nav__menu::before {
    transform: scaleY(1);
  }

  .js .tt-nav__list {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    margin: 0;
  }

  .js .tt-nav__list > li {
    overflow: hidden;
    overflow: clip;
    /* Luft für Unterlängen und Umlautpunkte in der Maske */
    padding-block: .06em;
  }

  .js .tt-nav__list > li:nth-child(1) { --i: 0; }
  .js .tt-nav__list > li:nth-child(2) { --i: 1; }
  .js .tt-nav__list > li:nth-child(3) { --i: 2; }
  .js .tt-nav__list > li:nth-child(4) { --i: 3; }
  .js .tt-nav__list > li:nth-child(5) { --i: 4; }
  .js .tt-nav__list > li:nth-child(6) { --i: 5; }
  .js .tt-nav__list > li:nth-child(7) { --i: 6; }
  .js .tt-nav__list > li:nth-child(8) { --i: 7; }
  .js .tt-nav__list > li:nth-child(9) { --i: 8; }

  .js .tt-nav__link {
    min-height: 0;
    padding-block: .1em;
    gap: .3em;
    font-family: var(--display-family);
    font-size: clamp(2.125rem, 10.5vw, 4rem);
    font-stretch: var(--display-stretch);
    font-weight: var(--display-weight);
    letter-spacing: var(--display-tracking);
    text-transform: var(--display-case);
    line-height: 1.08;
    color: var(--text);
    translate: 0 115%;
    transition: translate var(--dur-1) ease, color var(--dur-1) ease;
  }

  .js .tt-nav__link::after {
    display: none;
  }

  .js .tt-nav__link[aria-current="page"] {
    color: var(--accent);
  }

  .js .tt-nav__link .tt-ext {
    width: .42em;
    height: .42em;
    align-self: flex-start;
    margin-top: .28em;
  }

  .js .tt-nav.is-open .tt-nav__link {
    translate: 0 0;
    transition: translate var(--dur-2) var(--ease-out) calc(80ms + var(--i, 0) * 30ms), color var(--dur-1) ease;
  }

  .js .tt-nav__cta {
    margin-top: auto;
    min-height: 56px;
    opacity: 0;
    translate: 0 16px;
    transition: opacity var(--dur-1) ease, translate var(--dur-1) ease;
  }

  .js .tt-nav.is-open .tt-nav__cta {
    opacity: 1;
    translate: 0 0;
    transition: opacity var(--dur-2) var(--ease-out) .25s, translate var(--dur-2) var(--ease-out) .25s;
  }

  /* Ohne JS: schlichte, sichtbare Linkliste im Seitenfluss */
  html:not(.js) .tt-nav {
    position: relative;
    flex-wrap: wrap;
    height: auto;
    min-height: var(--nav-h);
    padding-block: var(--s-3);
    row-gap: var(--s-2);
  }

  html:not(.js) .tt-nav__menu {
    flex: 1 1 100%;
    flex-wrap: wrap;
    gap: var(--s-3) var(--s-5);
  }

  html:not(.js) .tt-nav__list {
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 0 var(--s-5);
    margin: 0;
  }

  html:not(.js) .tt-hero,
  html:not(.js) .tt-pagehead {
    padding-top: var(--s-6);
  }
}

/* Sehr schmal: Wortmarke auf Weltseiten und das Wort am Burger weglassen */
@media (max-width: 419.98px) {
  .tt-nav__brand:has(.tt-nav__world) .tt-nav__word {
    display: none;
  }
}

@media (max-width: 359.98px) {
  .tt-nav__burger-text {
    display: none;
  }
}

/* ============================================================
   6  BUTTONS  .tt-btn
   ------------------------------------------------------------
   <a class="tt-btn tt-btn--primary" href="wizardrp">WizardRP betreten
     <svg class="tt-btn__icon" viewBox="0 0 256 256" aria-hidden="true">(Phosphor arrow-right)</svg></a>
   Varianten: --primary (Akzentfläche), --ghost (1px Rahmen), --text (Link mit Pfeil)
   Größen:    --sm (40px, Leiste), Standard 48px, --lg (56px, Hero)
   Weitere:   --block (volle Breite), .is-disabled oder aria-disabled="true" (noch nicht verfügbar)
   Icon:      .tt-btn__icon hinter dem Text rückt beim Hover nach rechts,
              mit .tt-btn__icon--out (arrow-up-right) diagonal, vor dem Text bleibt es stehen.
   Rückmeldung: Fläche fährt per transform von unten ein, :active drückt auf .98.
   ============================================================ */

.tt-btn {
  --btn-bg: color-mix(in srgb, var(--ink-0) 30%, transparent);
  --btn-fg: var(--text);
  --btn-border: var(--line-strong);
  --btn-fill: var(--text);
  --btn-fill-fg: var(--ink-0);
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .625rem;
  min-height: 48px;
  padding: 0 1.375rem;
  overflow: hidden;
  border: 1px solid var(--btn-border);
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--btn-family);
  font-size: var(--btn-size);
  font-stretch: var(--btn-stretch);
  font-weight: var(--btn-weight);
  letter-spacing: var(--btn-tracking);
  text-transform: var(--btn-case);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  transition: color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), transform var(--dur-1) var(--ease-out);
}

/* einfahrende Fläche */
.tt-btn::before {
  content: "";
  position: absolute;
  inset: -1px;
  z-index: var(--z-below);
  background: var(--btn-fill);
  transform: translateY(102%);
  transition: transform var(--dur-2) var(--ease-out);
}

.tt-btn__icon {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  fill: currentColor;
  transition: transform var(--dur-2) var(--ease-out);
}

.tt-btn--primary {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-ink);
  --btn-border: var(--accent);
  --btn-fill: color-mix(in srgb, var(--accent) 62%, var(--text));
  --btn-fill-fg: var(--accent-ink);
}

.tt-btn--ghost {
  --btn-border: var(--line-strong);
}

.tt-btn--sm {
  min-height: 40px;
  padding: 0 1rem;
  gap: .5rem;
  font-size: calc(var(--btn-size) * .9);
}

.tt-btn--lg {
  min-height: 56px;
  padding: 0 1.75rem;
  font-size: calc(var(--btn-size) * 1.07);
}

.tt-btn--block {
  display: flex;
  width: 100%;
}

@media (hover: hover) {
  .tt-btn:not(.tt-btn--text, .is-disabled, [aria-disabled="true"], :disabled):hover {
    --btn-border: var(--btn-fill);
    color: var(--btn-fill-fg);
  }

  .tt-btn:not(.is-disabled, [aria-disabled="true"], :disabled):hover::before {
    transform: none;
  }

  .tt-btn:not(.is-disabled, [aria-disabled="true"], :disabled):hover .tt-btn__icon:last-child {
    transform: translateX(4px);
  }

  .tt-btn:not(.is-disabled, [aria-disabled="true"], :disabled):hover .tt-btn__icon--out:last-child {
    transform: translate(3px, -3px);
  }
}

.tt-btn:not(.is-disabled, [aria-disabled="true"], :disabled):active {
  transform: scale(.98);
}

/* Textlink mit Pfeil */
.tt-btn--text {
  --btn-bg: transparent;
  min-height: 44px;
  padding: 0;
  overflow: visible;
  border: 0;
  border-radius: 0;
  gap: .5rem;
}

.tt-btn--text::before,
.tt-btn--text::after {
  content: "";
  position: absolute;
  inset: auto 0 9px 0;
  z-index: var(--z-below);
  height: 1px;
  background: currentColor;
}

.tt-btn--text::before {
  opacity: .28;
  transform: none;
  transition: none;
}

.tt-btn--text::after {
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform var(--dur-2) var(--ease-out);
}

@media (hover: hover) {
  .tt-btn--text:not(.is-disabled, [aria-disabled="true"], :disabled):hover::after {
    transform: scaleX(1);
    transform-origin: 0 50%;
  }
}

/* Noch nicht verfügbar: sichtbar, aber ohne Aufforderung */
.tt-btn.is-disabled,
.tt-btn[aria-disabled="true"],
.tt-btn:disabled {
  --btn-bg: transparent;
  --btn-fg: var(--text-3);
  --btn-border: var(--line-strong);
  border-style: dashed;
  cursor: not-allowed;
}

.tt-btn--text.is-disabled::before,
.tt-btn--text[aria-disabled="true"]::before {
  opacity: .18;
}

/* ============================================================
   7  STATUS-CHIPS  .tt-chip
   ------------------------------------------------------------
   <span class="tt-chip tt-chip--live" data-status="wizard"><i class="tt-chip__dot" aria-hidden="true"></i>
     <span data-status-field="label">Live</span></span>
   <span class="tt-chip tt-chip--wip">In Arbeit</span>
   <span class="tt-chip tt-chip--soon">Coming Soon</span>
   Der Punkt steht nur für echten Serverstatus. Mit data-status folgt er dem Live-Zustand.
   Chips gehören nicht über Bilder.
   ============================================================ */

.tt-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink-0) 40%, transparent);
  font-family: var(--meta-family);
  font-size: .6875rem;
  font-weight: var(--meta-weight);
  letter-spacing: var(--meta-tracking);
  text-transform: var(--meta-case);
  line-height: 1;
  white-space: nowrap;
  color: var(--text-2);
}

.tt-chip--live {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 42%, transparent);
}

.tt-chip--wip {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 42%, transparent);
}

.tt-chip--soon {
  color: var(--info);
  border-color: color-mix(in srgb, var(--info) 42%, transparent);
}

.tt-chip__dot,
.tt-status__dot {
  position: relative;
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ok);
}

.tt-chip__dot::after,
.tt-status__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: tt-pulse 2.6s var(--ease-out) infinite;
}

@keyframes tt-pulse {
  0% {
    transform: scale(1);
    opacity: .55;
  }

  70%,
  100% {
    transform: scale(3.4);
    opacity: 0;
  }
}

/* Live-Chip, der an data-status hängt: Server nicht erreichbar oder Zustand unbekannt */
.tt-chip--live[data-state="offline"],
.tt-chip--live[data-state="unknown"] {
  color: var(--text-2);
  border-color: var(--line-strong);
}

/* ============================================================
   8  LIVE-STATUS  .tt-status
   ------------------------------------------------------------
   <p class="tt-status" data-status="wizard">
     <span class="tt-status__dot" aria-hidden="true"></span>
     <span class="tt-status__label" data-status-field="label">WizardRP</span>
     <span class="tt-status__count" data-status-when="online">
       <b data-status-field="players">0</b> von <span data-status-field="max">128</span> Spielern</span>
     <span class="tt-status__count" data-status-when="offline unknown">128 Slots</span>
   </p>
   core.js setzt data-state="online|offline|unknown" am Element mit data-status und füllt die Felder.
   data-status-when="online" (auch mehrere Werte) zeigt ein Kind nur in diesem Zustand.
   Vor dem ersten Abruf und ohne JS gilt "unknown": der statische Text bleibt stehen.
   Variante: --framed (mit Haarlinien-Rahmen)
   ============================================================ */

.tt-status {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 28px;
  font-family: var(--meta-family);
  font-size: var(--meta-size);
  font-weight: var(--meta-weight);
  letter-spacing: var(--meta-tracking);
  text-transform: var(--meta-case);
  line-height: 1.2;
  white-space: nowrap;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

.tt-status--framed {
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--ink-0) 40%, transparent);
}

.tt-status__label {
  color: var(--text);
}

.tt-status__count {
  padding-left: 10px;
  background: linear-gradient(var(--line-strong), var(--line-strong)) left center / 1px 12px no-repeat;
}

.tt-status__count b {
  font-weight: 600;
  color: var(--text);
}

/* Live-Zahlen: gleich breite Ziffern und eine Mindestbreite, damit ein Wechsel (9 auf 10) nichts schiebt.
   Breite je Stelle über --num-w steuern, zum Beispiel style="--num-w: 3ch". */
[data-status-field] {
  font-variant-numeric: tabular-nums;
}

[data-status-field]:is([data-status-field="players"], [data-status-field="max"], [data-status-field="members"], [data-status-field="online"]) {
  display: inline-block;
  min-width: var(--num-w);
  text-align: end;
}

[data-status-field="max"],
[data-status-field="members"],
[data-status-field="online"] {
  --num-w: 3ch;
}

/* Punkt folgt dem Zustand: nur "online" ist grün und pulsiert */
[data-status]:not([data-state="online"]) :is(.tt-status__dot, .tt-chip__dot),
[data-status]:not([data-state="online"]):is(.tt-status__dot, .tt-chip__dot) {
  background: var(--text-3);
}

[data-status]:not([data-state="online"]) :is(.tt-status__dot, .tt-chip__dot)::after {
  animation: none;
  opacity: 0;
}

/* Sichtbarkeit je Zustand */
[data-status][data-state="online"] [data-status-when]:not([data-status-when~="online"]),
[data-status][data-state="offline"] [data-status-when]:not([data-status-when~="offline"]),
[data-status][data-state="unknown"] [data-status-when]:not([data-status-when~="unknown"]),
[data-status]:not([data-state]) [data-status-when]:not([data-status-when~="unknown"]) {
  display: none !important;
}

/* ============================================================
   9  FUSSZEILE  .tt-footer
   ------------------------------------------------------------
   Aufbau siehe _skeleton.html: __top (__brand mit __emblem und __claim, daneben __cols mit vier
   __col aus __title und __list mit __link), __note (Fan-Hinweis je Welt), __bottom.
   ============================================================ */

.tt-footer {
  position: relative;
  padding-block: clamp(3.5rem, 2rem + 6vw, 7rem) var(--s-6);
  background: var(--ink-1);
  border-top: 1px solid var(--line);
  color: var(--text-2);
  font-size: .9375rem;
  line-height: 1.5;
}

.tt-footer__top {
  display: grid;
  gap: var(--s-8) var(--grid-gap);
}

@media (min-width: 1000px) {
  .tt-footer__top {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  }
}

.tt-footer__brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-5);
}

.tt-footer__emblem {
  width: 72px;
  height: 72px;
  object-fit: contain;
}

.tt-footer__claim {
  font-family: var(--display-family);
  font-size: min(calc(var(--step-3) * var(--display-scale)), calc(var(--display-cap) * .8));
  font-stretch: var(--display-stretch);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: calc(var(--display-leading) + .07);
  text-transform: var(--display-case);
  padding-bottom: var(--display-pad);
  color: var(--text);
  text-wrap: balance;
}

.tt-footer__claim em {
  display: block; /* zweite Zeile des Leitsatzes, bricht sonst bei breiten Welt-Schriften mitten im Satz */
  font-style: var(--em-style);
  color: var(--accent);
}

.tt-footer__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-7) var(--grid-gap);
}

@media (min-width: 640px) {
  /* beliebig viele Spalten nebeneinander (Hub: drei) */
  .tt-footer__cols {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }
}

.tt-footer__title {
  margin-bottom: var(--s-3);
  font-family: var(--meta-family);
  font-size: var(--meta-size);
  font-weight: var(--meta-weight);
  letter-spacing: var(--meta-tracking);
  text-transform: var(--meta-case);
  line-height: 1.5;
  color: var(--text-3);
}

.tt-footer__list {
  display: grid;
  justify-items: start;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tt-footer__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  color: var(--text-2);
  transition: color var(--dur-1) ease;
}

.tt-footer__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 7px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform var(--dur-2) var(--ease-out);
}

@media (hover: hover) {
  .tt-footer__link:hover {
    color: var(--text);
  }

  .tt-footer__link:hover::after {
    transform: scaleX(1);
    transform-origin: 0 50%;
  }
}

.tt-footer__link[aria-current="page"] {
  color: var(--text);
}

@media (pointer: coarse) {
  .tt-footer__link {
    min-height: 44px;
  }
}

/* Fan-Hinweis der jeweiligen Welt. Mehrere Absätze möglich. */
.tt-footer__note {
  max-width: 78ch;
  margin-top: var(--s-8);
  font-size: var(--step--1);
  line-height: 1.6;
  color: var(--text-3);
}

.tt-footer__note + .tt-footer__note {
  margin-top: var(--s-2);
}

.tt-footer__note a {
  color: var(--text-2);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
}

@media (hover: hover) {
  .tt-footer__note a:hover {
    color: var(--text);
  }
}

.tt-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s-2) var(--s-6);
  margin-top: var(--s-7);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
  font-family: var(--meta-family);
  font-size: var(--meta-size);
  font-weight: var(--meta-weight);
  letter-spacing: var(--meta-tracking);
  text-transform: var(--meta-case);
  line-height: 1.6;
  color: var(--text-3);
}

.tt-footer__note + .tt-footer__bottom {
  margin-top: var(--s-6);
}

.tt-footer__bottom a {
  color: var(--text-2);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
}

@media (hover: hover) {
  .tt-footer__bottom a:hover {
    color: var(--text);
  }
}

/* ============================================================
   10  BILDRAHMEN  .tt-media
   ------------------------------------------------------------
   <figure class="tt-media" style="--ratio: 16 / 9">
     <picture data-parallax="-0.12"> ... <img ...> </picture>
   </figure>
   --ratio   Seitenverhältnis (Standard 16 / 9)
   --focus   object-position (Standard 50% 50%)
   --bleed   Überstand des inneren Bildes für Parallax (Standard 8vh, reicht bis data-parallax ±0.16;
             größere Werte passt core.js selbst an)
   Das innere Element mit data-parallax ist oben und unten um --bleed größer als der Rahmen.
   Keine Labels oder Chips über das Bild legen. Bildunterschrift bei Bedarf als .tt-caption darunter.
   ============================================================ */

.tt-media {
  position: relative;
  display: block;
  aspect-ratio: var(--ratio, 16 / 9);
  overflow: hidden;
  overflow: clip;
  border-radius: var(--radius);
  background: var(--ink-1);
}

.tt-media > :is(picture, img, video, canvas) {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.tt-media :is(img, video) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
}

.tt-media > [data-parallax] {
  top: calc(var(--bleed, 8vh) * -1);
  height: calc(100% + var(--bleed, 8vh) * 2);
}

html:not([data-fx="off"]) [data-parallax] {
  will-change: transform;
}

.tt-caption {
  margin-top: var(--s-3);
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--text-3);
}

/* ============================================================
   11  ZUSTÄNDE FÜR core.js
   ============================================================ */

/* Reveal. core.js vergibt .tt-rv nur an Elemente unterhalb des ersten Sichtbereichs und setzt
   danach .is-in. Nach dem Einblenden werden beide Klassen wieder entfernt.
   Hart begrenzt: 0,6 s, 24px Weg, einmalig, nur opacity und translate. */
.tt-rv:not(.is-in) {
  opacity: 0;
  translate: 0 24px;
}

.tt-rv[data-reveal="fade"]:not(.is-in) {
  translate: none;
}

.tt-rv.is-in {
  transition:
    opacity .6s var(--ease-out) var(--rv-delay, 0s),
    translate .6s var(--ease-out) var(--rv-delay, 0s);
}

/* SplitText (lines, words, chars): Masken bekommen Luft, damit Umlautpunkte und Unterlängen
   bei enger Zeilenhöhe nicht abgeschnitten werden. */
.tt-line-mask {
  padding-block: .16em;
  margin-block: -.16em;
}

.tt-word,
.tt-char {
  will-change: transform, opacity;
}

/* Tilt: core.js setzt .tt-tilt und während der Bewegung .is-tilting sowie --tilt-x und --tilt-y.
   Der Effekt belegt die transform-Eigenschaft des Elements. */
.tt-tilt.is-tilting {
  transform: perspective(1100px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  will-change: transform;
}

/* Wächter-Elemente für IntersectionObserver */
.tt-sentinel {
  position: absolute;
  left: 0;
  width: 1px;
  height: 24px;
  pointer-events: none;
  visibility: hidden;
}

.tt-sentinel--top {
  top: 0;
}

.tt-sentinel--end {
  bottom: 0;
  height: 1px;
}

/* Scroll-Sperre (mobiles Menü, Dialoge): core.js lockScroll() */
html.tt-lock {
  overflow: hidden;
}

/* ============================================================
   12  REDUZIERTE BEWEGUNG, DRUCK
   ============================================================ */

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

  .tt-chip__dot::after,
  .tt-status__dot::after {
    animation: none !important;
    opacity: 0;
  }

  .tt-nav.is-hidden,
  [data-autohide].is-hidden {
    transform: none;
  }

  .tt-rv {
    opacity: 1 !important;
    translate: none !important;
  }

  [data-parallax] {
    will-change: auto;
  }

  .tt-tilt.is-tilting {
    transform: none;
  }
}

/* Gleiches Verhalten, wenn core.js die Effekte aus anderem Grund abschaltet (?fx=off) */
html[data-fx="off"] .tt-nav.is-hidden,
html[data-fx="off"] [data-autohide].is-hidden {
  transform: none;
}

@media print {
  .tt-nav,
  .tt-skip {
    display: none !important;
  }

  .tt-rv {
    opacity: 1 !important;
    translate: none !important;
  }
}
