/* ==========================================================================
   base.css — Schriften, Grundstellung, Typografie
   Fabio Venier DF Immobilienbetreuung

   Reihenfolge der Stylesheets: tokens → base → layout → components → pages
   Diese Datei fasst ausschliesslich Elemente an, keine Abschnittsklassen.
   Damit gibt es zwischen Element- und Abschnittsebene keinen
   Spezifitaetskonflikt: base.css bleibt immer bei Spezifitaet 0,0,1.

   ---------------------------------------------------------------------------
   VERTRAG ZUR BEWEGUNG — hier steht der wichtigste Teil der Datei.

   Der Grundzustand jedes Elements ist der ENDZUSTAND: sichtbar, an seiner
   Position, opacity 1. Es gibt in diesem Projekt kein Element, das im CSS
   auf opacity: 0 steht und darauf wartet, dass JavaScript es einblendet.

   Startzustaende fuer Animationen haengen ausnahmslos an der Klasse
   html.bewegung. Diese Klasse wird in einem winzigen Inline-Skript im
   <head> gesetzt, und zwar nur wenn:
     - JavaScript laeuft, und
     - prefers-reduced-motion NICHT auf reduce steht.

   Zusaetzlich entfernt ein Wachhund die Klasse wieder, falls GSAP nicht
   innerhalb von 2,5 Sekunden uebernimmt (Skript blockiert, Netzfehler,
   alter Browser). Dadurch ist der haeufige schwere Fehler — Inhalte
   bleiben unsichtbar auf opacity: 0 stehen — konstruktionsbedingt
   ausgeschlossen und nicht bloss "getestet".
   --------------------------------------------------------------------------- */


/* ==========================================================================
   1. SCHRIFTEN
   Lokal eingebettet. Kein Aufruf an Google, kein Drittanbieter.
   Grund: DSGVO — ohne Einwilligung darf keine Verbindung zu Dritten
   aufgebaut werden, und eine Einwilligung fuer Schriften waere unnoetig.
   ========================================================================== */

/* --- Inter, variabel (Gewicht 100-900) -----------------------------------
   Eine Schrift fuer die ganze Seite. Die Rollen Display, Fliesstext und
   Label werden ueber Gewicht, Groesse und Laufweite unterschieden.

   Die Datei liegt LOKAL. Es geht kein Aufruf an fonts.googleapis.com und
   keiner an fonts.gstatic.com — sonst waere nach DSGVO eine Einwilligung
   noetig. Optik von Google Fonts, ohne die Verbindung zu Google. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-100-900-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-100-900-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
                 U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
                 U+2C60-2C7F, U+A720-A7FF;
}


/* --- Manrope, variabel (Gewicht 200-800) ---------------------------------
   Ausschliesslich fuer Ueberschriften und grosse Zahlen. Etwas mehr
   Charakter als Inter, ohne dekorativ zu werden.
   Ebenfalls LOKAL — kein Aufruf an Google. */
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('../assets/fonts/manrope-200-800-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('../assets/fonts/manrope-200-800-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
                 U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
                 U+2C60-2C7F, U+A720-A7FF;
}


/* ==========================================================================
   2. GRUNDSTELLUNG
   ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* scroll-behavior wird bewusst NICHT auf smooth gesetzt.
     Das weiche Scrollen uebernimmt Lenis. Beides zusammen erzeugt
     gegeneinander laufende Bewegung. */
  scroll-behavior: auto;
}

/* Ankersprunge sollen nicht unter der festen Kopfzeile landen. */
:where(section, article, [id]) { scroll-margin-top: var(--raum-6); }

body {
  min-height: 100svh;
  background-color: var(--papier);
  color: var(--tiefe);
  font-family: var(--schrift-text);
  font-size: var(--gr-16);
  font-weight: var(--fett-text);
  line-height: var(--zeile-text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis-weight: none;
  /* Waagrechtes Verrutschen ist bei gepinnten, horizontal bewegten
     Abschnitten der haeufigste Fehler. Hier einmal zentral verhindert. */
  overflow-x: hidden;
}

/* Lenis benoetigt diese beiden Regeln, sonst greift das weiche Scrollen
   nicht und die Hoehenberechnung von ScrollTrigger wird ungenau. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

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

input, button, textarea, select { font: inherit; color: inherit; }

/* --- Umbruch langer Woerter ----------------------------------------------
   Deutsche Zusammensetzungen wie "Immobilienbetreuung" oder
   "Ansprechpartner" sprengen schmale Spalten. Dafuer gibt es zwei
   Werkzeuge, und nur eines davon ist richtig:

   hyphens: auto      trennt nach den Regeln der Sprache und setzt einen
                      Trennstrich. Braucht lang="de-AT" am <html>, das
                      steht dort.
   overflow-wrap:     bricht stumpf an beliebiger Stelle, ohne Strich.
     break-word       Ergebnis: "Ansprec / hpartner".

   In der ersten Fassung stand break-word auch auf den Ueberschriften.
   Genau das hat die Ueberschriften mitten im Wort zerrissen. Bei
   Ueberschriften ist der stumpfe Bruch deshalb ausgeschlossen: Sie
   brechen an Leerzeichen, und wenn ein einzelnes Wort nicht passt,
   wird es sauber getrennt. */
h1, h2, h3, h4 {
  overflow-wrap: normal;
  word-break: normal;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* Im Fliesstext bleibt break-word als letztes Netz, damit eine sehr
   lange E-Mail-Adresse oder URL das Layout nicht aufreisst. Die
   Silbentrennung greift vorher. */
p, li, dt, dd {
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
}


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

h1, h2, h3, h4 {
  font-family: var(--schrift-display);
  font-weight: var(--fett-h);
  font-stretch: var(--breite-display);
  line-height: var(--zeile-display);
  letter-spacing: var(--lauf-display);
  text-wrap: balance;
}

h1 { font-size: var(--gr-seiten-h1); font-weight: var(--fett-display); }
h2 { font-size: var(--gr-abschnitt); }
/* h3 stand auf 34 px und h2 loest ueber clamp bei ueblichen Breiten
   auf 34,5 px auf — beide waren praktisch gleich gross und es gab
   keine Rangordnung mehr. Jetzt ein klarer Schritt zwischen den
   Ebenen: h2 rund 34, h3 26, h4 20. */
h3 { font-size: var(--gr-26); line-height: var(--zeile-eng); }
h4 { font-size: var(--gr-20); line-height: var(--zeile-eng); }

p { text-wrap: pretty; }
p + p { margin-top: var(--raum-3); }

/* --- Satzbreite ----------------------------------------------------------
   Fliesstext im Inhaltsbereich bekommt eine Obergrenze. Ohne sie liefen
   Absaetze ueber die volle Spaltenbreite — gemessen bis 94 Zeichen je
   Zeile. Ab etwa 75 Zeichen findet das Auge beim Zeilenwechsel den
   Anfang der naechsten Zeile nicht mehr zuverlaessig.

   Absaetze in ohnehin schmalen Spalten sind davon unberuehrt: Die Regel
   deckelt nur nach oben. Ausgenommen sind Bauteile, die ihre Breite
   selbst bestimmen (Formularhilfen, Bildunterschriften, Fusszeile). */
main p:not(.bild-motiv) { max-width: var(--satzbreite); }

strong, b { font-weight: var(--fett-betont); }

/* --- Verweise ------------------------------------------------------------
   Unterstreichung als Haarlinie mit Abstand, nicht als Standardstrich.
   Beim Ueberfahren wandert die Linie an den Text heran. */
a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: var(--linie-staerke);
  text-underline-offset: 0.28em;
  text-decoration-color: var(--linie);
  transition: text-decoration-color var(--dauer-kurz) var(--kurve-aus),
              text-underline-offset var(--dauer-kurz) var(--kurve-aus),
              color var(--dauer-kurz) var(--kurve-aus);
}
a:hover { text-decoration-color: var(--akzent); text-underline-offset: 0.18em; }

/* --- Listen --------------------------------------------------------------
   Aufzaehlungen bekommen einen eigenen Marker als Haarlinie statt eines
   Punktes. Das passt zum Strichduktus der Icons und der Rasterlinien. */
ul, ol { padding-left: 0; list-style: none; }

/* --- Label-Rolle ---------------------------------------------------------
   Plex Mono, klein, versal, gesperrt. Ausschliesslich fuer Marginalien,
   Monatsbeschriftungen, Formularlabels und Spurbezeichnungen. */
.label {
  font-family: var(--schrift-label);
  font-size: var(--gr-12);
  font-weight: var(--fett-label);
  line-height: var(--zeile-dicht);
  letter-spacing: var(--lauf-label);
  text-transform: uppercase;
  color: var(--text-2);
}


/* ==========================================================================
   4. BEDIENBARKEIT
   ========================================================================== */

/* --- Fokus ---------------------------------------------------------------
   Sichtbar auf hellem wie auf dunklem Grund. Der Ring wird bewusst nicht
   auf :focus, sondern auf :focus-visible gelegt, damit ein Mausklick
   keinen Ring hinterlaesst, die Tastaturbedienung aber immer einen zeigt. */
:focus-visible {
  outline: var(--fokus-kontur) solid var(--fokus);
  outline-offset: var(--fokus-abstand);
  border-radius: var(--radius);
}
:focus:not(:focus-visible) { outline: none; }

/* Auf invertierten Baendern muss der Ring die helle Farbe annehmen. */
.band-tief :focus-visible { outline-color: var(--auf-tiefe); }

/* --- Sprungmarke ---------------------------------------------------------
   Erste fokussierbare Stelle der Seite. Sichtbar, sobald sie Fokus hat. */
.sprungmarke {
  position: absolute;
  top: var(--raum-2);
  left: var(--raum-2);
  z-index: var(--z-menue);
  padding: var(--raum-2) var(--raum-3);
  background: var(--tiefe);
  color: var(--auf-tiefe);
  text-decoration: none;
  font-family: var(--schrift-label);
  font-size: var(--gr-12);
  letter-spacing: var(--lauf-label);
  text-transform: uppercase;
  transform: translateY(calc(-100% - var(--raum-4)));
  transition: transform var(--dauer-mittel) var(--kurve-aus);
}
.sprungmarke:focus { transform: translateY(0); }

/* --- Kurzfassungen fuer die Handyansicht ---------------------------------
   Fuer Saetze, die fest im HTML stehen und deshalb nicht ueber die
   Kurzfassungen aus content.js laufen koennen.

     <span class="nur-breit">Langer Satz mit allen Einzelheiten.</span>
     <span class="nur-schmal">Kurzer Satz.</span>

   Es ist immer genau eine der beiden Fassungen im Fluss. Beide stehen
   im Quelltext, aber display: none nimmt die nicht gebrauchte auch aus
   der Vorlesereihenfolge — es wird also nichts doppelt angesagt.

   Wichtig: Das ist KEIN Ersatz fuer inhaltliche Arbeit. Wenn ein Satz
   am Handy nicht gebraucht wird, gehoert er meist auch am Rechner
   gekuerzt. Die beiden Klassen sind fuer die Faelle, wo die lange
   Fassung wirklich Mehrwert hat und nur der Platz fehlt.
   ------------------------------------------------------------------------ */
.nur-schmal { display: none; }

@media (max-width: 47.99rem) {
  .nur-breit  { display: none; }
  .nur-schmal { display: inline; }
  /* Als Block ausgezeichnete Kurzfassungen behalten ihre Anzeigeart. */
  p.nur-schmal, div.nur-schmal { display: block; }
}

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

::selection { background: var(--akzent); color: var(--papier); }


/* ==========================================================================
   5. STARTZUSTAENDE FUER BEWEGUNG
   --------------------------------------------------------------------------
   Alles hier haengt an html.bewegung. Ohne diese Klasse existiert kein
   einziger unsichtbarer Zustand — die Seite ist dann statisch vollstaendig
   lesbar. Siehe Vertrag am Dateianfang.
   ========================================================================== */

/* Zeilenweise Einblendung: Die Zeile wird von einer Maske beschnitten und
   von unten hereingeschoben. Ohne .bewegung sitzt sie einfach da. */
.zeile-maske { display: block; overflow: hidden; }

/* Der innere Traeger MUSS ein Block sein.
   transform wirkt nicht auf nicht-ersetzte Inline-Elemente — ein
   <span> ohne diese Zeile bliebe unverschoben und die ganze
   Zeilenmaske waere wirkungslos, ohne dass es eine Fehlermeldung gibt. */
.zeile-maske > * { display: block; }

html.bewegung .zeile-maske > * { transform: translateY(105%); }
html.bewegung [data-auftritt]  { opacity: 0; }


/* Sicherheitsnetz: Sollte der Wachhund greifen, wird die Klasse entfernt
   und beide Regeln oben verlieren ihre Grundlage. Zusaetzlich hier noch
   einmal ausdruecklich, falls ein Element bereits von GSAP angefasst wurde
   und ein Inline-Style zurueckbleibt. */
html.bewegung-aus [data-auftritt],
html.bewegung-aus .zeile-maske > * {
  opacity: 1 !important;
  transform: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html [data-auftritt],
  html .zeile-maske > * {
    opacity: 1 !important;
    transform: none !important;
  }
  /* Die Maske wuerde sonst weiterhin beschneiden. */
  .zeile-maske { overflow: visible; }
}


/* ==========================================================================
   HANDY — Trefferflaechen im Fliesstext
   --------------------------------------------------------------------------
   Verweise mitten im Satz sind so hoch wie ihre Zeile, gemessen 20 Pixel.
   Fuer einen Daumen ist das zu wenig. Betroffen sind ausgerechnet die
   wichtigsten: Telefonnummer und E-Mail im Impressum, der Verweis auf die
   Datenschutzerklaerung unter dem Formular.

   Zwei Wege, je nach Lage:

   a) Steht der Verweis allein in seiner Zeile (Impressumsliste), wird er
      zum Block mit voller Hoehe. Am Zeilenfall aendert das nichts, weil
      ohnehin nichts danebensteht.

   b) Steht er mitten im Satz, bekommt er senkrechten Innenabstand.
      An einem Inline-Element waechst der ueber die Zeilenbox HINAUS,
      statt sie aufzublaehen — der Text rueckt also nicht auseinander,
      die Trefferflaeche wird trotzdem groesser.

      Preis von b): Liegen in einem Absatz zwei Verweise direkt
      untereinander, ueberlappen ihre Trefferflaechen leicht. Das kommt
      auf dieser Seite nirgends vor, und 20 Pixel hohe Ziele waeren in
      jedem Fall das groessere Problem.
   ========================================================================== */

@media (max-width: 47.99rem) {
  main dd > a:only-child {
    display: flex;
    align-items: center;
    min-height: 2.75rem;
  }
  /* dialog muss mitgenannt werden: Das Anfrage-Sheet haengt am body und
     liegt damit ausserhalb von main. Ohne das blieb der Verweis auf die
     Datenschutzerklaerung im Sheet bei 16 Pixeln stehen. */
  main p a,
  dialog p a { padding-block: 0.875rem; }
}
