/* ==========================================================================
   Tipsy Traveller — Design-System
   Farben/Muster aus dem Styleguide + den Location-Fotos abgeleitet.
   Überschriften: Engebrechtre, sobald die Font-Datei vorliegt — bis dahin
   hochwertiger Serifen-System-Stack (siehe --font-display).
   Fließtext: Inter (SIL Open Font License, lizenzkostenfrei), lokal
   gehostet unter public/fonts/ statt über Googles CDN eingebunden — sonst
   würde bei jedem Seitenaufruf die IP-Adresse der Besucher an Google
   übertragen, was in Deutschland ohne Einwilligung ein DSGVO-Verstoß wäre
   (LG München I, Urt. v. 20.01.2022 – 3 O 17493/20).
   ========================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-latin-variable.woff2") format("woff2-variations"), url("/fonts/inter-latin-variable.woff2") format("woff2");
}

:root {
  /* Brand — aus dem Logo-Styleguide */
  --tt-navy: #0a1a33;
  --tt-navy-raised: #16253f;
  --tt-green: #2f3e2d;
  --tt-rose: #aa8572;
  --tt-rose-beige: #c3aea7;
  --tt-gold: #a98f4a;
  --tt-wallpaper-line: #c3aea7;
  --tt-black: #000000;
  --tt-white: #ffffff;

  /* Content (helle Lesebereiche) */
  --paper: #f5efea;
  --paper-raised: #ffffff;
  --ink: #1f2837;
  --ink-soft: #5b6874;
  --line: rgba(31, 40, 55, 0.14);
  --accent: #aa8572;
  --accent-2: #2f3e2d;

  /* Chrome (Header/Footer — immer dunkel, unabhängig vom OS-Theme) */
  --chrome-bg: #0a1a33;
  --chrome-bg-raised: #16253f;
  --chrome-ink: #f1e9e1;
  --chrome-ink-soft: #c3aea7;
  --chrome-line: rgba(241, 233, 225, 0.18);
  --chrome-accent: #c3aea7;

  /* Rose (helle/mittlere Rose-Flächen — Abschnitte im Wechsel mit Blau,
     sowie Karten) — dunkle, warme Lesefarben statt hellem Chrome-Text. */
  --rose-ink: #241812;
  --rose-ink-soft: #4a372c;
  --rose-line: rgba(36, 24, 18, 0.18);

  --shadow-soft: 0 1px 2px rgba(31, 40, 55, 0.08), 0 8px 24px rgba(31, 40, 55, 0.08);
  --shadow-chrome: 0 4px 20px rgba(0, 0, 0, 0.35);

  --font-display: "Engebrechtre", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --font-body: "Inter", -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", Consolas, monospace;

  --radius: 8px;
  --container-width: 1180px;

  /* Feine Papiermaserung für die Passseiten-Optik der Abschnittskarten —
     abstraktes fractalNoise, per feColorMatrix in eine weiße Alphamaske
     verwandelt, damit background-blend-mode:overlay es organisch über die
     jeweilige Kartenfarbe legt statt eine feste Farbe zu überdecken. */
  --page-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='tt-grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.45 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23tt-grain)'/%3E%3C/svg%3E");
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Sicherheitsnetz: verhindert, dass die ganze Seite horizontal
     verschiebbar wird, falls irgendein Inhaltsblock (z.B. eine lange
     Preiszeile) mal breiter als der Viewport gerät. Einzelne Bereiche
     können weiterhin gezielt eigenes overflow-x: auto setzen. */
  overflow-x: hidden;
}

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent-2);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 3px;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  text-wrap: balance;
  margin: 0 0 0.5em;
  letter-spacing: 0.01em;
}

p {
  margin: 0 0 1rem;
}

.container {
  width: 100%;
  max-width: var(--container-width);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

/* --------------------------------------------------------------------
   Bogen-/Ovalmuster — festes CI-Element, auf dunklen Flächen (Chrome)
   -------------------------------------------------------------------- */

.pattern-arches {
  position: relative;
  /* `clip`, not `hidden` — hidden still makes this a scroll container even
     without a visible scrollbar, so an in-page anchor jump (e.g. the
     "Gutscheine" nav link) can end up scrolling *inside* this element
     instead of the actual page: the window never moves, the content shifts
     invisibly with no way to scroll further, and the footer stays exactly
     where it always was — looking like a huge gap once you do get there.
     `clip` still confines the fixed-position pattern layer below to this
     section's own box without opting into that scroll-container
     behavior. */
  overflow: clip;
  /* Text, der direkt auf dem Muster liegt, braucht etwas Kontrast gegen die
     kreuzenden Linien im Hintergrund — vererbt sich auf allen Text
     innerhalb, wird aber unten für die geboxten Karten (section-dark /
     section-rose) wieder zurückgesetzt, da deren Text auf Vollfarbe sitzt. */
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}

.section-dark,
.section-rose,
.section-passport {
  text-shadow: none;
}

/* Muster sitzt fix am Viewport (statt an der Seite zu scrollen) — der
   Inhalt bewegt sich darüber hinweg, das Musterband selbst steht still.
   War vorher ein Scroll-Parallax (Hintergrund läuft langsamer als der
   Inhalt statt stillzustehen), erst per JS+CSS-Custom-Property, dann per
   JS+direktem Transform — auf Touch-Geräten blieb es trotz beidem
   spürbar ruckelig, weil scroll-Events dort dem compositor-gesteuerten
   nativen Scrollen grundsätzlich hinterherhinken. position: fixed
   braucht dagegen gar kein JS mehr: der Browser positioniert das rein
   über CSS, ohne pro Frame etwas nachzurechnen — dadurch garantiert
   ruckelfrei auf jedem Gerät. Netter Nebeneffekt: alle
   .pattern-arches-Abschnitte einer Seite zeigen dieselbe, am Viewport
   verankerte Musterphase, dadurch keine sichtbare Naht mehr zwischen
   ihnen. */
.pattern-arches::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;

  /* Woven stadium/pill trellis — matches the reference pattern 1:1: deep
     navy ground, thin opaque rosé-beige lattice made of interlocking
     "pill" shapes (semicircular top/bottom, straight sides) rather than
     full ellipses — no separate line strokes, the "spine" look comes
     purely from adjacent pills overlapping at their tangent points. Each
     pill is an SVG rect (224x400) with rx=112 — since the corner radius
     equals half the width, the top/bottom edges become full semicircles
     while the sides stay straight. Built as a seamless tile: two straight
     columns (x=0 / x=320, period 400) plus one half-offset column between
     them (x=160, offset by 200) — a classic brick-weave lattice, drawn
     wide enough to tile without seams. Doubled in scale from the original
     160x200 tile (same proportions/stroke ratio, just larger). Opacity
     sits on the &lt;g&gt; itself (not stroke-opacity per shape) — stroke-opacity
     would composite each overlapping stroke separately, so tangent points
     where two pills cross come out visibly darker. Group opacity flattens
     the whole lattice first and dims it once, so it's the same tone
     everywhere, crossings included. */
  background-color: var(--chrome-bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='400' viewBox='0 0 320 400'%3E%3Cg fill='none' stroke='%23c3aea7' stroke-width='3.5' opacity='0.4'%3E%3Crect x='-112' y='-600' width='224' height='400' rx='112'/%3E%3Crect x='-112' y='-200' width='224' height='400' rx='112'/%3E%3Crect x='-112' y='200' width='224' height='400' rx='112'/%3E%3Crect x='-112' y='600' width='224' height='400' rx='112'/%3E%3Crect x='208' y='-600' width='224' height='400' rx='112'/%3E%3Crect x='208' y='-200' width='224' height='400' rx='112'/%3E%3Crect x='208' y='200' width='224' height='400' rx='112'/%3E%3Crect x='208' y='600' width='224' height='400' rx='112'/%3E%3Crect x='48' y='-400' width='224' height='400' rx='112'/%3E%3Crect x='48' y='0' width='224' height='400' rx='112'/%3E%3Crect x='48' y='400' width='224' height='400' rx='112'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 320px 400px;
}

/* --------------------------------------------------------------------
   Header
   -------------------------------------------------------------------- */

.site-header {
  background: var(--chrome-bg);
  color: var(--chrome-ink);
  position: sticky;
  top: 0;
  z-index: 50;
  box-shadow: var(--shadow-chrome);
}

/* In-page anchor targets (the "Gutscheine" nav jump, the "Tisch
   reservieren" jump on the contact page) need to stop short of the sticky
   header instead of landing flush behind it — header is a steady 72px
   tall at every breakpoint, plus a little breathing room. */
#gutscheine,
#reservieren {
  scroll-margin-top: 88px;
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.brand img {
  height: 40px;
  width: auto;
  display: block;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: 1.8rem;
  flex-wrap: wrap;
}

.main-nav__list {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  gap: 1.5rem;
  flex-wrap: wrap;
}

/* Menüpunkte im Stempel-Stil, passend zu den Passseiten-Badges: ein
   dezenter Stempelring, der beim Hover/aktiven Zustand "abgestempelt"
   wird — gefüllt, dashed Innenring sichtbar, leicht schräg. */
.main-nav__list a {
  display: inline-flex;
  align-items: center;
  position: relative;
  color: var(--chrome-accent);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 0.45em 0.9em;
  border: 1px solid var(--chrome-accent);
  border-radius: 999px;
  opacity: 0.7;
  transition: opacity 0.15s ease, transform 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.main-nav__list a::before {
  content: "";
  position: absolute;
  inset: 2px;
  border: 1px dashed currentColor;
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.15s ease;
}

.main-nav__list a:hover,
.main-nav__list a[aria-current="page"] {
  opacity: 1;
  transform: rotate(-2deg);
}

.main-nav__list a:hover::before,
.main-nav__list a[aria-current="page"]::before {
  opacity: 0.6;
}

.main-nav__list a[aria-current="page"] {
  background-color: var(--chrome-accent);
  color: var(--tt-navy);
}

.lang-switch {
  display: flex;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
}

.lang-switch a {
  color: var(--chrome-ink-soft);
  text-decoration: none;
  padding: 0.2em 0.5em;
  border-radius: 4px;
  border: 1px solid transparent;
}

.lang-switch a[aria-current="true"] {
  color: var(--chrome-ink);
  border-color: var(--chrome-line);
}

/* Tischkarte (QR-only, siehe table-menu.blade.php): eigener, größerer
   Sprachwähler statt .lang-switch — diese Seite hat keine Kopfzeile mit
   Navigation als Rückfallebene, die Sprachwahl muss hier auf den ersten
   Blick auffindbar sein. Sitzt im dunklen .hero-Bereich, daher die
   --chrome-* Tokens statt --ink/--ink-soft. */
.table-menu-lang-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.5rem;
}

.table-menu-lang-switch a {
  padding: 0.5em 1.1em;
  border-radius: 999px;
  border: 1px solid var(--chrome-line);
  color: var(--chrome-ink-soft);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
}

.table-menu-lang-switch a[aria-current="true"] {
  background-color: var(--chrome-accent);
  border-color: var(--chrome-accent);
  color: var(--tt-navy);
}

/* Speisen-/Getränke-Sprungmarken oberhalb der beiden Kartenabschnitte —
   reines Ankerlink-Paar (#food-menu / #drinks-menu), kein JS nötig. */
.table-menu-tabs {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
}

.table-menu-tabs a {
  padding: 0.6em 1.4em;
  border-radius: 999px;
  border: 1px solid var(--ink-soft);
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
}

.table-menu-tabs a:hover {
  background-color: rgba(0, 0, 0, 0.06);
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--chrome-line);
  border-radius: 6px;
  color: var(--chrome-ink);
  padding: 0.4rem 0.6rem;
  font-size: 1.1rem;
  cursor: pointer;
}

/* Sieben Stempel-Badges plus Sprachumschalter brauchen als Pillen (mit
   Rahmen und Innenpolster statt schlichtem Text) spürbar mehr Platz als
   die frühere Unterstreich-Optik — bei 0.9rem+ passen sie erst ab
   1180px (= --container-width) nebeneinander in eine Zeile. Deshalb
   bleibt bis dahin das Mobil-Menü aktiv (siehe unten), auch auf
   Laptop-Breiten. Ab 1180px wächst die Schrift stufenlos (clamp) bis
   1400px auf ihre Zielgröße — die Kopfzeile sitzt in derselben
   .container-Klasse wie der Rest der Seite und wird darüber hinaus
   nicht mehr breiter, deshalb bleibt das Menü ab 1400px bewusst
   konstant statt auf 4K-Monitoren unkontrolliert weiterzuwachsen und
   umzubrechen. Werte bewusst knapper als der Kommentarname suggeriert
   (war ursprünglich für sechs Punkte austariert, siehe Karte-Split in
   Getränke/Speisen) — sieben Punkte brauchen spürbar weniger Luft pro
   Pille, um bei 1180px noch einzeilig zu bleiben. */
@media (min-width: 1180px) {
  .main-nav {
    gap: clamp(1.2rem, 0.1rem + 1.2vw, 1.5rem);
  }

  .main-nav__list {
    gap: clamp(0.9rem, 0.25rem + 0.75vw, 1.1rem);
  }

  .main-nav__list a {
    font-size: clamp(0.76rem, 0.15rem + 0.82vw, 0.87rem);
    padding: 0.48em 0.9em;
  }
}

@media (max-width: 1179px) {
  .nav-toggle {
    display: inline-flex;
  }
  .main-nav {
    display: none;
    position: absolute;
    inset-inline: 0;
    top: 100%;
    background: var(--chrome-bg);
    flex-direction: column;
    align-items: flex-end;
    padding: 1rem 1.5rem 1.5rem;
    box-shadow: var(--shadow-chrome);
  }
  .main-nav.is-open {
    display: flex;
  }
  .main-nav__list {
    flex-direction: column;
    align-items: flex-end;
    gap: 0.6rem;
  }
  /* Im aufgeklappten Menü ist pro Zeile nur ein Stempel zu lesen (kein
     Nebeneinander wie am Desktop) — etwas Luft nach oben, dafür rücken
     die Zeilen selbst enger zusammen (gap oben). */
  .main-nav__list a {
    font-size: 0.76rem;
    padding: 0.5em 0.95em;
  }
}

/* --------------------------------------------------------------------
   Traveller-Pfad — Scroll-Fortschrittsanzeige, die sich durch die ganze
   Seite schlängelt statt geradeaus zu laufen. Absolut positioniert als
   direktes body-Kind (kein positionierter Vorfahre dazwischen), damit es
   sich über die komplette Dokumenthöhe erstreckt und mit der Seite
   mitscrollt. Der Marker ist aktuell ein Platzhalter-Punkt — sobald ein
   freigestelltes Traveller-Icon vorliegt, ersetzt das den Kreis in
   traveller-path.js.
   -------------------------------------------------------------------- */

.traveller-path-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  pointer-events: none;
  z-index: 5;
  overflow: hidden;
}

.traveller-path-layer svg {
  display: block;
}

.traveller-line-ghost {
  fill: none;
  stroke: var(--tt-rose-beige);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 9 10;
  opacity: 0.45;
}

.traveller-marker image {
  /* A light halo keeps the (dark navy) figure readable on the dark
     pattern-arches sections too, not just the light content areas. */
  filter: drop-shadow(0 0 2px var(--paper)) drop-shadow(0 0 2px var(--paper))
    drop-shadow(0 2px 4px rgba(0, 0, 0, 0.35));
}

/* --------------------------------------------------------------------
   Sticky reservation button
   -------------------------------------------------------------------- */

/* Im Stempel-Stil wie die Nav-Links: dashed Innenring, leichte
   Schräglage, die sich beim Hover vertieft — wirkt wie frisch
   abgestempelt statt wie ein gewöhnlicher Button. */
/* Stacked directly above the back-to-top circle (bottom:1.6rem, 52px tall)
   instead of vertically centred — centred used to float over the middle
   of the reading area on narrower windows, right where body text sits. */
/* Startet unsichtbar wie back-to-top — sticky-reserve.js blendet sie erst
   ein, sobald der "Tisch reservieren"-Button im Hero (unter dem Logo)
   aus dem Viewport gescrollt ist, statt doppelt neben ihm zu schweben. */
.sticky-reserve {
  position: fixed;
  z-index: 40;
  right: 1.25rem;
  bottom: 5.5rem;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px) rotate(-3deg);
  background: var(--accent-2);
  color: var(--tt-white);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85rem 1.15rem;
  border-radius: 999px;
  box-shadow: var(--shadow-soft);
  border: 1.5px solid var(--tt-rose-beige);
  transition: opacity 0.2s ease, transform 0.15s ease, background-color 0.15s ease;
}

.sticky-reserve.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) rotate(-3deg);
}

.sticky-reserve::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed currentColor;
  border-radius: inherit;
  opacity: 0.45;
  pointer-events: none;
}

.sticky-reserve:hover {
  background: var(--tt-navy);
  transform: rotate(-6deg);
}

/* --------------------------------------------------------------------
   Back-to-top
   -------------------------------------------------------------------- */

/* Rundstempel wie bei den Event-Terminen: doppelter Ring per
   inset-Box-Shadow statt eines zweiten Rahmens, damit die Kreisform
   sauber bleibt. */
.back-to-top {
  position: fixed;
  z-index: 40;
  right: 1.25rem;
  bottom: 1.6rem;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-2);
  color: var(--tt-white);
  border: 1.5px solid var(--tt-rose-beige);
  box-shadow: inset 0 0 0 4px var(--tt-rose-beige), var(--shadow-soft);
  border-radius: 50%;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px) rotate(-4deg);
  transition: opacity 0.2s ease, transform 0.2s ease, background 0.15s ease;
}

.back-to-top.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) rotate(-4deg);
}

.back-to-top svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* Little flutter on click, timed roughly to the smooth-scroll trip back to
   the top — on the icon only, so it doesn't fight the button's own
   position/visibility transform. */
.back-to-top.is-launching svg {
  animation: paper-plane-wobble 0.7s ease-in-out;
}

@keyframes paper-plane-wobble {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  20% { transform: translateY(-2px) rotate(10deg); }
  40% { transform: translateY(-4px) rotate(-12deg); }
  60% { transform: translateY(-2px) rotate(8deg); }
  80% { transform: translateY(-1px) rotate(-6deg); }
}

.back-to-top:hover {
  background: var(--tt-navy);
  transform: translateY(0) rotate(4deg);
}

/* Mobil: die Reservieren-Leiste wird schmaler und zentriert, der
   Back-to-top-Kreis bleibt rechts frei daneben stehen. */
@media (max-width: 640px) {
  .sticky-reserve {
    top: auto;
    bottom: 1rem;
    left: 50%;
    right: auto;
    transform: translate(-50%, 8px) rotate(-2deg);
    padding: 0.7rem 1rem;
    font-size: 0.72rem;
  }

  .sticky-reserve.is-visible {
    transform: translate(-50%, 0) rotate(-2deg);
  }

  .sticky-reserve:hover {
    transform: translate(-50%, 0) rotate(-4deg);
  }

  .back-to-top {
    right: 1rem;
    bottom: 1rem;
    width: 44px;
    height: 44px;
  }

  .back-to-top svg {
    width: 17px;
    height: 17px;
  }
}

/* --------------------------------------------------------------------
   Reservierungs-Panel — seitlich ausklappend statt eigener Seite
   -------------------------------------------------------------------- */

.reservation-panel-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 26, 51, 0.55);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
  /* Höher als event-modal/lightbox (beide 90/91) — die Reservierung
     lässt sich auch aus einem offenen Event-Modal heraus öffnen (der
     "Tisch reservieren"-Link darin) und muss dann davor liegen, nicht
     dahinter. */
  z-index: 92;
  touch-action: none;
}

.reservation-panel-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.reservation-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(480px, 92vw);
  /* Aged paper instead of flat white, same recipe as the menu pages and
     highlight cards. */
  background-color: #e6d9b8;
  background-image: var(--page-grain);
  background-repeat: repeat;
  background-size: 200px 200px;
  background-blend-mode: overlay;
  box-shadow: -8px 0 32px rgba(10, 26, 51, 0.25);
  z-index: 93;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.3s ease;
  /* Verhindert Scroll-Chaining zur Seite dahinter (siehe
     body.reservation-panel-open weiter unten) — nicht selbst scrollbar,
     aber als Sicherheitsnetz falls Touch-Gesten über den Panelrand
     hinaus interpretiert werden. */
  overscroll-behavior: contain;
}

.reservation-panel.is-open {
  transform: translateX(0);
}

/* Rose statt des hellen Passpapier-Tons — passt zur Info-Karte weiter
   unten, damit Kopfzeile und Hinweis als ein zusammengehöriges,
   warmes Rose-Element wirken statt zwei unterschiedlich helle Flächen
   nebeneinander zu haben. */
.reservation-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem 1.3rem;
  background: var(--tt-rose);
  color: var(--rose-ink);
  border-bottom: 1px solid var(--rose-ink-soft);
  flex: none;
  /* Nicht scrollbar — Touch-Drags hier sollen nie als Scroll-Geste an
     die Seite dahinter durchgereicht werden. */
  touch-action: none;
}

.reservation-panel-header h2 {
  margin: 0;
  font-size: 1.2rem;
  font-family: var(--font-display);
  color: var(--rose-ink);
}

.reservation-panel-close {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1.5px solid var(--rose-ink);
  background: transparent;
  color: var(--rose-ink);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.reservation-panel-close:hover {
  background: var(--rose-ink);
  color: var(--tt-rose-beige);
}

.reservation-panel-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Feste Höhe, unabhängig davon, ob der Reopen-Button gerade sichtbar
   ist — sonst springt das Widget beim Ein-/Ausblenden der Info-Karte
   nach oben/unten. Der Button wird nur per hidden ein-/ausgeblendet,
   die Zeile selbst bleibt immer gleich groß. */
.reservation-panel-toolbar {
  flex: none;
  height: 2.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Gleicher Rose-Ton wie die Kopfzeile, statt hier auf den hellen
     Passpapier-Untergrund des Panels zu treffen — wirkt zusammen mit
     dem Header wie ein durchgehendes Rose-Band, nicht wie eine
     freischwebende Pille auf hellem Grund. */
  background: var(--tt-rose);
  border-bottom: 1px solid var(--rose-ink-soft);
  touch-action: none;
}

/* position: relative, damit die Hinweise als Overlay über dem iframe
   liegen (position: absolute) statt ihm dauerhaft Höhe wegzunehmen —
   das Widget bekommt so immer die volle verbleibende Höhe. */
.reservation-panel-widget-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
}

/* Kleine Info-Karte über dem Widget statt einer festen Textspalte, die
   ihm dauerhaft Platz wegnimmt — "Alles klar, einchecken" blendet sie
   aus, der Reopen-Button in der Toolbar holt sie bei Bedarf zurück.
   Rose-Ton wie die "Servus"-Karte auf der Startseite (.section-rose),
   damit sie als eigenständiger, warmer Hinweis auffällt statt wie eine
   weitere Formularzeile zu wirken. Der doppelte Rahmen per
   inset-box-shadow ist derselbe Passseiten-Look wie .section-rose >
   .container (--page-ink/--page-bg dort = genau --rose-ink/--tt-rose
   hier), nur ohne Drehung/Heftung — das würde auf dieser kleinen
   Fläche zu unruhig wirken. */
.reservation-panel-notes {
  position: absolute;
  z-index: 2;
  top: 0.8rem;
  left: 0.8rem;
  right: 0.8rem;
  /* Höhe richtet sich nach dem Inhalt statt die Fläche bis unten
     auszufüllen — sonst bleibt unter dem Button auf hohen Panels viel
     leere Rose-Fläche stehen. max-height + overflow-y bleiben als
     Sicherheitsnetz für sehr kleine Bildschirme. */
  max-height: calc(100% - 1.6rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 1rem 1.1rem;
  border-radius: 3px;
  box-shadow:
    inset 0 0 0 1px var(--rose-ink),
    inset 0 0 0 4px var(--tt-rose),
    inset 0 0 0 5px var(--rose-ink),
    var(--shadow-soft);
  font-size: 0.92rem;
  line-height: 1.45;
  background: var(--tt-rose);
  color: var(--rose-ink);
}

.reservation-panel-notes p {
  margin: 0 0 0.6rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px dashed var(--rose-ink-soft);
}

.reservation-panel-notes p:last-child {
  margin: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.reservation-panel-notes-dismiss {
  display: block;
  margin: 0.8rem auto 0;
  padding: 0.55rem 1.2rem;
  border: 1.5px solid var(--tt-rose-beige);
  border-radius: 999px;
  background: var(--tt-rose-beige);
  color: var(--rose-ink);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.84rem;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.reservation-panel-notes-dismiss:hover {
  background: var(--tt-white);
  border-color: var(--tt-white);
  color: var(--rose-ink);
}

/* Stempel-Look wie .passport-stamp (gestrichelter Innenring, leichte
   Schräglage, Pillenform) statt eines gewöhnlichen Buttons — reiht sich
   damit optisch bei den anderen Stempel-Elementen der Seite ein. */
.reservation-panel-notes-reopen {
  position: relative;
  padding: 0.5em 1.2em;
  border: 1.5px solid var(--rose-ink);
  border-radius: 999px;
  background: var(--tt-rose);
  color: var(--rose-ink);
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--shadow-soft);
  transform: rotate(-2deg);
  transition: transform 0.15s ease;
}

.reservation-panel-notes-reopen::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed currentColor;
  border-radius: inherit;
  opacity: 0.55;
  pointer-events: none;
}

.reservation-panel-notes-reopen:hover {
  transform: rotate(-2deg) translateY(-1px);
}

.reservation-panel-widget-wrap iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  /* Solange die Info-Karte aktiv ist, liest sich das Widget dahinter
     bewusst ausgeblichen/unscharf statt scharf und interaktiv — betont
     die Karte als das, worauf gerade reagiert werden soll.
     pointer-events: none verhindert Klicks/Scrollen im unscharfen
     Widget, solange sie sichtbar ist. */
  filter: blur(3px) brightness(0.82);
  pointer-events: none;
  /* pointer-events: none macht das iframe selbst schon untouchbar, aber
     iOS Safari kann Touch-Drags trotzdem noch als Scroll-Geste an die
     Seite dahinter durchreichen (dasselbe Muster wie Header/Toolbar
     oben) — touch-action: none blockt das explizit. Sobald die Karte
     weg ist, braucht das Widget seine eigene Scroll-/Touch-Steuerung
     zurück (touch-action: auto). */
  touch-action: none;
  transition: filter 0.2s ease;
}

.reservation-panel-body.notes-collapsed .reservation-panel-widget-wrap iframe {
  filter: none;
  pointer-events: auto;
  touch-action: auto;
}

/* Vorher stand hier zusätzlich position: fixed (body.style.top gepinnt),
   um Touch-Scroll-Durchsickern auf iOS zu verhindern — das sperrte die
   Seite zwar zuverlässig, brachte aber ein schlimmeres Problem: Safaris
   halbtransparente untere Werkzeugleiste zeigt sonst live einen Blur des
   Seiteninhalts direkt darunter; das Pinnen/Entpinnen brachte diesen
   Blur-Schnappschuss durcheinander und ließ danach dauerhaft einen
   hellen Balken um die URL-Leiste stehen. overscroll-behavior: contain
   auf der einzigen wirklich scrollbaren Fläche im Panel
   (.reservation-panel-notes) verhindert das Scroll-Chaining zur Seite
   dahinter genauso zuverlässig, ohne body selbst anzufassen. */
body.reservation-panel-open {
  overflow: hidden;
}

@media (max-width: 640px) {
  .reservation-panel {
    width: 100%;
  }
}

/* --------------------------------------------------------------------
   Event-Info-Modal — Klick auf eine Veranstaltung im Abflugtafel-Board
   öffnet die Detailinfos hier statt wegzunavigieren; Vor/Zurück wechselt
   zwischen den Events derselben Tafel, ohne das Modal zu schließen.
   -------------------------------------------------------------------- */

.event-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 26, 51, 0.6);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
  z-index: 90;
}

.event-modal-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.event-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  width: min(640px, 92vw);
  max-height: 85vh;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 20px 60px rgba(10, 26, 51, 0.35);
  z-index: 91;
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -48%) scale(0.97);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}

.event-modal.is-open {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, -50%) scale(1);
}

.event-modal-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 2.2rem 2rem 1.2rem;
}

.event-modal-close {
  position: absolute;
  top: 0.8rem;
  right: 0.8rem;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--paper-raised);
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  z-index: 1;
}

.event-modal-close:hover {
  border-color: var(--accent-2);
  color: var(--accent-2);
}

.event-modal-footer {
  flex: none;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.3rem;
  border-top: 1px solid var(--line);
}

.event-modal-nav {
  border: none;
  background: none;
  padding: 0.3rem 0;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--accent-2);
  cursor: pointer;
}

.event-modal-nav:hover {
  text-decoration: underline;
}

.event-modal-nav:disabled {
  color: var(--ink-soft);
  opacity: 0.5;
  cursor: default;
  text-decoration: none;
}

.event-modal-nav--next {
  margin-left: auto;
}

body.event-modal-open {
  overflow: hidden;
}

/* Der geladene Inhalt kommt 1:1 aus der Event-Detailseite (Hero + Section) —
   im Modal selbst braucht es weder das eigene hero-Pattern noch die
   "Zurück"-Zeile, nur Titel/Termine/Beschreibung kompakt untereinander.
   Kein eigenes padding-right mehr für den Schließen-Button: das machte
   das Ticket schmaler als den Textbereich darunter (der dieses Padding
   nicht hat). Unnötig ohnehin — .event-ticket bringt durch margin-top
   schon genug Abstand von oben mit, der Button sitzt vollständig darüber. */
.event-modal-hero {
  margin-bottom: 1.5rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid var(--line);
}

.event-modal-loading,
.event-modal-error {
  padding: 2rem 0;
  text-align: center;
  color: var(--ink-soft);
}

@media (max-width: 640px) {
  .event-modal {
    width: 100%;
    max-height: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border-radius: 0;
    transform: translateY(8px);
  }

  .event-modal.is-open {
    transform: translateY(0);
  }
}

/* --------------------------------------------------------------------
   Main content
   -------------------------------------------------------------------- */

main {
  min-height: 60vh;
}

.section {
  padding-block: 3.5rem;
}

/* Bogenmuster-Wrapper: der Abschnitt selbst bleibt transparent und gibt
   den Blick auf das durchgehende Musterband dahinter frei (.pattern-arches,
   einmal um den ganzen Startseiten-Inhalt gelegt — siehe home.blade.php).
   Farbe/Textur sitzen stattdessen auf dem inneren .container als eigene
   "Passseite" (siehe Block weiter unten) — auf allen Breiten, nicht nur
   ab Desktop. */
.pattern-arches > .section {
  padding-block: 1.25rem;
}

.section-dark,
.section-rose,
.section-passport {
  background: transparent;
}

.section-dark {
  color: var(--chrome-ink);
  --page-ink: var(--chrome-accent);
  /* Etwas helleres Navy statt exakt --chrome-bg: Karte und Musterband
     dahinter wären sonst dieselbe Farbe und kaum zu unterscheiden. */
  --page-bg: var(--chrome-bg-raised);
}

.section-rose {
  color: var(--rose-ink);
  --page-ink: var(--rose-ink);
  --page-bg: var(--tt-rose);
}

/* Veranstaltungsseite: gleiche Hintergrundfarbe wie die Events-Karte auf
   der Startseite, aber bewusst ohne das Passseiten-Rahmenwerk (Rahmen,
   Wasserzeichen-Stempel) — hier soll die Tafel für sich stehen. */
.section-events-board {
  background: var(--tt-rose);
  color: var(--rose-ink);
}

/* Getränke-/Speisekarte: gealtertes Papier wie die "Findet uns"-Passseite,
   aber wieder bewusst ohne das Rahmenwerk (Doppelrahmen, Drehung, Heftung,
   Seitenzahl) — hier soll es einfach wie eine Speisekarte auf altem Papier
   aussehen, keine weitere Passseiten-Requisite. */
.section-menu-paper {
  background-color: #e6d9b8;
  background-image: var(--page-grain);
  background-repeat: repeat;
  background-size: 200px 200px;
  background-blend-mode: overlay;
}

.section-rose h1,
.section-rose h2,
.section-rose h3,
.section-rose h4 {
  color: var(--rose-ink);
}

/* Passseite in Creme statt Akzentfarbe — die "Datenseite" zwischen den
   gestempelten Rose-/Navy-Seiten. */
.section-passport {
  color: var(--ink);
  --page-ink: var(--accent-2);
  /* Neither --paper-raised (pure white, #fff) nor --paper (#f5efea, too
     pale to read as beige next to the saturated rose/navy cards) work
     here — this needs to look like actual aged manila paper. */
  --page-bg: #e6d9b8;
}

.section-passport .hours-list li {
  border-bottom-color: var(--line);
}

/* --------------------------------------------------------------------
   Passseiten — jede Karte liest sich wie eine Seite aus einem benutzten
   Reisepass: doppelte Rahmenlinie wie im Passdruck (als inset-Box-Shadow,
   damit sie auch randlos auf Mobil sauber sitzt), feine Papiermaserung,
   minimale Drehung wie eine eingescannte Seite, eine Heftung links
   (::before) und eine Seitenzahl unten rechts (::after, aus dem
   data-page-Attribut in home.blade.php). Gilt auf allen Breiten — ab
   Desktop kommt zusätzlich Zentrierung, mehr Innenabstand und ein
   weicher Schlagschatten dazu, weil dort genug Randfläche ist, damit die
   Karte sichtbar über dem Musterband "schwebt".
   -------------------------------------------------------------------- */

.section-dark > .container,
.section-rose > .container,
.section-passport > .container {
  position: relative;
  border-radius: 3px;
  padding: 1.75rem 1.5rem;
  background-color: var(--page-bg);
  background-image: var(--page-grain);
  background-repeat: repeat;
  background-size: 200px 200px;
  background-blend-mode: overlay;
  box-shadow:
    inset 0 0 0 1px var(--page-ink),
    inset 0 0 0 5px var(--page-bg),
    inset 0 0 0 6px var(--page-ink);
}

/* translateZ(0) alongside the rotation: promotes the container to its own
   GPU compositing layer. A non-axis-aligned rotation (even a fraction of
   a degree) takes text off the browser's pixel grid and can noticeably
   soften glyph edges — this doesn't undo the tilt, but on most engines it
   makes the GPU rasterise the layer at a sharper resolution instead of
   the cheaper CPU path, which measurably helps. */
.section-dark > .container {
  transform: rotate(0.3deg) translateZ(0);
}

.section-rose > .container {
  transform: rotate(-0.35deg) translateZ(0);
}

.section-passport > .container {
  transform: rotate(-0.25deg) translateZ(0);
}

.section-dark > .container::before,
.section-rose > .container::before,
.section-passport > .container::before {
  content: "";
  position: absolute;
  left: 12px;
  top: 14px;
  bottom: 14px;
  border-left: 1.5px dashed var(--page-ink);
  opacity: 0.35;
  pointer-events: none;
}

.section-dark > .container::after,
.section-rose > .container::after,
.section-passport > .container::after {
  content: "· " attr(data-page) " ·";
  position: absolute;
  right: 1.2rem;
  bottom: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--page-ink);
  opacity: 0.55;
  pointer-events: none;
}

@media (min-width: 860px) {
  .section-dark > .container,
  .section-rose > .container,
  .section-passport > .container {
    max-width: 960px;
    padding: 3rem 2.5rem;
    box-shadow:
      inset 0 0 0 1px var(--page-ink),
      inset 0 0 0 5px var(--page-bg),
      inset 0 0 0 6px var(--page-ink),
      0 16px 40px rgba(0, 0, 0, 0.3);
  }

  .section-dark > .container::after,
  .section-rose > .container::after,
  .section-passport > .container::after {
    right: 1.5rem;
    bottom: 1.1rem;
  }
}

/* --------------------------------------------------------------------
   Alte Stempel — dekorative, verblasste Einreisestempel (echte Scans,
   nicht gezeichnet). Liegen als Wasserzeichen HINTER dem Karteninhalt
   (negativer z-index innerhalb des positionierten .container) statt in
   dessen Textfluss — dadurch dürfen sie frei mit Überschrift, Text oder
   der Abflugtafel überlappen, ohne je etwas zu verdecken, und können
   beliebig groß sein, ohne der Karte zusätzliche Höhe zu kosten.
   .section-dark/.section-rose/.section-passport > .container ist
   bereits position:relative (siehe Passseiten-Block oben), das reicht
   als Bezugsrahmen für die Absolutpositionierung hier.
   -------------------------------------------------------------------- */

.card-watermark {
  position: absolute;
  z-index: -1;
  width: 230px;
  opacity: 0.22;
  pointer-events: none;
}

.card-watermark img {
  display: block;
  width: 100%;
  height: auto;
}

.card-watermark--left {
  top: 0.5rem;
  left: 0.5rem;
  transform: rotate(-10deg);
}

.card-watermark--right {
  top: 0.5rem;
  right: 0.5rem;
  transform: rotate(8deg);
}

.card-watermark--bottom-right {
  bottom: 0.5rem;
  right: 0.5rem;
  transform: rotate(8deg);
}

@media (max-width: 640px) {
  .card-watermark {
    width: 160px;
  }
}

/* --------------------------------------------------------------------
   Vintage-Weltkarte — Wasserzeichen für die "Findet uns"-Karte, statt
   eines Einreisestempels (passt thematisch besser zum Standort-Bereich).
   Selbe Technik wie .card-watermark: negativer z-index innerhalb des
   positionierten .container, damit sie frei unter Text und Tafel liegen
   kann. Anders als der Stempel deckt sie die ganze Karte ab, daher
   eigener Wrapper mit inset:0 + overflow:hidden, damit das Bild nicht
   über die abgerundete Kartenkante hinausragt. mix-blend-mode:multiply
   lässt den beigen Kartenhintergrund durch die Karte "durchschimmern"
   statt sie wie eine separate Ebene draufzulegen.
   -------------------------------------------------------------------- */

.card-map-watermark {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}

.card-map-watermark img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 115%;
  height: 115%;
  min-width: 900px;
  object-fit: cover;
  transform: translate(-50%, -50%);
  opacity: 0.24;
  mix-blend-mode: multiply;
}

/* --------------------------------------------------------------------
   Stempel-Badge — ersetzt die schlichten Eyebrow-Texte auf den
   Passseiten-Abschnitten durch einen Einreisestempel-artigen Ring.
   -------------------------------------------------------------------- */

.passport-stamp {
  display: inline-flex;
  position: relative;
  padding: 0.5em 1.1em;
  margin-bottom: 1.1rem;
  border: 1.5px solid var(--page-ink, var(--accent-2));
  border-radius: 999px;
  color: var(--page-ink, var(--accent-2));
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  opacity: 0.85;
  transform: rotate(-3deg);
}

.passport-stamp::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed currentColor;
  border-radius: inherit;
  opacity: 0.55;
  pointer-events: none;
}

.passport-stamp--right {
  transform: rotate(2.5deg);
}

/* WhatsApp-Link im dunklen Footer als Stempel-Button — .passport-stamp
   fällt hier auf --accent-2 zurück (dunkles Grün, auf --chrome-bg praktisch
   unsichtbar), da --page-ink im Footer nicht gesetzt ist. Feste
   Chrome-Akzentfarben statt der ererbten machen den Button lesbar. */
.footer-stamp {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin-top: 0.6rem;
  border-color: var(--chrome-accent);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.footer-stamp-icon {
  width: 1.1em;
  height: 1.1em;
  fill: currentColor;
  flex: none;
}

/* .footer-col a's own color rule outranks a single .footer-stamp class on
   specificity — matched here (and on :hover below) to win without
   !important. Without the :hover version, the hover background and text
   ended up the same accent tan — unreadable. */
.footer-col a.footer-stamp {
  color: var(--chrome-accent);
}

.footer-col a.footer-stamp:hover {
  opacity: 1;
  background-color: var(--chrome-accent);
  color: var(--chrome-bg);
  transform: rotate(0deg);
}

/* --------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------- */

.hero {
  color: var(--chrome-ink);
  padding-block: 5rem;
  text-align: center;
}

.hero-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.75rem;
  opacity: 0;
  transform: translateY(-12px);
  animation: hero-logo-in 0.9s ease 0.15s forwards;
}

.hero-logo-mark,
.hero-logo-word {
  height: 230px;
  width: auto;
  /* The logo is drawn in the same rosé-beige as the woven pattern lines
     behind it (--chrome-accent) — near-identical hue on the dark navy
     ground, so it visually merges into the lattice. A dark shadow adds
     contrast independent of hue: a tight one traces the actual silhouette
     against busy pattern crossings, a soft wider one lifts it off the
     background overall. */
  filter: drop-shadow(0 0 3px rgba(10, 26, 51, 0.85)) drop-shadow(0 4px 14px rgba(10, 26, 51, 0.55));
}

.hero-logo-word {
  height: 114px;
}

@media (max-width: 560px) {
  .hero-logo {
    width: 100%;
  }
  .hero-logo-mark,
  .hero-logo-word {
    width: 100%;
    height: auto;
  }
}

@keyframes hero-logo-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.hero-eyebrow {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--chrome-ink-soft);
  margin-bottom: 1rem;
}

.hero h1 {
  color: var(--chrome-ink);
  font-size: clamp(2.6rem, 7vw, 4.5rem);
  margin-bottom: 0.4em;
}

.hero p {
  color: var(--chrome-ink-soft);
  max-width: 46ch;
  margin-inline: auto;
  font-size: 1.1rem;
}

/* --------------------------------------------------------------------
   Neon-Schriftzug — reiner Sektionswechsel zwischen Events und
   Impressionen, ohne eigene Passseiten-Karte. Sitzt direkt auf dem
   dunklen Bogenmuster von .pattern-arches (transparenter SVG-Hintergrund),
   wie
   ein Leuchtschild an der Wand.
   -------------------------------------------------------------------- */

.neon-divider {
  padding-block: 1.5rem;
  text-align: center;
}

.neon-sign {
  width: 100%;
  max-width: 360px;
  height: auto;
  margin-inline: auto;
  /* Original-Datei glüht rot/orange (feste Hex-Werte im SVG, kein
     currentColor) — per hue-rotate auf Pink gedreht statt die Datei
     anzufassen, dadurch bleibt der mehrschichtige Glow-Effekt erhalten. */
  filter: hue-rotate(320deg);
}

@media (max-width: 640px) {
  .neon-sign {
    max-width: 260px;
  }
}

/* Alle Buttons im selben Stempel-Stil wie Nav-Links und Reservieren-
   Button: dashed Innenring, der beim Hover erscheint, plus leichte
   Drehung wie beim Abstempeln. currentColor im ::before übernimmt
   automatisch die jeweilige Kontextfarbe (Chrome/on-light/on-rose). */
.btn {
  display: inline-flex;
  align-items: center;
  position: relative;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.85rem 1.7rem;
  border-radius: 999px;
  border: 1.5px solid var(--chrome-accent);
  color: var(--chrome-ink);
  margin-top: 1.5rem;
  transition: transform 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

.btn::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed currentColor;
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
}

.btn:hover {
  background: var(--chrome-accent);
  color: var(--tt-navy);
  transform: rotate(-2deg);
}

.btn:hover::before {
  opacity: 0.55;
}

.btn.on-light {
  border-color: var(--accent-2);
  color: var(--accent-2);
}

.btn.on-light:hover {
  background: var(--accent-2);
  color: var(--paper-raised);
}

/* Für den dunkleren Rose-Ton (.section-rose): weder das helle Chrome-Weiß
   noch das dunkelgrüne on-light bieten dort genug Kontrast. */
.btn.on-rose {
  border-color: var(--rose-ink);
  color: var(--rose-ink);
}

.btn.on-rose:hover {
  background: var(--rose-ink);
  color: var(--tt-rose-beige);
}

/* --------------------------------------------------------------------
   Events — Abflugtafel (Retro-Split-Flap-Display)
   Dieselbe dunkle Chrome-Palette wie Header/Footer, damit die Tafel wie
   ein physisches Gerät wirkt statt wie eine weitere helle Content-Karte.
   Gold steht für normale "Flap"-Zeichen (wie beleuchtete Lettern), die
   übrigen Statusfarben (Grün/Amber/Rot/Blau) markieren den Live-Status.
   -------------------------------------------------------------------- */

.departure-board {
  --board-cols: 7.56rem 6.3rem 1fr 8.6rem;
  --board-amber: #e0a94e;
  display: flex;
  flex-direction: column;
  background: var(--chrome-bg);
  border: 1px solid var(--chrome-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-chrome);
  overflow: hidden;
  font-family: var(--font-mono);
  /* Die Events-Karte zentriert ihren Container für Überschrift und
     Button — die Tafel selbst soll wie ein echtes Abflugbrett aber
     linksbündig bleiben, sonst rutschen Veranstaltungsnamen etc. mit
     in die Zentrierung. */
  text-align: left;
}

.departure-cell.departure-weekday { grid-area: weekday; }
.departure-cell.departure-date { grid-area: date; }
.departure-cell.departure-time { grid-area: time; }
.departure-cell.departure-event { grid-area: event; }
.departure-cell.departure-status { grid-area: status; }

/* Kopfschild wie an echten Anzeigetafeln — Flugzeug-Glyphe + gesperrter
   "DEPARTURES"-Schriftzug über einer Goldlinie. */
.departure-board-sign {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.7rem 1.1rem;
  background: rgba(0, 0, 0, 0.25);
  border-bottom: 2px solid var(--tt-gold);
}

.departure-board-sign-icon {
  display: inline-block;
  transform: rotate(-45deg);
  font-size: 1.05rem;
  color: var(--tt-gold);
}

.departure-board-sign-text {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--chrome-ink);
}

.departure-board-sign-text--sub {
  margin-left: auto;
  font-weight: 400;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  color: var(--chrome-ink-soft);
}

.departure-board-row {
  display: grid;
  grid-template-columns: var(--board-cols);
  grid-template-rows: auto auto;
  grid-template-areas:
    "weekday weekday event  status"
    "date    time    event  status";
  align-items: center;
  gap: 0.3rem 0.9rem;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--chrome-line);
  text-decoration: none;
  color: var(--chrome-ink);
}

.departure-board-row:last-child {
  border-bottom: none;
}

.departure-board-head {
  padding-block: 0.6rem;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--chrome-ink-soft);
  background: rgba(0, 0, 0, 0.15);
}

/* The flap-char glyph beneath sits centered inside its tile (border +
   padding + centering slack), so it starts a few px right of the tile's
   own edge — nudge the plain-text header labels by that same amount so
   "ESTIMATED"/"DATUM" visually start above the actual digits, not the tile. */
.departure-board-head .departure-date,
.departure-board-head .departure-time {
  padding-left: 0.29rem;
}

.departure-row {
  transition: background 0.15s ease;
  animation: departure-flap-in 0.5s ease backwards;
  animation-delay: calc(var(--departure-index, 0) * 0.08s);
}

a.departure-row:hover,
a.departure-row:focus-visible {
  background: rgba(169, 143, 74, 0.12);
}

.departure-row--static {
  cursor: default;
}

.departure-cell {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* sr-only: Klartext für Screenreader, während die zerlegten Flap-Zeichen
   daneben aria-hidden bleiben — sonst würde jedes Zeichen einzeln
   vorgelesen ("null neun punkt null drei punkt ..."). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Eine Zeile aus Split-Flap-Zeichen (Wochentag, Datum, Zeit) — jede
   Ziffer/jeder Buchstabe eine eigene Klappe, wie im Original. */
/* Grid statt Flex: die Kacheln teilen sich die volle Zeilenbreite zu
   gleichen Teilen (1fr je Kachel), egal ob 5 (Zeit) oder 12 (Wochentag)
   Zeichen — dadurch endet die letzte Kachel IMMER exakt am rechten Rand
   der Zelle, statt bei kurzem Text Leerraum übrig zu lassen. Das macht
   die Breitenangleichung robust gegenüber Schriftart/Rendering, statt
   sich auf von Hand abgestimmte rem-Werte zu verlassen. */
.flap-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.12rem;
}

.flap-char {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.12rem;
  height: 1.62rem;
  padding: 0 0.12rem;
  background: var(--chrome-bg-raised);
  border: 1px solid rgba(241, 233, 225, 0.14);
  border-radius: 2px;
  color: var(--board-amber); /* dasselbe Gelb wie der "Boarding"-Status */
  font-weight: 700;
  font-size: 1.14rem;
  /* Without this the glyph inherits body's line-height (1.65) — a line box
     taller than the tile itself, which flex-centers slightly off (glyph
     reads a touch too high). A tight line-height lets it centre on its
     actual ink instead. */
  line-height: 1;
}

.flap-char::after {
  content: "";
  position: absolute;
  left: 1px;
  right: 1px;
  top: 50%;
  height: 1px;
  background: rgba(0, 0, 0, 0.4);
}

/* Wochentag-Klappen — dunkler Untergrund wie der Rest der Tafel, nur die
   Schrift ist weiß. Leere Slots (kürzerer Wochentagsname) bleiben als
   blasse, unbeschriftete Klappe stehen, damit die Zeile immer so breit
   wirkt wie Datum + Zeit zusammen. */
.flap-char--weekday {
  color: var(--tt-white);
  font-size: 0.9rem;
}

/* Leere Slots dürfen nicht per opacity abgedunkelt werden: die Kachel ist
   heller als der Tafel-Hintergrund, also würde reduzierte Deckkraft sie
   zum dunkleren Untergrund hin abblenden — optisch das Gegenteil von
   "gedimmt". Stattdessen direkt ein blasseres Füllung/Rand definieren. */
.flap-char:empty {
  background: rgba(241, 233, 225, 0.04);
  border-color: rgba(241, 233, 225, 0.08);
}

.departure-event {
  overflow: hidden;
}

.departure-event-title {
  font-size: 1rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--chrome-ink);
}

.departure-recurring-badge {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 0.2rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--tt-gold);
}

.departure-recurring-icon {
  display: inline-block;
  font-size: 0.95em;
}

.departure-subtitle,
.departure-note {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.78rem;
  color: var(--chrome-ink-soft);
  text-transform: none;
  letter-spacing: normal;
}

.departure-note {
  font-style: italic;
  color: var(--tt-rose-beige);
}

/* Status bleibt EIN Textblock (kein Zeichen-Flap wie Datum/Zeit) — aber mit
   fester Breite, damit "ON TIME" und "PLANMÄSSIG" gleich viel Platz
   einnehmen. Das Durchwechseln passiert wortweise per JS (spinWord in
   departure-board.js), nicht buchstabenweise. */
.status-flap {
  position: relative;
  display: inline-block;
  flex: none;
  width: 7rem;
  padding: 0.2rem 0.4rem;
  background: var(--chrome-bg-raised);
  border: 1px solid rgba(241, 233, 225, 0.12);
  border-radius: 3px;
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  color: var(--board-amber);
}

.status-flap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: rgba(0, 0, 0, 0.35);
}

.status-flap--on_time { color: #9fbf86; }
.status-flap--boarding { color: #e0a94e; text-shadow: 0 0 8px rgba(224, 169, 78, 0.45); }
.status-flap--final_call { color: #e2685c; text-shadow: 0 0 8px rgba(226, 104, 92, 0.45); }
.status-flap--canceled { color: #d9827a; }
.status-flap--rescheduled { color: #b39ddb; }
.status-flap--holiday { color: #8aa0c4; }
.status-flap--closed { color: #94a3b8; }

.departure-row.is-cancelled {
  color: var(--chrome-ink-soft);
}

/* Die zwei "Kontrolllämpchen" jeder Zeile — übereinander links vom Status,
   blinken nur am Veranstaltungstag. */
.departure-cell.departure-status {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
}

.departure-lights {
  display: inline-flex;
  flex-direction: column;
  gap: 0.25rem;
  flex: none;
}

.light {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(241, 233, 225, 0.15);
}

.departure-lights.is-blinking .light--amber {
  background: #9fbf86;
  animation: departure-blink 1.1s steps(1, end) infinite;
}

.departure-lights.is-blinking .light--green {
  background: #9fbf86;
  animation: departure-blink 1.1s steps(1, end) infinite;
  animation-delay: 0.55s;
}

/* Cancelled/closed and rescheduled entries flag themselves regardless of
   whether the date is today — worth catching the eye on the board whenever
   it's seen, not just on the day itself. Same two lights, recoloured, same
   staggered rhythm as the green/amber "today" pair. */
.departure-lights.is-blinking-red .light {
  background: #e2685c;
  animation: departure-blink 1.1s steps(1, end) infinite;
}

.departure-lights.is-blinking-orange .light {
  background: #e0a94e;
  animation: departure-blink 1.1s steps(1, end) infinite;
}

.departure-lights.is-blinking-red .light--green,
.departure-lights.is-blinking-orange .light--green {
  animation-delay: 0.55s;
}

@keyframes departure-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0.15; }
}

@keyframes departure-flap-in {
  from {
    opacity: 0;
    transform: scaleY(0.4);
    transform-origin: top;
  }
  to {
    opacity: 1;
    transform: scaleY(1);
  }
}

@media (max-width: 640px) {
  .departure-board-sign-text--sub {
    display: none;
  }

  .departure-board-head {
    display: none;
  }

  .departure-board-row {
    grid-template-columns: auto auto;
    /* Status now shares the top row with the weekday instead of getting
       its own full-width row below the event — there's enough spare
       width next to the (short) weekday flap display for it, and it
       keeps the card noticeably shorter. Right-aligned to line up with
       the time underneath it (see align-items below). Desktop is
       untouched — this whole block only applies under 640px. */
    grid-template-areas:
      "weekday status"
      "date time"
      "event event";
    row-gap: 0.5rem;
  }

  /* Ohne eigene align-items-Regel würde diese Zeile (als einzige) noch
     die alte flex-Stretch-Vorgabe von .departure-cell erben und dadurch
     über die volle Kartenbreite gezogen, statt wie Datum/Uhrzeit bei der
     festen Klappkarten-Breite zu bleiben. */
  .departure-cell.departure-weekday { align-items: flex-start; }
  .departure-cell.departure-date { align-items: flex-start; }
  .departure-cell.departure-time { align-items: flex-end; }
  /* .departure-status is row-flex, not column-flex like the other cells
     (see the unconditional rule above) — align-items there controls
     *vertical* centering of the lights against the status flap, so
     setting it here to line up with time below would have fought that
     and pushed the lights to the row's bottom instead. justify-content
     is the row-axis equivalent: pushes the (shrink-to-fit) lights+flap
     group to the right of the grid cell without touching align-items,
     so the lights stay vertically centered on the flap. */
  .departure-cell.departure-status { justify-content: flex-end; }

  /* The weekday flap-row always renders 12 slots (padded with blanks so
     every weekday name lines up on desktop), which alone claims most of
     a phone-width row — combined with the fixed 7rem desktop status pill
     that left no room for the column gap, so the pill either touched the
     weekday tiles or bled past the card edge. Dropping the unused blank
     slots and shrinking the pill (not the row height, which is set by
     the weekday/date/time stack, not by this cell) restores breathing
     room between them. */
  .departure-weekday .flap-char:empty {
    display: none;
  }

  .departure-board-row {
    column-gap: 0.6rem;
  }

  .departure-cell.departure-status .departure-lights { gap: 0.18rem; }
  .status-flap {
    width: 5rem;
    padding: 0.15rem 0.25rem;
    font-size: 0.6rem;
  }
}

/* --------------------------------------------------------------------
   Startseite — Highlights & Location-Teaser
   -------------------------------------------------------------------- */

.highlight-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
}

@media (max-width: 760px) {
  .highlight-grid {
    grid-template-columns: 1fr;
  }
}

.highlight-card {
  display: flex;
  flex-direction: column;
  position: relative;
  /* Aged, slightly stained paper instead of flat white — these three
     cards sit on the dark section and used to glow starkly against it.
     Stains are much fainter than the photo-frame ones (--page-grain
     alone was the old texture) since real body text sits on top and
     still needs to stay readable. */
  background-color: #e6d9b8;
  background-image:
    radial-gradient(circle at 14% 18%, rgba(90, 62, 25, 0.12), transparent 30%),
    radial-gradient(circle at 88% 78%, rgba(90, 62, 25, 0.11), transparent 32%),
    radial-gradient(circle at 55% 8%, rgba(90, 62, 25, 0.07), transparent 20%),
    var(--page-grain);
  background-repeat: no-repeat, no-repeat, no-repeat, repeat;
  background-size: 100% 100%, 100% 100%, 100% 100%, 200px 200px;
  background-blend-mode: multiply, multiply, multiply, overlay;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* box-shadow ignores clip-path (it shadows the full, un-clipped box) —
     filter:drop-shadow follows the actual clipped silhouette instead,
     same fix used for the earlier folded-corner version of this card. */
  filter: drop-shadow(0 1px 2px rgba(31, 40, 55, 0.08)) drop-shadow(0 8px 24px rgba(31, 40, 55, 0.08));
  text-decoration: none;
  color: var(--ink);
  /* Jede Karte liegt leicht schief da, wie ein einzeln abgerissener
     Bordkarten-Stub, der auf den Tisch geworfen wurde — Winkel kommt
     per --tilt aus dem Markup, selbes Prinzip wie --rotate bei den
     Foto-Rahmen. */
  transform: rotate(var(--tilt, 0deg)) translateZ(0);
  transition: transform 0.15s ease, filter 0.15s ease;
}

/* Abrisskante — nur links, per clip-path direkt auf der Karte selbst statt
   auf einem separaten Streifen-Element daneben. Ein zweites Element mit
   eigenem background konnte den Papierton der Karte nie exakt treffen
   (Radialverläufe skalieren pro Box unterschiedlich) — das erzeugte immer
   eine sichtbare Kante an der Nahtstelle. Jetzt ist es dieselbe
   durchgehend gemalte Fläche, nur nachträglich beschnitten — eine
   Farbabweichung ist so gar nicht mehr möglich. Rechts bleibt
   unbeschnitten, die runde Kartenkante von border-radius (oben/unten grob
   mit ein paar Punkten nachgebildet, da clip-path sie sonst überschreiben
   würde). Amplitude klein (unter 2.5%) und mit mehr Zacken als beim
   ersten Versuch, damit sie feiner wirken statt grob — und jede Karte
   bekommt ihr eigenes Muster (andere Phase/Abstände), statt dass alle
   drei identisch gezackt sind. */
.highlight-card--torn-a {
  clip-path: polygon(
    2% 0%,
    0.4% 3%, 2% 6%, 0.3% 10%, 1.8% 13%, 0.5% 17%, 2.2% 20%, 0.3% 24%,
    1.7% 27%, 0.5% 31%, 2% 35%, 0.4% 38%, 1.9% 42%, 0.3% 46%, 2.1% 49%,
    0.5% 53%, 1.8% 57%, 0.4% 60%, 2% 64%, 0.3% 68%, 1.9% 71%, 0.5% 75%,
    2.1% 79%, 0.4% 82%, 1.7% 86%, 0.3% 90%, 2% 93%, 0.5% 97%,
    2% 100%,
    97% 100%, 99.3% 99.3%, 100% 97%,
    100% 3%, 99.3% 0.7%, 97% 0%
  );
}

.highlight-card--torn-b {
  clip-path: polygon(
    1.8% 0%,
    0.3% 4%, 2.1% 7%, 0.5% 11%, 1.6% 14%, 0.3% 18%, 2% 21%, 0.4% 25%,
    1.9% 29%, 0.3% 32%, 2.2% 36%, 0.5% 39%, 1.7% 43%, 0.3% 47%, 2% 50%,
    0.4% 54%, 1.8% 58%, 0.5% 61%, 2.1% 65%, 0.3% 69%, 1.6% 72%, 0.4% 76%,
    2% 79%, 0.3% 83%, 1.9% 87%, 0.5% 90%, 2.2% 94%, 0.3% 97%,
    1.8% 100%,
    97% 100%, 99.3% 99.3%, 100% 97%,
    100% 3%, 99.3% 0.7%, 97% 0%
  );
}

.highlight-card--torn-c {
  clip-path: polygon(
    2.2% 0%,
    0.5% 3%, 1.7% 6%, 0.3% 9%, 2% 13%, 0.4% 16%, 1.9% 20%, 0.3% 23%,
    2.1% 27%, 0.5% 30%, 1.6% 34%, 0.3% 37%, 2% 41%, 0.4% 44%, 1.8% 48%,
    0.3% 52%, 2.2% 55%, 0.5% 59%, 1.7% 62%, 0.4% 66%, 2% 69%, 0.3% 73%,
    1.9% 77%, 0.5% 80%, 2.1% 84%, 0.3% 87%, 1.6% 91%, 0.4% 94%, 2% 98%,
    2.2% 100%,
    97% 100%, 99.3% 99.3%, 100% 97%,
    100% 3%, 99.3% 0.7%, 97% 0%
  );
}

.highlight-card:hover {
  transform: translateY(-2px) rotate(var(--tilt, 0deg)) translateZ(0);
  filter: drop-shadow(0 4px 14px rgba(31, 40, 55, 0.12));
}

/* Ausgeblichener Deko-Text am rechten Rand, um 90° gedreht — reiner
   Ticket-Flair, hat inhaltlich nichts mit der Karte zu tun. */
.highlight-card-code {
  position: absolute;
  top: 50%;
  right: 10px;
  /* Native vertical text instead of transform:rotate(90deg): rotating a
     translateY(-50%)-centred box composes the two functions into one
     matrix, so the translate ends up acting along the *rotated* axis —
     in practice that meant the text centred itself ~67px above the
     card's actual middle instead of on it. writing-mode sidesteps the
     whole problem: the box's own height already matches the (rotated)
     text, so a single translateY(-50%) centres it correctly. */
  transform: translateY(-50%);
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  color: var(--ink);
  opacity: 0.3;
  white-space: nowrap;
  pointer-events: none;
}

/* Nur die Airport-Codes selbst sind fett und eine Stufe größer — "FROM"/
   "TO" bleiben in der normalen Stärke/Größe von .highlight-card-code. */
.highlight-card-code-airport {
  font-weight: 700;
  font-size: 1.15em;
}

.highlight-card-header {
  flex: none;
  padding: 0.75rem 1.75rem;
  background: var(--tt-navy);
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}

.highlight-card-header h3 {
  margin: 0;
  font-size: 1.3rem;
  color: var(--chrome-ink);
}

.highlight-card-body {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 1.5rem 1.75rem 1rem;
}

.highlight-card-body p {
  /* --ink-soft was tuned for the old flat-white card — on the aged paper
     beige its contrast drops noticeably (same issue as the reservation
     panel notes). --ink matches what the "Findet uns" passport page uses
     on the same beige tone. */
  color: var(--ink);
  margin: 0 0 1rem;
}

/* Job listings (jobs page) — a "crew noticeboard" instead of the site's
   usual passport-page card grid: each opening is its own pinned notice,
   stacked full-width so they read as clearly separate postings rather
   than competing side by side. Deliberately its own thing (distinct from
   home/private-events' rose-beige highlight cards) while still built
   entirely from established tokens (--tt-rose-beige, --tt-gold,
   --font-display, the checkmark list already used elsewhere here) — no
   clip-path, no torn edges, just a rotated rounded card + a drawing-pin
   dot, learned safe after the event-ticket redesign history. */
.job-notices {
  display: flex;
  flex-direction: column;
  gap: 3.5rem;
  max-width: 820px;
  margin: 2.5rem auto 0;
}

.job-notice {
  position: relative;
  background: var(--tt-rose-beige);
  border-radius: 6px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.4);
  padding: 2.6rem 2rem 2.2rem;
  text-align: left;
  transform: rotate(var(--tilt, 0deg));
}

.job-notice-pin {
  position: absolute;
  top: -10px;
  left: 50%;
  width: 18px;
  height: 18px;
  margin-left: -9px;
  border-radius: 50%;
  background: var(--tt-gold);
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.45), inset 0 -3px 4px rgba(0, 0, 0, 0.3);
}

.job-notice-header {
  text-align: center;
  margin-bottom: 1.7rem;
}

.job-notice-title {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  color: var(--rose-ink);
  margin: 0 0 0.8rem;
}

.job-notice-badges {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.job-notice-columns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.2rem;
  padding-top: 1.7rem;
  border-top: 1px dashed var(--tt-gold);
}

@media (max-width: 760px) {
  .job-notice-columns {
    grid-template-columns: 1fr;
    gap: 1.6rem;
  }
}

.job-card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.2rem;
}

.job-card-badge {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-2);
  border: 1px solid var(--accent-2);
  border-radius: 999px;
  padding: 0.25em 0.7em;
}

.job-card-badge--muted {
  color: var(--ink-soft);
  border-color: var(--line);
}

.job-card-section-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 1.3rem 0 0.6rem;
}

.job-card-section-label:first-of-type {
  margin-top: 0;
}

.job-card-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.55rem;
}

.job-card-list li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--ink);
  font-size: 0.92rem;
  line-height: 1.5;
}

.job-card-list li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--tt-gold);
  font-weight: 700;
}

.highlight-card-stamps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}

.highlight-card-partner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.15rem;
}

/* .highlight-card-body p's own margin rule outranks a single
   .highlight-card-partner-label class on specificity, so its 1rem
   bottom margin was winning here — matched on two classes to override
   it without !important. */
.highlight-card-body .highlight-card-partner-label {
  margin: 0;
  font-size: 0.82rem;
  /* Default body line-height (1.65) leaves visible leading below the
     text that gap alone doesn't close — same issue as elsewhere on this
     page (see the .highlight-card-partner note history). */
  line-height: 1.2;
  color: var(--ink);
}

.highlight-card-partner-logo {
  height: 46px;
  width: auto;
  transition: opacity 0.15s ease;
}

.highlight-card-partner a:hover .highlight-card-partner-logo {
  opacity: 0.75;
}

.highlight-card-body .more-link {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-2);
}

/* Deko-Flugdaten unter dem eigentlichen Inhalt, nur fürs Ticket-Flair —
   siehe $ticketDetails in home.blade.php. margin-top:auto braucht den
   Body als Flex-Column (siehe .highlight-card-body), damit die Zeile bei
   allen drei Karten unten sitzt statt direkt unter unterschiedlich
   langem Inhalt zu "schweben". */
.highlight-card-flightinfo {
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 0.15rem 1.2rem;
  margin-top: auto;
  padding-top: 0.5rem;
  border-top: 1px dashed rgba(31, 40, 55, 0.28);
}

.highlight-card-flightinfo div {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.highlight-card-flightinfo span:first-child {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.highlight-card-flightinfo span:last-child {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.78rem;
  line-height: 1.2;
  color: var(--ink);
}

/* Same stamp badge as the section eyebrows, but clickable here — a
   "stamped ink fill" on hover instead of the plain opacity/rotate the
   decorative (non-link) stamps use, so it reads as interactive. Sized up
   and fully opaque, unlike the small decorative eyebrows, since these are
   real navigation buttons and need to read clearly at a glance. */
.stamp-link {
  padding: 0.75em 1.6em;
  font-size: 0.95rem;
  opacity: 1;
  text-decoration: none;
  cursor: pointer;
  /* Fixed colours instead of the inherited --page-ink/--page-bg: those
     resolve to the *dark section's* light-on-dark palette (--chrome-accent,
     meant for text sitting directly on navy) — but this card is its own
     light beige surface floating on that dark section, so light text on it
     read as barely-there until hovered. Always readable at rest now. */
  color: var(--accent-2);
  border-color: var(--accent-2);
}

.stamp-link:hover {
  opacity: 1;
  background: var(--accent-2);
  color: var(--paper-raised);
}

/* --------------------------------------------------------------------
   Feature-Badges — kurze Fakten (Hunde, Kartenzahlung, kein TV) unter
   den drei Highlight-Karten, dezent im Stil der find-us-Badges auf der
   Standort-Karte.
   -------------------------------------------------------------------- */

.feature-badges {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.75rem 2.5rem;
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px dashed var(--page-ink);
}

.feature-badge {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.85rem;
  color: var(--chrome-ink-soft);
}

.feature-badge-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1.5px solid var(--page-ink);
  color: var(--page-ink);
}

.feature-badge-icon svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
}

/* --------------------------------------------------------------------
   Foto-Galerie — wie lose Abzüge in ein Reisetagebuch geklebt: leicht
   vergilbter Weißrand (dickerer Streifen unten, klassische Sofortbild-
   Optik), zufällig wechselnde Schräglage, dezenter Sepia-Filter fürs
   "alte Reisefotografie"-Gefühl statt die eigentlich schon stimmungsvollen
   Fotos zu verfälschen.
   -------------------------------------------------------------------- */

.photo-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1.75rem 1.5rem;
  margin-top: 2rem;
}

/* Aged tobacco-tan instead of stark white — a fresh-off-the-printer white
   border reads as a modern photo print, not the vintage Polaroid look this
   is going for. Blotchy radial-gradient "stains" (like foxing/water marks
   on real old photo paper) plus an inset vignette on top of the grain, for
   a much more visibly aged, worn border than a flat tint alone gives. */
.photo-gallery-item {
  background-color: #d4bd88;
  background-image:
    radial-gradient(circle at 10% 15%, rgba(90, 62, 25, 0.45), transparent 22%),
    radial-gradient(circle at 88% 80%, rgba(90, 62, 25, 0.4), transparent 28%),
    radial-gradient(circle at 62% 8%, rgba(90, 62, 25, 0.3), transparent 18%),
    radial-gradient(circle at 22% 88%, rgba(90, 62, 25, 0.35), transparent 20%),
    radial-gradient(circle at 92% 22%, rgba(90, 62, 25, 0.28), transparent 16%),
    radial-gradient(circle at 45% 50%, rgba(90, 62, 25, 0.15), transparent 42%),
    var(--page-grain);
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat;
  background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 180px 180px;
  background-blend-mode: multiply, multiply, multiply, multiply, multiply, multiply, multiply;
  box-shadow: inset 0 0 34px rgba(70, 45, 15, 0.55), inset 0 0 10px rgba(60, 40, 10, 0.35), 0 10px 22px rgba(0, 0, 0, 0.4);
  padding: 0.5rem 0.5rem 1.5rem;
  transform: rotate(var(--rotate, 0deg));
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.photo-gallery-item:hover {
  transform: rotate(0deg) scale(1.04);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
  position: relative;
  z-index: 2;
}

.photo-gallery-item img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  filter: sepia(0.2) saturate(0.88) contrast(1.05);
  cursor: zoom-in;
}

/* Auf Mobilgeräten sprengt eine einspaltige Grid-Ansicht mit 10 Fotos die
   Seite (jedes gestapelt in voller Breite = sehr viel Scrollstrecke nur
   für die Galerie). Ein horizontales Swipe-Karussell per scroll-snap
   statt Grid — braucht kein JS (also auch kein neues Ruckel-Risiko wie
   beim Hintergrundmuster), zeigt bewusst ein Stück des nächsten Fotos am
   Rand an, damit "hier geht's weiter" auf den ersten Blick klar ist.
   Bleibt innerhalb des Passseiten-Innenabstands statt randlos zu laufen,
   sonst würde das Karussell durch die Heftungslinie/Seitenzahl der
   Passseiten-Optik hindurchscrollen. */
@media (max-width: 640px) {
  .photo-gallery {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 1.1rem;
    margin-top: 1.5rem;
    padding-bottom: 0.5rem;
    scrollbar-width: none;
  }

  .photo-gallery::-webkit-scrollbar {
    display: none;
  }

  .photo-gallery-item {
    flex: 0 0 76%;
    scroll-snap-align: start;
  }

  /* :hover kann auf Touch nach dem Antippen "hängen bleiben" — auf
     Mobilgeräten bewusst kein Hover-Zoom, nur der normale Schrägstand. */
  .photo-gallery-item:hover {
    transform: rotate(var(--rotate, 0deg));
    box-shadow: inset 0 0 34px rgba(70, 45, 15, 0.55), inset 0 0 10px rgba(60, 40, 10, 0.35), 0 10px 22px rgba(0, 0, 0, 0.4);
  }
}

/* --------------------------------------------------------------------
   Lightbox — Klick auf ein Galerie-Foto öffnet es großformatig, mit
   Pfeiltasten-Navigation und ESC/Klick-außerhalb zum Schließen. Bewusst
   dunkel und randlos (statt der Passseiten-Optik) — hier soll allein das
   Foto wirken, in echten Farben ohne den Sepia-Filter der Kachelansicht.
   -------------------------------------------------------------------- */

.lightbox-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 26, 51, 0.94);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
  z-index: 90;
}

.lightbox-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 91;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s ease, visibility 0.2s;
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.lightbox-image {
  max-width: min(90vw, 1100px);
  max-height: 85vh;
  width: auto;
  height: auto;
  border: 5px solid var(--tt-white);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(241, 233, 225, 0.4);
  background: rgba(10, 26, 51, 0.6);
  color: var(--chrome-ink);
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.lightbox-close:hover,
.lightbox-nav:hover {
  border-color: var(--chrome-ink);
}

.lightbox-close {
  top: 1rem;
  right: 1rem;
  width: 44px;
  height: 44px;
  font-size: 1.6rem;
}

.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  font-size: 1.3rem;
}

.lightbox-nav--prev {
  left: 1rem;
}

.lightbox-nav--next {
  right: 1rem;
}

body.lightbox-open {
  overflow: hidden;
}

@media (max-width: 640px) {
  .lightbox-image {
    max-width: 94vw;
    max-height: 78vh;
    border-width: 3px;
  }

  .lightbox-nav {
    width: 40px;
    height: 40px;
  }
}

/* --------------------------------------------------------------------
   "Findet uns…" — kompakte Zeilenliste statt einzelner Blöcke: Adresse
   und die Social-/Bewertungsplattformen als gleichförmige Zeilen mit
   Rundbadge-Icon, im selben Stempel-Look wie .passport-stamp. Einträge
   ohne echten Link (noch keine URL vorhanden) bekommen dieselbe Zeile,
   nur nicht klickbar und leicht abgeblendet.
   -------------------------------------------------------------------- */

.find-us-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.5rem;
  max-width: 720px;
  margin: 2rem auto 0;
  text-align: left;
}

/* Desktop: the hours column is naturally shorter than the icon-row list
   next to it (grid stretches both to match, so there's spare room at the
   bottom of the hours column) — tuck the stamp in there instead of adding
   height to the section. Mobile: grid.find-us-grid.css collapses to one
   column, list on top — sits beside it as a corner accent instead. */
.find-us-stamp {
  position: absolute;
  z-index: -1;
  width: 170px;
  opacity: 0.22;
  pointer-events: none;
  bottom: 0.25rem;
  right: 0.5rem;
  transform: rotate(8deg);
}

.find-us-stamp img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 640px) {
  .find-us-stamp {
    width: 170px;
    top: 0;
    right: 0;
    bottom: auto;
  }
}

@media (max-width: 640px) {
  .find-us-grid {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
}

.find-us-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.find-us-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.7rem 0.2rem;
  border-bottom: 1px dashed var(--line);
  text-decoration: none;
  color: var(--ink);
}

.find-us-list li:last-child .find-us-row {
  border-bottom: none;
}

a.find-us-row {
  transition: transform 0.15s ease;
}

a.find-us-row:hover {
  transform: translateX(3px);
}


.find-us-badge {
  flex: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.5px solid var(--page-ink, var(--accent-2));
  color: var(--page-ink, var(--accent-2));
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

/* Gestrichelter Innenring wie bei .passport-stamp — bleibt bis zum Hover
   unsichtbar, damit die Badges in Ruhe schlicht bleiben. */
.find-us-badge::before {
  content: "";
  position: absolute;
  inset: 3px;
  border: 1px dashed currentColor;
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.find-us-badge svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
}

/* Beim Hover "eingefärbt" wie ein frisch gestempelter Abdruck: Kreis
   füllt sich mit der Tintenfarbe, Icon kehrt sich dadurch automatisch
   um (currentColor), Innenring blendet ein, leichte Drehung je nach
   Zeile für die handgestempelte Optik. */
a.find-us-row:hover .find-us-badge {
  background: var(--page-ink, var(--accent-2));
  color: var(--page-bg, var(--paper));
}

a.find-us-row:hover .find-us-badge::before {
  opacity: 0.6;
}

.find-us-list li:nth-child(odd) a.find-us-row:hover .find-us-badge {
  transform: rotate(-8deg) scale(1.08);
}

.find-us-list li:nth-child(even) a.find-us-row:hover .find-us-badge {
  transform: rotate(7deg) scale(1.08);
}

.find-us-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.find-us-label {
  font-weight: 600;
}

.find-us-detail {
  font-size: 0.85rem;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --------------------------------------------------------------------
   Private Feiern — Ablauf-Schritte
   -------------------------------------------------------------------- */

.process-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}

@media (max-width: 760px) {
  .process-steps {
    grid-template-columns: 1fr;
  }
}

.process-step {
  text-align: center;
}

.process-step-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  border: 1px solid var(--accent);
  color: var(--accent-2);
  font-family: var(--font-display);
  font-size: 1.15rem;
  margin-bottom: 0.8rem;
}

.process-step h3 {
  margin-bottom: 0.4rem;
}

.process-step p {
  /* --ink-soft is tuned for the light --paper background — this
     component only ever sits on --section-rose (see private-events
     page), where that cool gray reads as barely-there against the warm
     rose ground. --rose-ink-soft is the pairing the design system
     already defines for rose surfaces (see the "Rose" section in
     :root). */
  color: var(--rose-ink-soft);
  font-size: 0.92rem;
}

/* --------------------------------------------------------------------
   Private-Feiern-Anfrageformular
   -------------------------------------------------------------------- */

.private-event-form {
  display: grid;
  gap: 1.1rem;
  max-width: 480px;
  margin: 1.75rem auto 0;
  text-align: left;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 560px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

.form-field {
  display: grid;
  gap: 0.35rem;
}

.form-field label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--page-ink, var(--ink-soft));
}

.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 0.95rem;
  padding: 0.65em 0.85em;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper-raised);
  color: var(--ink);
}

.form-field textarea {
  resize: vertical;
  min-height: 5rem;
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--tt-gold);
  box-shadow: 0 0 0 3px rgba(169, 143, 74, 0.22);
}

/* Off-screen, not display:none — some simple bots skip display:none
   fields entirely, which would defeat the honeypot; a real visitor never
   sees this either way, and tabindex/autocomplete keep it out of
   keyboard nav and password-manager suggestions. */
.form-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-error-text {
  display: block;
  color: #a6402c;
  font-size: 0.78rem;
}

.form-success-banner {
  margin: 1.75rem auto 0;
  max-width: 480px;
  padding: 1.1rem 1.4rem;
  background: var(--tt-rose-beige);
  border: 1px solid var(--tt-gold);
  border-radius: 8px;
  color: var(--rose-ink);
  font-weight: 600;
}

.form-checkbox-fieldset {
  border: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.5rem;
}

.form-checkbox-fieldset legend {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--page-ink, var(--ink-soft));
  padding: 0;
  margin-bottom: 0.15rem;
}

.form-hint {
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  opacity: 0.75;
}

.form-checkbox {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.92rem;
  color: var(--ink);
  cursor: pointer;
}

.form-checkbox input[type="checkbox"] {
  width: 1.1em;
  height: 1.1em;
  accent-color: var(--tt-gold);
  flex: none;
}

.form-consent {
  font-size: 0.85rem;
  color: var(--page-ink, var(--ink-soft));
}

/* --------------------------------------------------------------------
   Kontakt / Reservierung
   -------------------------------------------------------------------- */

.teburio-embed {
  width: 100%;
  min-height: 640px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper-raised);
}

.teburio-embed iframe {
  width: 100%;
  height: 640px;
  border: 0;
  display: block;
}

.contact-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}

@media (max-width: 760px) {
  .contact-grid {
    grid-template-columns: 1fr;
  }
}

.footer-col-heading {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.7rem;
}

/* Auf der Standort-Karte darf die Öffnungszeiten-Überschrift größer sein
   als das sonst kleinere Footer-/Kontaktseiten-Pendant. */
.find-us-grid .footer-col-heading {
  font-size: 0.95rem;
}

/* --------------------------------------------------------------------
   Menu / Karte
   -------------------------------------------------------------------- */

.menu-category {
  margin-bottom: 1.1rem;
}

.menu-category:last-child {
  margin-bottom: 0;
}

.menu-category-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  cursor: pointer;
  padding-bottom: 0.5rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--line);
  list-style: none;
}

.menu-category-heading {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}

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

/* Says "Ausklappen"/"Einklappen" (translated) next to the +/- symbol, so
   a collapsed category reads as collapsible at a glance instead of relying
   on the +/- alone. */
.menu-category-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
}

.menu-category-toggle-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.menu-category-toggle-label--collapse {
  display: none;
}

details[open] > .menu-category-summary .menu-category-toggle-label--expand {
  display: none;
}

details[open] > .menu-category-summary .menu-category-toggle-label--collapse {
  display: inline;
}

.menu-category-toggle::after {
  content: '+';
  flex: none;
  font-family: var(--font-mono);
  font-size: 1.1rem;
  color: var(--accent);
  transition: transform 0.15s ease;
}

details[open] > .menu-category-summary .menu-category-toggle::after {
  content: '\2212';
}

.menu-category-summary:hover .menu-category-toggle::after {
  color: var(--accent-2);
}

.menu-category-eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0.25rem 0 0;
}

.menu-category-name {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.35rem;
  letter-spacing: 0.01em;
}

/* Mehrere gleichnamige Kategorien (z.B. "Favourites" nach Region, "Whisky
   & Whiskey" nach Anbaugebiet) landen in einer gemeinsamen Karte statt
   mehrfach mit demselben Titel hintereinander zu stehen — jede behält
   ihre eigene Zwischenüberschrift. */
.menu-subcategory {
  margin-top: 1.6rem;
}

.menu-subcategory + .menu-subcategory {
  padding-top: 1.4rem;
  border-top: 1px dashed var(--line);
}

.menu-subcategory-heading {
  font-family: var(--font-mono);
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.8rem;
}

.menu-item-list {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.menu-item-row {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
}

.menu-item-row.is-special {
  border: 1px dashed var(--tt-gold);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin: -0.6rem -0.8rem;
}

.menu-item-main {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.menu-item-name {
  font-weight: 600;
}

.menu-item-desc {
  font-size: 0.86rem;
  color: var(--ink-soft);
}

.menu-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 700;
  min-width: 1.3em;
  height: 1.3em;
  padding: 0 0.35em;
  border-radius: 999px;
  border: 1px solid var(--accent-2);
  color: var(--accent-2);
  margin-left: 0.35em;
  vertical-align: middle;
}

.menu-tag.vegan {
  border-color: var(--accent-2);
  color: var(--accent-2);
}

.menu-tag.vegetarian {
  border-color: var(--accent);
  color: var(--accent);
}

.menu-tag.late-night {
  border-color: var(--tt-gold);
  color: var(--tt-gold);
}

.menu-special-badge {
  display: inline-flex;
  position: relative;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tt-gold);
  border: 1px solid var(--tt-gold);
  border-radius: 999px;
  padding: 0.2em 0.7em;
  margin-left: 0.4em;
  vertical-align: middle;
  transform: rotate(-4deg);
}

.menu-special-badge::before {
  content: "";
  position: absolute;
  inset: 2px;
  border: 1px dashed var(--tt-gold);
  border-radius: inherit;
  opacity: 0.6;
  pointer-events: none;
}

.menu-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.6rem;
  list-style: none;
  margin: 2rem 0 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper-raised, transparent);
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.menu-legend li {
  display: flex;
  align-items: center;
  gap: 0.5em;
}

.menu-item-price {
  flex: none;
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.menu-price-tier {
  display: flex;
  gap: 0.7rem;
  justify-content: flex-end;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.menu-price-tier span:last-child {
  color: var(--ink);
  min-width: 4.5ch;
}

/* Preisstaffeln mit langen Labels (z.B. Painkiller "No. 2 - für milde
   Fälle: 4cl Pusser's Rum") sprengen auf Telefonbreite die feste,
   nicht-umbrechende Preisspalte und schieben die ganze Seite in die
   Breite. Nur betroffene Zeilen (has-tiered-price) auf Mobilgeräten auf
   volle Breite stapeln, damit die Labels normal umbrechen können -
   einfache Ein-Preis-Zeilen bleiben unverändert kompakt. */
@media (max-width: 640px) {
  .menu-item-row.has-tiered-price {
    flex-direction: column;
    gap: 0.35rem;
  }

  .menu-item-row.has-tiered-price .menu-item-price {
    white-space: normal;
  }

  /* Nur das Label (erstes span) darf umbrechen. Der Preis (zweites span)
     bleibt bewusst nowrap, sonst reißt es "11,90" vom "€" auf zwei
     Zeilen auseinander. align-items: flex-start statt des ererbten
     center hält den Preis oben neben der ersten Umbruchzeile des
     Labels, statt ihn über die ganze umgebrochene Höhe zu zentrieren. */
  .menu-item-row.has-tiered-price .menu-price-tier {
    align-items: flex-start;
  }

  .menu-item-row.has-tiered-price .menu-price-tier span:first-child {
    white-space: normal;
    flex: 1 1 auto;
    min-width: 0;
  }

  .menu-item-row.has-tiered-price .menu-price-tier span:last-child {
    white-space: nowrap;
    flex: none;
  }
}

.event-reservation-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.6rem;
  padding: 0.45em 0.95em;
  background: rgba(47, 62, 45, 0.08);
  border: 1px solid var(--accent-2);
  border-radius: 999px;
  color: var(--accent-2);
  font-weight: 700;
  font-size: 0.88rem;
}

.event-reservation-hint::before {
  content: "\2605";
  font-size: 0.9em;
}

.event-reservation-hint + .btn {
  margin-top: 0.5rem;
}

/* Same pill shape as .event-reservation-hint, just gold instead of green
   and an info glyph instead of a star — was a plain 0.92rem/--ink-soft
   <p>, easy to miss next to the bold reservation hint/button. */
.event-no-reservation-note {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.6rem;
  padding: 0.45em 0.95em;
  background: rgba(169, 143, 74, 0.12);
  border: 1px solid var(--tt-gold);
  border-radius: 999px;
  color: var(--rose-ink);
  font-weight: 700;
  font-size: 0.88rem;
}

.event-no-reservation-note::before {
  content: "\2139";
  font-size: 0.95em;
}

/* --------------------------------------------------------------------
   Event-Ticket — der komplette Hero-Kopf (Titel, Untertitel, Termin) als
   Boarding-Pass, im Reisethema der Seite. Eigener Papier-Hintergrund
   unabhängig vom Kontext (dunkler Seiten-Hero vs. helles Event-Modal)
   hält Titel/Termin immer lesbar, ohne dass Textfarben je nach Kontext
   umgeschaltet werden müssten. Bewusst ohne clip-path/Ausstanzungen und
   ohne rotate()-Transform auf der Karte selbst nach den Problemen der
   vorherigen Entwürfe (siehe Git-Historie) — nur Rahmen, Rechtecke und
   ein SVG-Barcode, nichts, das an einem variabel-hohen Element brechen
   könnte.
   -------------------------------------------------------------------- */
.event-ticket {
  position: relative;
  width: 100%;
  /* No pixel cap of its own — the hero's .container now carries the same
     max-width:760px as the text section's .container below it (see
     pages/events/show.blade.php), so the ticket just fills that and the
     two line up exactly instead of guessing the content width here too. */
  max-width: 100%;
  margin: 1.4rem auto 0;
  background: var(--tt-rose-beige);
  border: 1px solid var(--tt-gold);
  border-radius: 6px;
  box-shadow: var(--shadow-soft);
  text-align: left;
  overflow: hidden;
}

.event-ticket-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.9rem;
  border-bottom: 1px solid var(--tt-gold);
}

.event-ticket-brand {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--rose-ink);
}

.event-ticket-brand-icon {
  color: var(--tt-gold);
  font-size: 0.9rem;
  transform: rotate(-45deg);
}

.event-ticket-status {
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tt-gold);
}

.event-ticket-body {
  padding: 0.8rem 0.9rem 0.9rem;
  overflow-wrap: break-word;
}

.event-ticket-title-wrap {
  position: relative;
}

.event-ticket h1 {
  color: var(--rose-ink);
  font-size: clamp(1.35rem, 4.5vw, 1.7rem);
  line-height: 1.2;
  margin: 0 0 0.15rem;
}

.event-ticket .event-subtitle {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--rose-ink-soft);
  font-size: clamp(0.88rem, 2.2vw, 1.05rem);
  max-width: none;
  margin: 0 0 0.7rem;
}

.event-ticket-fields {
  display: flex;
  gap: 1.6rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--tt-gold);
}

.event-ticket-field-label {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--rose-ink-soft);
}

.event-ticket-field-value {
  font-family: var(--font-mono);
  font-size: clamp(1rem, 2.4vw, 1.2rem);
  font-weight: 600;
  color: var(--rose-ink);
  margin-top: 0.1rem;
  white-space: nowrap;
}

/* Sized and positioned to sit centered over the title (not the whole
   card) regardless of how long the title is — .event-ticket-title-wrap
   is the positioning root, sized to the title text itself. Double
   border + mix-blend-mode: multiply is what sells the "stamped ink"
   look: it darkens where it overlaps the card instead of sitting flat
   on top like a sticker. */
.event-ticket-cancelled-stamp {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-9deg);
  padding: 0.22em 0.7em;
  border: 2.5px solid #a6402c;
  outline: 1.5px solid #a6402c;
  outline-offset: 2.5px;
  border-radius: 4px;
  color: #a6402c;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  mix-blend-mode: multiply;
  opacity: 0.82;
  pointer-events: none;
}

.event-ticket.is-cancelled {
  opacity: 0.85;
}

.event-ticket .event-moved-from {
  margin: 0.5rem 0 0;
  max-width: none;
  font-size: 0.74rem;
  line-height: 1.3;
  font-style: italic;
  color: var(--rose-ink-soft);
}

/* Narrower and centered rather than edge-to-edge — a full-bleed strip at
   the card's own width read as oversized next to the compact fields
   above it. */
.event-ticket-barcode {
  display: block;
  width: 70%;
  height: 11px;
  margin: 0.9rem auto 0;
  opacity: 0.9;
}

.event-ticket-barcode rect {
  fill: var(--rose-ink);
}

/* --------------------------------------------------------------------
   Kalenderseiten — wiederkehrende Termine als kleiner Stapel alter
   Abreißkalenderblätter, leicht schräg nebeneinander wie zufällig hingelegt.
   -------------------------------------------------------------------- */

.calendar-pages {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1.4rem;
  margin: 0 0 2rem;
}

.calendar-page {
  position: relative;
  flex: none;
  width: 108px;
  background: var(--paper-raised);
  border-radius: 6px;
  box-shadow: var(--shadow-soft);
  overflow: hidden;
  text-align: center;
  transform: rotate(var(--tilt, 0deg));
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.calendar-page:nth-child(3n+1) { --tilt: -2.5deg; }
.calendar-page:nth-child(3n+2) { --tilt: 1.75deg; }
.calendar-page:nth-child(3n+3) { --tilt: -1deg; }

.calendar-page:hover {
  transform: rotate(0deg) translateY(-3px);
  box-shadow: 0 6px 16px rgba(31, 40, 55, 0.18);
  z-index: 1;
}

.calendar-page-weekday {
  background: var(--accent-2);
  color: var(--tt-white);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.35rem 0;
  border-bottom: 2px dashed rgba(255, 255, 255, 0.5);
}

.calendar-page-day {
  font-family: var(--font-display);
  font-size: 2.05rem;
  line-height: 1.15;
  color: var(--ink);
  padding-top: 0.35rem;
}

.calendar-page-month {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.calendar-page-time {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--ink-soft);
  padding-bottom: 0.55rem;
}

.calendar-page-note {
  font-size: 0.7rem;
  color: var(--ink-soft);
  padding: 0 0.4rem 0.5rem;
}

.calendar-page-moved-from {
  font-size: 0.62rem;
  line-height: 1.3;
  font-style: italic;
  color: var(--ink-soft);
  padding: 0 0.4rem 0.5rem;
}

.calendar-page.is-cancelled {
  opacity: 0.55;
}

.calendar-page-cancelled {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #a6402c;
  padding: 0.3rem 0 0.5rem;
}

/* 320px is only the pre-JS fallback (so there's a numeric starting point
   for the max-height transition, and content isn't briefly shown in full
   before JS runs) — calendar-pages.js immediately overrides this with an
   exact pixel height measured from the actual rendered rows, so it always
   matches "two rows" regardless of card height (a card carrying a
   "verschoben"-Hinweis is noticeably taller than a plain one, which a
   fixed cap can never account for reliably: see the row-measuring logic
   in calendar-pages.js instead). */
.calendar-pages-wrap[data-collapsible] .calendar-pages {
  max-height: 320px;
  overflow: hidden;
  transition: max-height 0.2s ease;
}

.calendar-pages-wrap[data-collapsible]:not(.is-fully-expanded) {
  position: relative;
}

.calendar-pages-wrap[data-collapsible]:not(.is-fully-expanded)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2.6rem;
  height: 3rem;
  background: linear-gradient(to bottom, rgba(245, 239, 234, 0), var(--paper));
  pointer-events: none;
}

.calendar-pages-more {
  display: block;
  margin: 0.6rem auto 2rem;
  background: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.5em 1.2em;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  cursor: pointer;
}

/* Author CSS always wins over the user-agent stylesheet's [hidden] rule,
   so the display:block above silently defeated the button's `hidden`
   attribute entirely — calendar-pages.js was toggling `hidden` correctly
   the whole time, it just never had any visible effect. This is the
   actual fix for the "Noch mehr Termine" button that stayed visible with
   nothing left to reveal. */
.calendar-pages-more[hidden] {
  display: none;
}

.calendar-pages-more:hover {
  border-color: var(--accent-2);
  color: var(--accent-2);
}

/* --------------------------------------------------------------------
   Placeholder pages
   -------------------------------------------------------------------- */

.placeholder-page {
  text-align: center;
  padding-block: 5rem;
}

/* Impressum/Datenschutz: schlichter Fliesstext statt Passport-Page-Deko —
   das ist Pflichttext, keine Marketingseite. */
.legal-page {
  max-width: 65ch;
  padding-block: 3rem 5rem;
}

.legal-page h2 {
  margin-top: 2.5rem;
}

.legal-page h4 {
  margin-top: 1.5rem;
}

.legal-page ul {
  color: var(--ink-soft);
  padding-inline-start: 1.25rem;
}

.legal-page ul li + li {
  margin-top: 0.5rem;
}

.legal-page-source {
  margin-top: 3rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.placeholder-page p {
  color: var(--ink-soft);
  max-width: 50ch;
  margin-inline: auto;
}

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

/* Partner-Marke: Namen laufen endlos von rechts nach links durch, dezent
   und einfarbig (kein Logo-Nachbau — echte Markenlogos liegen uns nicht
   vor). Der Trick für nahtloses Endlos-Scrollen: die Liste wird im Markup
   einmal verdoppelt, dann exakt um die Hälfte der Track-Breite
   verschoben — an dem Punkt sieht die zweite Kopie genauso aus wie der
   Ausgangszustand, der Sprung zurück auf 0% ist unsichtbar. */
.partners-strip {
  overflow: hidden;
  border-bottom: 1px solid var(--chrome-line);
  padding-block: 1rem;
  background: var(--chrome-bg);
}

.partners-track {
  display: flex;
  width: max-content;
  gap: 3.5rem;
  animation: partners-scroll 34s linear infinite;
}

.partners-item {
  flex: none;
  display: flex;
  align-items: center;
  opacity: 0.6;
}

.partners-item img {
  display: block;
  height: 34px;
  width: auto;
}

.partners-item--text {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--chrome-ink-soft);
  white-space: nowrap;
}

@keyframes partners-scroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

/* Bewusst KEIN .pattern-arches auf dem Footer (siehe footer.blade.php) —
   ein eigener, klar abgegrenzter Abschluss statt einer weiteren Fläche
   mit dem Geflecht-Muster. Ein einfarbiger Hintergrund in derselben
   Chrome-Farbe schließt nahtlos an die angrenzenden .pattern-arches-
   Abschnitte an. */
.site-footer {
  background: var(--chrome-bg);
  color: var(--chrome-ink);
}

.footer-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.5rem;
  padding-block: 3.5rem;
}

@media (max-width: 760px) {
  .footer-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 560px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

.footer-col h3 {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--chrome-ink-soft);
  margin-bottom: 0.9rem;
}

.footer-col p,
.footer-col address {
  font-style: normal;
  color: var(--chrome-ink);
  font-size: 0.92rem;
  margin: 0 0 0.4rem;
}

.footer-col a {
  color: var(--chrome-ink);
}

.hours-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.88rem;
}

.hours-list li {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.2rem 0;
  border-bottom: 1px dashed var(--chrome-line);
}

.hours-list li:last-child {
  border-bottom: none;
}

.world-clock {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem 0.5rem;
}

@media (max-width: 400px) {
  .world-clock {
    grid-template-columns: repeat(2, 1fr);
  }
}

.world-clock > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

/* Namensschild unterm Ziffernblatt, wie bei echten Flur-/Lobby-Weltuhren:
   dunkles Schild, heller Grossbuchstaben-Stadtname. */
.world-clock .clock-city {
  background: #14100c;
  color: var(--chrome-ink);
  font-size: 0.6rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: center;
  padding: 0.15rem 0.5rem;
  border-radius: 2px;
}

.analog-clock svg {
  display: block;
}

.analog-clock .clock-bezel {
  fill: var(--tt-gold);
}

.analog-clock .clock-face {
  fill: #f4efe1;
  stroke: rgba(10, 15, 25, 0.25);
  stroke-width: 0.4;
}

.analog-clock .clock-num {
  font-size: 4.3px;
  font-weight: 700;
  fill: #2a241c;
  text-anchor: middle;
  font-family: var(--font-mono, monospace);
}

.analog-clock .clock-hand-hour,
.analog-clock .clock-hand-minute {
  stroke: #2a241c;
  stroke-linecap: round;
}

.analog-clock .clock-hand-hour {
  stroke-width: 2.2;
}

.analog-clock .clock-hand-minute {
  stroke-width: 1.4;
}

.analog-clock .clock-hand-second {
  stroke: #a6402c;
  stroke-width: 0.7;
  stroke-linecap: round;
}

.analog-clock .clock-center {
  fill: #a6402c;
}

.footer-legal {
  border-top: 1px solid var(--chrome-line);
  padding-block: 1.2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.8rem;
  font-size: 0.82rem;
  color: var(--chrome-ink-soft);
}

.footer-legal a {
  color: var(--chrome-ink-soft);
  margin-inline-end: 1rem;
}

