* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; background: #0d1f10; }

#intro {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  background: #060d10;
  /* Kürzer als der Anflug (2,6 s), damit der Garten während der Fahrt
     freigegeben wird und nicht erst, wenn die Kamera schon steht. */
  transition: opacity 0.9s ease, visibility 0.9s ease;
}
#intro.fade-out { opacity: 0; visibility: hidden; }
#intro-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

.intro-content {
  position: relative; z-index: 2;
  text-align: center;
  animation: introFadeUp 1s 0.4s both;
}
.intro-eyebrow {
  font-family: 'DM Mono', monospace; font-weight: 300;
  font-size: 0.72rem; letter-spacing: 0.28em; text-transform: uppercase;
  color: #4caf6e; margin-bottom: 1.4rem;
}
.intro-title {
  font-family: 'Playfair Display', serif;
  font-size: clamp(3.5rem, 10vw, 7rem); font-weight: 700;
  line-height: 0.9; color: #e8f5e9; margin-bottom: 1.4rem;
}
.intro-title em { display: block; font-style: italic; color: #6bde92; }
.intro-sub {
  font-family: 'DM Mono', monospace; font-weight: 300;
  font-size: 0.82rem; letter-spacing: 0.1em; color: #89a892; margin-bottom: 3rem;
}
.intro-enter {
  font-family: 'DM Mono', monospace; font-size: 0.68rem;
  letter-spacing: 0.25em; text-transform: uppercase;
  color: #4caf6e; border: 1px solid rgba(76,175,110,0.4);
  padding: 0.7rem 2rem; cursor: pointer; background: transparent;
  transition: all 0.3s; animation: pulse-border 2s ease-in-out infinite;
}
.intro-enter:hover { background: rgba(76,175,110,0.1); border-color: #6bde92; color: #6bde92; }

.intro-scroll-hint {
  position: absolute; bottom: 2.5rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.5rem;
  animation: introFadeUp 1s 1.4s both;
  /* Der Hinweis führt jetzt auch hinein — vorher war er reine Deko. */
  cursor: pointer;
}
.intro-scroll-hint:hover span { color: #6bde92; }
.intro-scroll-hint span {
  font-family: 'DM Mono', monospace; font-size: 0.62rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: #4a6b52;
}
.scroll-line {
  width: 1px; height: 36px;
  background: linear-gradient(to bottom, #4caf6e, transparent);
  animation: scrollPulse 2s ease-in-out infinite;
}

/* ── SZENE ─────────────────────────────────────────────────────*/
#scene { position: fixed; inset: 0; display: block; touch-action: none; cursor: grab; }
#ui { position: fixed; inset: 0; pointer-events: none; z-index: 40; }

/* ── NAMENSSCHILDER ÜBER DEN PFLANZEN ──────────────────────────
   Stehen dauerhaft da, nicht erst beim Hover: sonst sieht man dem
   Garten nicht an, dass etwas anklickbar ist. Position kommt pro
   Bild aus der Projektion der Blüte. */
/* Bewusst klein und leise: die Schilder sollen den Garten nicht
   beschriften, sondern nur verraten, dass hier etwas zu finden ist. Der
   Name in voller Größe steht in der Hover-Karte. */
.plabel {
  position: absolute; transform: translate(-50%,-100%);
  font-family: 'DM Mono', monospace; font-weight: 300;
  font-size: 0.46rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(224,247,234,0.85); white-space: nowrap; padding: 1px 5px;
  background: rgba(8,20,10,0.3);
  border: 0; border-radius: 2px;
  text-shadow: 0 1px 4px rgba(0,0,0,0.55);
  opacity: 0; transition: opacity .35s ease, transform .25s ease;
  will-change: transform, opacity;
}
.plabel.soon { color: rgba(203,215,209,0.7); }
.plabel .dot { color: #6bde92; font-size: 0.5rem; }

/* ── HOVER-KARTE ───────────────────────────────────────────────*/
#tip {
  position: absolute; transform: translate(-50%,-100%);
  min-width: 190px; padding: 0.85rem 1rem 0.8rem;
  background: linear-gradient(180deg, rgba(10,20,15,0.96), rgba(7,14,11,0.96));
  border: 1px solid rgba(107,222,146,0.28); border-radius: 8px;
  box-shadow: 0 18px 50px rgba(0,0,0,0.55), 0 0 40px -14px var(--tipglow, rgba(107,222,146,0.7));
  opacity: 0; transition: opacity .18s ease; pointer-events: none;
}
#tip.on { opacity: 1; }
/* Kein Platz nach oben: unter den Zeiger klappen statt die Pflanze verdecken. */
#tip.below { transform: translate(-50%, 0); }
#tip .tname { font-family: 'Playfair Display', serif; font-style: italic; font-size: 1.2rem; color: #f3fbf6; line-height: 1; }
#tip .turl  { margin-top: 0.55rem; font-family: 'DM Mono', monospace; font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase; color: #6bde92; }
#tip .tdesc { margin-top: 0.45rem; font-family: 'DM Mono', monospace; font-weight: 300; font-size: 0.66rem; color: #9db3aa; line-height: 1.45; }
#tip .tstate{ display: inline-flex; align-items: center; gap: 6px; margin-top: 0.7rem;
  font-family: 'DM Mono', monospace; font-size: 0.56rem; letter-spacing: 0.2em; text-transform: uppercase; color: #4caf6e; }
#tip .tstate::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: #6bde92; box-shadow: 0 0 8px #6bde92; animation: blink 1.6s infinite;
}
/* Bewohner statt Ziel: keine URL-Zeile, und der Punkt blinkt nicht wie
   bei einem Dienst, der „LIVE" ist. */
#tip.nourl .turl { display: none; }
#tip.critter .tstate::before { animation: none; }
#tip.soon { --tipglow: rgba(160,175,168,0.35); }
#tip.soon .turl { color: #aab8b1; }
#tip.soon .tstate { color: #8b9992; }
#tip.soon .tstate::before { background: #8b9992; box-shadow: none; animation: none; }
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: .25; } }

/* ── BEDIENHINWEIS ─────────────────────────────────────────────
   Kommt erst mit dem Garten und verschwindet beim ersten Griff. */
/* Sitzt oben im Bild, wo je nach Kamerawinkel dunkler Wald ODER helle
   Wiese liegt. Heller Text auf eigener dunkler Fläche ist das einzige,
   was in beiden Lagen trägt — dunkler Text war auf den Bäumen weg. */
#hint {
  position: fixed; top: 1.1rem; left: 50%; transform: translateX(-50%);
  z-index: 45; pointer-events: none; white-space: nowrap;
  font-family: 'DM Mono', monospace; font-weight: 300;
  font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(233,245,238,0.72);
  padding: 0.4rem 0.9rem; border-radius: 4px;
  background: rgba(8,18,14,0.42);
  border: 1px solid rgba(230,245,238,0.12);
  opacity: 0; transition: opacity .8s ease;
}
#hint.on { opacity: 1; }
#hint b { color: #6bde92; font-weight: 400; }
#hint .narrow { display: none; }
/* Auf schmalen Schirmen passt der Satz nicht in eine Zeile — und
   „Scrollen zum Zoomen" gilt am Touchscreen ohnehin nicht. */
@media (max-width: 640px) {
  #hint .wide { display: none; }
  #hint .narrow { display: inline; }
  #hint { font-size: 0.54rem; letter-spacing: 0.16em; }
}

.ripple {
  position: fixed; width: 60px; height: 60px;
  border: 2px solid #6bde92; border-radius: 50%;
  transform: translate(-50%,-50%) scale(0); pointer-events: none; z-index: 60;
  animation: rippleOut 0.5s ease-out forwards;
}
@keyframes rippleOut { to { transform: translate(-50%,-50%) scale(2.5); opacity: 0; } }

#garden-footer {
  position: fixed; bottom: 1.4rem; left: 50%; transform: translateX(-50%);
  z-index: 50; display: flex; align-items: center; gap: 1rem;
  opacity: 0; transition: opacity 1s 0.5s;
}
#garden-footer.visible { opacity: 1; }
/* Heller Text mit Schattenkante: die Szene ist eine helle Wiese, aber der
   Footer liegt je nach Kamerawinkel mal auf Rasen, mal auf dunklem Wald.
   Ein fester dunkler Ton war nur in einer der beiden Lagen lesbar. */
.footer-brand {
  font-family: 'Playfair Display', serif; font-style: italic; font-size: 1.15rem;
  color: #eef7f1; text-shadow: 0 2px 14px rgba(0,0,0,0.55);
}
.footer-bmc {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: 'DM Mono', monospace; font-size: 0.6rem; letter-spacing: 0.22em;
  text-transform: uppercase; color: #dfeee7; text-decoration: none;
  padding: 0.45rem 0.8rem; border-radius: 5px;
  border: 1px solid rgba(230,245,238,0.28);
  background: rgba(10,20,15,0.4); transition: all 0.2s;
}
.footer-bmc svg { width: 13px; height: 13px; flex: none; }
/* Ohne das brach der Button im Hochformat dreizeilig um. */
.footer-bmc { white-space: nowrap; }
.footer-bmc:hover { border-color: #6bde92; color: #6bde92; box-shadow: 0 0 22px -8px #6bde92; }

@keyframes introFadeUp { from { opacity:0; transform:translateY(24px); } to { opacity:1; transform:translateY(0); } }
@keyframes scrollPulse { 0%,100% { opacity:0.3; } 50% { opacity:1; } }
@keyframes pulse-border { 0%,100% { box-shadow:0 0 0 0 rgba(76,175,110,0); } 50% { box-shadow:0 0 0 6px rgba(76,175,110,0.12); } }

/* ── GARTEN-INDEX ──────────────────────────────────────────────
   Die Szene ist Canvas: für Crawler, Screenreader und alles ohne
   WebGL wäre die Seite sonst leer. Dieselben Ziele als echtes,
   verlinktes DOM — versteckt, aber nicht vor der Tastatur. */
#garden-index {
  position: fixed; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* Tab dorthin macht die Liste sichtbar — Tastaturnutzer kommen so an
   jedes Ziel, ohne mit der Maus über den Rasen zu fahren. */
#garden-index:focus-within {
  position: fixed; inset: auto auto 5.5rem 50%;
  transform: translateX(-50%);
  width: min(92vw, 30rem); height: auto;
  margin: 0; padding: 1.2rem 1.4rem; overflow: visible;
  clip: auto; clip-path: none; white-space: normal;
  z-index: 70; background: rgba(8,20,10,0.96);
  border: 1px solid rgba(107,222,146,0.55);
}
#garden-index h2 {
  font-family: 'DM Mono', monospace; font-weight: 400;
  font-size: 0.62rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: #4caf6e; margin-bottom: 0.9rem;
}
#garden-index ul { list-style: none; display: flex; flex-direction: column; gap: 0.75rem; }
#garden-index a, #garden-index .gi-inert { text-decoration: none; display: block; }
.gi-name { font-family: 'Playfair Display', serif; font-size: 1rem; color: #e8f5e9; display: block; }
#garden-index a:hover .gi-name, #garden-index a:focus-visible .gi-name { color: #6bde92; }
.gi-url  { font-family: 'DM Mono', monospace; font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase; color: #6bde92; display: block; }
.gi-desc { font-family: 'DM Mono', monospace; font-weight: 300; font-size: 0.6rem; color: #89a892; display: block; }
.gi-inert .gi-name { color: #89a892; }
#garden-index a:focus-visible { outline: 2px solid #6bde92; outline-offset: 4px; }
.intro-enter:focus-visible, .footer-bmc:focus-visible { outline: 2px solid #6bde92; outline-offset: 3px; }

/* ── FALLBACK: kein JS, kein WebGL ─────────────────────────────
   Statt eines schwarzen Rechtecks die Liste als eigentlicher Inhalt. */
body.fallback #intro, body.fallback #scene, body.fallback #ui, body.fallback #hint { display: none; }
body.fallback #garden-index {
  position: static; transform: none;
  width: min(92vw, 34rem); height: auto; margin: 0 auto; padding: 4rem 1.4rem;
  overflow: visible; clip: auto; clip-path: none; white-space: normal;
  background: none; border: 0;
}
body.fallback { overflow: auto; }
/* Ohne Szene liegt der Footer auf dem dunklen Waldgrund statt auf hellem
   Rasen — die dunkle Schrift wäre dort unsichtbar. */
body.fallback #garden-footer { opacity: 1; position: static; transform: none; justify-content: center; padding-bottom: 3rem; }
body.fallback .footer-brand { color: #89a892; text-shadow: none; }
body.fallback .footer-bmc { color: #6bde92; border-color: rgba(107,222,146,0.45); }

/* ── REDUCED MOTION ────────────────────────────────────────────
   Das CSS erreicht nur die Intro-Ebene; Canvas und three.js hängen an
   ihren eigenen Schaltern in JS (prefersReducedMotion()). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .scroll-line { opacity: 0.6; }
}
