/*
Theme Name: Zumsande Dachmarke
Theme URI: https://luarmedia.de/
Description: Das Dachmarken-Portal auf zumsande.com. Eine einzige Aufgabe: Orientierung. Zwei vollflaechige Raeume, getrennt von einem schraegen Schnitt, fuehren in die beiden Leistungswelten Betriebspruefungen und Buchhaltung. Kein Framework, kein Formular, ein einziges kleines Skript. Betreut von LuarMedia.
Author: LuarMedia
Author URI: https://luarmedia.de/
Version: 1.1.0
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 8.0
License: GPLv2 or later
Text Domain: zumsande-dachmarke
*/

/* =====================================================================
   ZUMSANDE — DACHMARKEN-PORTAL
   Version 2.4.0 (02.09.2026)
   Konzept: "ZWEI RÄUME"

   Vollstaendiger Neubau. Die vorige Fassung ("Der Standpunkt") arbeitete
   mit Papiertoenen, einem Massstab und einer senkrechten Naht. Sie war
   praezise und zu kalt, zu leer, zu blass, und im Kern doch nur zwei
   Haelften nebeneinander. Sie ist verworfen, nicht ueberarbeitet.

   Die neue Idee ist keine Metapher, sondern eine Behauptung ueber Raum:

     Es gibt hier nicht eine Seite mit zwei Bereichen.
     Es gibt ZWEI RAEUME, und du stehst zwischen ihnen.

   Beide sind vom ersten Moment an vollflaechig da - kein Papier, keine
   Karten, keine Kacheln. Tinte links, Hausgruen rechts, getrennt von
   einem schraegen Schnitt quer durch den Schirm. Der Schnitt ist der
   Grund, warum das nicht wie zwei Haelften aussieht: eine Senkrechte
   teilt, eine Schraege spannt.

   Die Wortmarke liegt quer ueber dem Schnitt und gehoert dadurch
   sichtbar beiden Raeumen. Sie bewegt sich nie. Die Raeume dahinter
   schon: naeherst du dich einem, verschiebt sich der Schnitt und der
   Raum waechst. Dieselbe Aussage wie im alten Konzept - dein Standpunkt
   verschiebt sich, die Marke nicht - nur nicht mehr als Messgeraet
   erzaehlt, sondern als Raum.

   Technik: kein Framework, keine Drittanbieter-Verbindung, ein einziges
   kleines Skript fuer den Uebergang. Ohne JavaScript vollstaendig
   benutzbar.

   Reuse aus dem bestehenden System (nicht neu erfunden):
   - Hausgruen #0C8F5C und Fussgruen #0B4F38, identisch auf Seite A und B
   - Familjen Grotesk, selbst gehostet
   - Rechtstexte wortgleich von Seite B, soweit sie hier zutreffen
   ================================================================== */

/* =====================================================================
   SCHRIFT
   Selbst ausgeliefert. Kein Google Fonts, keine externe Verbindung -
   das ist hier kein Detail, sondern Teil des Versprechens in der
   Datenschutzerklaerung.
   Lizenz: SIL Open Font License 1.1, siehe assets/fonts/OFL.txt.
   ================================================================== */
@font-face{
  font-family: "Familjen Grotesk";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("assets/fonts/familjen-grotesk-latin.woff2") format("woff2");
}

/* =====================================================================
   TOKEN
   ================================================================== */
:root{
  /* DIE BEIDEN RAEUME — jeder Wert aus einer der Schwesterseiten.

     Das Portal hatte anfangs zwei Werte selbst gesetzt: eine fast
     neutrale Tinte (#101410) und ein erfundenes Signalgruen (#4BD79B).
     Beides fiel beim Vergleich mit den Fachseiten auf. Seither stammt
     jeder Wert nachweislich aus Seite A oder Seite B.

     Der linke Raum ist HELL, nicht dunkel. Das folgt einer
     ausdruecklichen Kundenkorrektur, die schon in CLAUDE.md steht:
     Seite A ist "weiss-gruen (nicht dunkel/schwarz)". Seite A haelt
     dafuer einen vollstaendigen Hell-Tokensatz bereit
     (:root[data-theme="light"]) - genau der wird hier benutzt.

       --weiss        Seite A hell, --bg
       --weiss-hoch   Seite A hell, --bg-band (angehobene Flaeche)
       --weiss-rein   Seite A hell, --bg-raised (aufliegende Flaeche)
       --gruen        Seite B, --green-deep (dort der Fussbereich)
       --gruen-hoch   Seite A hell, --accent-dim
       --gruen-hell   Seite A hell --accent, Seite B --green: der Anker
       --gruen-signal Seite A dunkel, --accent (nur auf gruener Flaeche) */
  --weiss:      #F4F7F5;
  --weiss-hoch: #EAF1EC;
  --weiss-rein: #FFFFFF;
  --gruen:      #0B4F38;
  --gruen-hoch: #0A6F48;
  --gruen-hell: #0C8F5C;
  --gruen-signal:#34E0A1;

  /* Schrift auf den Raeumen. Beide Flaechen sind dunkel, deshalb gibt es
     genau eine Textfarbe und zwei Abstufungen. */
  --hell:    #FFFFFF;
  --hell-2:  rgba(255,255,255,0.88);
  --hell-3:  rgba(255,255,255,0.62);
  --hell-4:  rgba(255,255,255,0.30);

  /* Leseseiten. Impressum und Datenschutz sind Dokumente, keine
     Markenflaechen - sie bleiben hell. Ein Rechtstext auf dunklem
     Grund ist eine Zumutung, kein Design.

     Sie nutzen dasselbe --weiss wie die Startseite. Eine erste Fassung
     hatte hier das waermere Papier von Seite B (#FBFAF7) stehen -
     gemessen ein anderer Ton als die #F4F7F5 der Startseite. Zwei
     Weisstoene auf drei Seiten derselben Website sind kein Detail,
     sondern ein Bruch. */
  --text:    #0A100C;                  /* Seite A hell, --text */
  --text-2:  rgba(10,16,12,0.68);      /* Seite A hell, --text-dim */
  --text-3:  rgba(10,16,12,0.48);      /* Seite A hell, --text-faint */
  --linie:   rgba(10,15,12,0.10);      /* Seite A hell, --line */

  /* Der schraege Schnitt. Zwei Werte, oben und unten - der Abstand
     zwischen ihnen ist die Neigung. 16 Prozentpunkte sind genug, dass
     man die Schraege sofort sieht, und wenig genug, dass beide Raeume
     eine ruhige Grundflaeche behalten. */
  --schnitt-oben:  59%;
  --schnitt-unten: 43%;

  --rand: clamp(22px, 4vw, 76px);

  /* MOTION-CHARAKTERISTIK
     Zwei Kurven, die sich absichtlich verschieden anfuehlen.
     --antwort  reagiert sofort und landet langsam. Fuer alles, was auf
                den Nutzer antwortet.
     --spannung beginnt kontrolliert und rastet ein. Fuer alles, was
                sich beim Eintritt SETZT.
     Beide enden exakt auf dem Zielwert - kein Ueberschwingen, kein
     Federn, kein elastisches Easing.

     Und der Kern: der TON reagiert schnell, der RAUM landet langsam.
     Waeren beide gleich lang, saehe die Reaktion wie ein Block aus. So
     wirkt sie wie eine Entscheidung, die sofort feststeht und sich
     danach im Raum durchsetzt. */
  --antwort:  cubic-bezier(0.16, 1, 0.30, 1);
  --spannung: cubic-bezier(0.62, 0, 0.16, 1);
  --t-ton:  320ms;
  --t-raum: 680ms;
  --t-kurz: 180ms;

  --font: "Familjen Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
}

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

html{
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
}

body{
  margin: 0;
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.5;
  /* Der Grundton der Seite ist Tinte, nicht Weiss. Waehrend des Ladens
     und beim Ueberscrollen sieht man deshalb nie eine weisse Blitzflaeche
     unter einer dunklen Seite. */
  background: var(--weiss);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

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

a{ color: inherit; }

h1, h2, p, ul{ margin: 0; }

/* Sichtbarer Fokus. Der Grundwert gilt auf hellem Grund - das Minzgruen
   der dunklen Fassung traegt dort nicht (rund 1,9:1 gegen Weiss). Auf
   der gruenen Flaeche wird weiter unten auf Weiss umgestellt. */
:focus-visible{
  outline: 3px solid var(--gruen-hell);
  outline-offset: 3px;
}

.sprung{
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 14px 20px;
  background: var(--gruen);
  color: var(--weiss-rein);
  font-weight: 600;
  text-decoration: none;
}
.sprung:focus{ left: 0; }

/* =====================================================================
   DAS KORN

   Feines Korn ueber der ganzen Seite. Auf zwei grossen, satten
   Farbflaechen ist das kein Effekt, sondern die Bedingung dafuer, dass
   sie nach Material aussehen und nicht nach zwei CSS-Rechtecken.

   Erzeugt, nicht geladen: eine SVG-Turbulenz als data-URI, 160x160
   gekachelt, rund 300 Byte, keine zusaetzliche Anfrage.
   "overlay" statt "multiply": so bleibt das Korn auf Tinte UND auf
   Gruen sichtbar und kippt die hellen Leseseiten nicht ins Graue.
   ================================================================== */
body::after{
  content: "";
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: 0.42;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='k'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23k)'/%3E%3C/svg%3E");
}

/* =====================================================================
   DAS PORTAL
   ================================================================== */
.portal{
  position: relative;
  /* svh statt vh: auf mobilen Browsern rechnet vh mit ausgeblendeter
     Adressleiste und schneidet dadurch unten ab. */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  overflow: hidden;   /* der Schnitt darf nichts nach aussen tragen */
}

/* ---------------------------------------------------------------
   DIE ZWEI RAEUME

   Beide liegen vollflaechig uebereinander und werden durch
   komplementaere clip-path-Polygone in zwei Keile geschnitten. Sie
   ergaenzen sich exakt: was der eine freilaesst, nimmt der andere.
   Deshalb gibt es keine Fuge, keine Linie, keinen Rand - der Schnitt
   ist die Kante zwischen zwei Farben und nicht ein Strich darauf.

   clip-path zwischen zwei Polygonen mit gleicher Punktzahl laesst sich
   sauber ueberblenden. Genau das ist die Bewegung dieser Seite.
   --------------------------------------------------------------- */
.raeume{
  position: relative;
  flex: 1 1 auto;
  margin: 0;
  padding: 0;
  list-style: none;
  min-height: clamp(460px, 74svh, 900px);
}

/* Die Listenpunkte sind vollflaechig und werden NICHT beschnitten - nur
   die Links darin. Ohne pointer-events: none liegt der zweite
   Listenpunkt als unsichtbare Vollflaeche ueber der ganzen Seite und
   schluckt jeden Zeiger: kein Hover, kein Klick auf den linken Raum.
   Der Beschnitt der Links wirkt auch auf die Trefferflaeche - jeder
   Zeiger landet dadurch exakt in dem Keil, den man auch sieht. */
.raeume > li{
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.raum{ pointer-events: auto; }

.raum{
  position: absolute;
  inset: 0;
  display: block;
  text-decoration: none;
  transition: background-color var(--t-ton) var(--antwort),
              clip-path var(--t-raum) var(--antwort);
}

/* Jeder Raum bringt seine eigenen drei Schriftstufen mit. Dadurch
   braucht keine einzige Textregel weiter unten eine Fallunterscheidung.

   Wichtig auf der hellen Flaeche: das Markengruen #0C8F5C traegt gegen
   #F4F7F5 nur 3,8:1. Das reicht fuer GROSSE Schrift (ab 3:1), nicht
   fuer Lesetext (4,5:1). Seite B haelt genau das seit jeher fest:
   "#0C8F5C - Flaechen und Linien, keine kleine Schrift". Der
   Bereichsname steht deshalb im Markengruen, alles Kleinere in der
   dunkleren Fassung #0A6F48 (5,8:1). Beides ist Markengruen, nur in
   zwei Abstufungen - wie auf beiden Fachseiten. */
.raum--pruefung{
  --schrift:   var(--gruen-hell);   /* 3,8:1 - nur der grosse Name */
  --schrift-2: var(--gruen-hoch);   /* 5,8:1 - Lesetext */
  --schrift-3: var(--gruen-hoch);
  background: var(--weiss);
  color: var(--schrift-2);
  clip-path: polygon(0 0, var(--schnitt-oben) 0, var(--schnitt-unten) 100%, 0 100%);
}
.raum--buchhaltung{
  --schrift:   var(--hell);
  --schrift-2: var(--hell-2);
  --schrift-3: var(--hell-3);
  background: var(--gruen);
  color: var(--schrift-2);
  clip-path: polygon(var(--schnitt-oben) 0, 100% 0, 100% 100%, var(--schnitt-unten) 100%);
}

/* ---------------------------------------------------------------
   DIE VERSCHIEBUNG

   Naeherst du dich einem Raum, wandert der Schnitt zur anderen Seite
   und der gewaehlte Raum waechst. Der andere tritt zurueck, bleibt aber
   immer vollstaendig sichtbar und lesbar - er behaelt rund ein Viertel
   des Schirms. Ein Raum, der fast verschwindet, waere ein Akkordeon,
   und man muesste seine Entscheidung erst zurueckbauen, um sie zu
   aendern.

   An :hover UND :focus-visible-within gebunden: die Tastatur bekommt
   exakt dieselbe Rueckmeldung wie die Maus.
   --------------------------------------------------------------- */
/* min-width mit in der Bedingung: ohne sie greifen diese Regeln auch
   auf schmalen Geraeten mit Zeiger und setzen dort den senkrechten
   Schnitt ueber den waagerechten der Mobilfassung. Gemessen auf 320 px:
   der Bereichsname lag dann zur Haelfte ausserhalb seines Raums. */
@media (hover: hover) and (pointer: fine) and (min-width: 901px){
  .raeume:has(.raum--pruefung:hover) .raum--pruefung{
    clip-path: polygon(0 0, 70% 0, 54% 100%, 0 100%);
    background: var(--weiss-hoch);
  }
  .raeume:has(.raum--pruefung:hover) .raum--buchhaltung{
    clip-path: polygon(70% 0, 100% 0, 100% 100%, 54% 100%);
  }
  .raeume:has(.raum--buchhaltung:hover) .raum--buchhaltung{
    clip-path: polygon(48% 0, 100% 0, 100% 100%, 32% 100%);
    background: var(--gruen-hoch);
  }
  .raeume:has(.raum--buchhaltung:hover) .raum--pruefung{
    clip-path: polygon(0 0, 48% 0, 32% 100%, 0 100%);
  }
}

/* Tastatur: dieselbe Rueckmeldung wie die Maus, auf jedem Geraet mit
   dieser Breite. Die Mobilfassung hat weiter unten ihre eigene. */
@media (min-width: 901px){
  .raeume:has(.raum--pruefung:focus-visible) .raum--pruefung{
    clip-path: polygon(0 0, 70% 0, 54% 100%, 0 100%);
    background: var(--weiss-hoch);
  }
  .raeume:has(.raum--pruefung:focus-visible) .raum--buchhaltung{
    clip-path: polygon(70% 0, 100% 0, 100% 100%, 54% 100%);
  }
  .raeume:has(.raum--buchhaltung:focus-visible) .raum--buchhaltung{
    clip-path: polygon(48% 0, 100% 0, 100% 100%, 32% 100%);
    background: var(--gruen-hoch);
  }
  .raeume:has(.raum--buchhaltung:focus-visible) .raum--pruefung{
    clip-path: polygon(0 0, 48% 0, 32% 100%, 0 100%);
  }
}

/* ---------------------------------------------------------------
   DER INHALT IN DEN RAEUMEN

   Die Ortungsfrage steht oben, der Bereichsname unten - und die beiden
   Raeume spiegeln sich: links linksbuendig, rechts rechtsbuendig. Das
   ist der zweite Grund, warum die Seite nicht wie zwei Haelften wirkt.
   Die Bloecke sitzen ausserdem in gegenueberliegenden Ecken und nicht
   auf gleicher Hoehe.

   Beide Bloecke bleiben innerhalb ihres Keils, auch wenn der Schnitt
   wandert - deshalb sind die Breiten begrenzt und nicht an den Schnitt
   gekoppelt.
   --------------------------------------------------------------- */
/* Die beiden Bloecke sitzen diagonal gegenueber, nicht auf gleicher
   Hoehe nebeneinander. Das ist der zweite Grund, warum die Seite nicht
   wie zwei Haelften wirkt - und zugleich die Loesung eines sehr
   praktischen Problems: der linke Keil ist OBEN breit, der rechte
   UNTEN. Ein langes Wort wie "Betriebspruefungen" passt deshalb links
   nur oben und rechts nur unten in eine Zeile.

   Die erste Fassung setzte beide Bloecke unten und liess das Wort in
   drei Silben brechen. Die Komposition folgt jetzt der Form des Keils
   statt gegen sie zu arbeiten. */
.raum-inhalt{
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.4vh, 18px);
}
.raum--pruefung .raum-inhalt{
  left: var(--rand);
  top: clamp(180px, 34svh, 330px);
  align-items: flex-start;
  text-align: left;
  /* Prozent, nicht ch. "ch" bemisst sich an der Schriftgroesse DIESES
     Containers - 17 px - und nicht am 68-px-Namen darin. Die erste
     Fassung stand deshalb faktisch auf rund 215 px, und der lange Name
     brach in drei Silben. */
  max-width: 40%;
}
.raum--buchhaltung .raum-inhalt{
  right: var(--rand);
  bottom: clamp(30px, 7vh, 84px);
  align-items: flex-end;
  text-align: right;
  max-width: 40%;
}

/* Die Ortungsfrage. Woertlich die "Claim-Uebersetzung" der jeweiligen
   Marke aus ZUMSANDE_BRAND_ARCHITECTURE.md - keine neue Copy. Sie sitzt
   in der oberen Ecke des jeweiligen Raums, moeglichst weit vom
   Bereichsnamen weg: zuerst verortet man sich, dann liest man, wo man
   landet. */
/* Die Ortungsfrage steht direkt ueber ihrem Bereichsnamen. In der
   ersten Fassung stand sie in der oberen Ecke des Raums und ist dort
   mit dem Claim kollidiert - zwei absolut gesetzte Bloecke, die sich
   dieselbe Hoehe teilen. Sie gehoert ohnehin zum Namen: erst verortet
   man sich, dann liest man, wo man landet. */
.raum-frage{
  font-size: clamp(15px, 0.88rem + 0.28vw, 20px);
  font-weight: 500;
  line-height: 1.35;
  color: var(--schrift-3);
  transition: color var(--t-ton) var(--antwort);
}

/* Groesse so gewaehlt, dass beide Namen an jeder Breite in EINE Zeile
   passen UND auch im zurueckgetretenen Zustand vollstaendig in ihrem
   Keil bleiben. Das zweite ist die schaerfere Bedingung: der Beschnitt
   reflowt nicht, er schneidet. Eine erste Fassung stand auf 68 px mit
   einem Versatz von 23 Prozentpunkten - beim Annaehern an den einen
   Raum wurde im anderen "Betriebspruefungen" zu "Betriebspruefu"
   abgeschnitten. Die QA misst das jetzt an jeder Breite und in jedem
   Zustand. */
.raum-name{
  color: var(--schrift);
  font-size: clamp(28px, 1.0rem + 2.5vw, 58px);
  font-weight: 700;
  line-height: 1.0;
  letter-spacing: -0.038em;
  hyphens: auto;
}

.raum-lage{
  font-size: clamp(15px, 0.9rem + 0.3vw, 21px);
  line-height: 1.45;
  color: var(--schrift-2);
}

/* Die Handlungszeile. Kein Knopf: der ganze Raum ist die Flaeche, ein
   Knopf darin waere ein zweites, konkurrierendes Ziel. */
.raum-los{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: clamp(4px, 1vh, 12px);
  font-size: clamp(15px, 0.9rem + 0.2vw, 19px);
  font-weight: 600;
  transition: gap var(--t-ton) var(--antwort),
              color var(--t-ton) var(--antwort);
}
.raum--pruefung .raum-los{ color: var(--gruen-hoch); }
.raum--buchhaltung .raum-los{ color: var(--hell); justify-content: flex-end; }

.raum-pfeil{ width: 30px; height: 9px; flex: none; overflow: visible; }
.raum-pfeil line, .raum-pfeil polyline{
  stroke: currentColor;
  stroke-width: 1.8;
  fill: none;
}
/* Beide Pfeile zeigen nach rechts, in die Richtung, in die es geht.
   Die erste Fassung hat den rechten gespiegelt, damit er zum
   rechtsbuendigen Satz passt - er zeigte damit vom Ziel weg. */

@media (hover: hover) and (pointer: fine){
  .raum:hover .raum-los{ gap: 20px; }
  .raum--buchhaltung:hover .raum-frage{ color: var(--hell-2); }
  .raum--pruefung:hover .raum-frage{ color: var(--gruen); }
}
.raum:focus-visible .raum-los{ gap: 20px; }

/* Der Fokusring nimmt die Gegenfarbe seines Raums - sonst verschwindet
   er auf einer der beiden Flaechen. */
.raum--pruefung:focus-visible{
  outline: 3px solid var(--gruen);
  outline-offset: -8px;
}
.raum--buchhaltung:focus-visible{
  outline: 3px solid var(--hell);
  outline-offset: -8px;
}

/* ---------------------------------------------------------------
   DIE MARKE UEBER DEM SCHNITT

   Die Wortmarke liegt quer ueber der Kante und gehoert dadurch
   sichtbar beiden Raeumen. Sie ist die weisse Freigabefassung des
   gelieferten Assets - eine reine Farbvariante, alphagleich mit dem
   Original. Weiss traegt auf Tinte wie auf Gruen, deshalb braucht es
   keine zweite Datei und keinen einzigen Eingriff in die Datei.

   Sie liegt UEBER den Raeumen und laesst Klicks durch
   (pointer-events: none) - sonst waere die Mitte des Schirms tot.

   Und sie bewegt sich nie. Die Raeume verschieben sich dahinter. Das
   ist dieselbe Aussage wie im verworfenen Konzept, nur ohne Messgeraet:
   dein Standpunkt aendert sich, die Marke nicht.
   --------------------------------------------------------------- */
/* Die Marke traegt ausdruecklich die Flaeche des hellen Raums als
   eigenen Hintergrund. Sichtbar aendert das nichts - sie liegt immer
   vollstaendig auf dieser Flaeche (dafuer sorgt die Breitenformel bei
   .marke-bild). Es macht aber den Untergrund fuer Pruefwerkzeuge
   aufloesbar: axe und Lighthouse werten clip-path nicht aus, sehen
   beide Raeume als vollflaechige Boxen und ermittelten fuer den Claim
   den gruenen Raum als Hintergrund - gemeldet als 1,54:1, tatsaechlich
   5,76:1. Ein eigener Hintergrund beendet das Raten. */
.marke{
  position: absolute;
  left: var(--rand);
  top: clamp(30px, 6vh, 74px);
  z-index: 20;
  pointer-events: none;
  background: var(--weiss);
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.4vh, 18px);
}

/* Obergrenze 570 px - die native Breite der gelieferten Datei.

   Der Entwurf hatte die Wortmarke zunaechst bis 815 px gezogen, damit
   sie den Schnitt ueberquert und dadurch sichtbar beiden Raeumen
   gehoert. Das ging nur durch Hochskalieren: Lighthouse hat die
   Wortmarke mit 763 px Anzeigebreite gegen 570 px Dateibreite
   gemeldet, und auf einem Retina-Schirm waere sie sichtbar weich.

   Ein Logo hochzurechnen ist keine Skalierung mehr, sondern eine
   Verschlechterung des Markenassets - und die groesste im System
   vorhandene Fassung IST diese Datei. Eine Vektorquelle existiert
   nirgends; sie steht bereits als offener Punkt im Brand-Closeout.

   Bis sie vorliegt, laeuft die Marke in Originalgroesse. Sie sitzt
   dadurch vollstaendig im linken Raum statt auf der Kante. Das ist der
   sichtbare Preis eines fehlenden Assets, keine Gestaltungsentscheidung
   - mit einer SVG-Fassung waere die urspruengliche Absicht in einer
   Zeile wiederhergestellt. */
.marke-bild{
  width: min(570px, 62vw);
  height: auto;
}

/* Zwischen 901 und rund 1090 px lief die Wortmarke in den gruenen Raum
   hinein - gemessen bis zu 79 px. Dort steht Markengruen auf Hausgruen
   und traegt 2,3:1, der ueberstehende Teil war praktisch unsichtbar.
   1024 px ist eine der haeufigsten Breiten ueberhaupt.

   Die Breite haengt deshalb ab jetzt am Schnitt selbst: 59vw ist seine
   Lage am oberen Rand, davon gehen der Seitenrand und 60 px Luft ab.
   Ueber rund 1090 px greift wieder die Obergrenze von 570 px, der
   nativen Breite der Datei - hochskaliert wird nie.

   Nur ab 901 px: darunter liegt der Schnitt waagerecht, dort gibt es
   keine senkrechte Kante, die die Marke schneiden koennte. */
@media (min-width: 901px){
  .marke-bild{
    width: min(570px, calc(59vw - var(--rand) - 60px));
  }
}

/* Der Claim, genau einmal sichtbar auf dieser Website. Er wird im
   Fussbereich NICHT wiederholt: er ist eine Unterschrift, kein
   Argument (ZUMSANDE_BRAND_ARCHITECTURE.md). Und er ist bewusst kein
   H2 - er ist Markensprache, keine Gliederung. */
/* Der Claim steht ueber dem hellen Raum, also in der dunkleren
   Markengruen-Fassung. */
.claim{
  font-size: clamp(16px, 0.95rem + 0.5vw, 26px);
  font-weight: 400;
  line-height: 1.35;
  color: var(--gruen-hoch);
}

/* =====================================================================
   DER EINTRITT

   Die Seite faellt nicht fertig herein. Der Schnitt oeffnet sie:

     1. Tinte steht.
     2. Der gruene Raum faehrt an der Schraege auf - der Schnitt
        entsteht als Bewegung, nicht als fertige Kante.
     3. Die Marke setzt sich darueber.
     4. Die Inhalte beider Raeume treten an.
     5. Der Claim schliesst ab.

   Nach 1000 ms ist alles vorbei und nie wieder zu sehen. Kein
   Vorschaltbild, nichts wegzuklicken, keine Sperre.

   Der ganze Block haengt an (prefers-reduced-motion: no-preference).
   Wer Bewegungsarmut eingestellt hat, bekommt die fertige Seite - ohne
   fehlenden Inhalt, denn nichts hier versteckt etwas.
   ================================================================== */
@media (prefers-reduced-motion: no-preference){
  /* "backwards" statt "both", und der Keyframe hat nur ein "from".

     Mit "both" haelt die Animation ihren Endwert dauerhaft fest - und
     Animationen schlagen normale Deklarationen im Cascade. Der
     Endwert war der Desktop-Beschnitt, und damit hatte die Media
     Query fuer Mobil keine Chance: auf 390 stand weiter der
     senkrechte Schnitt. Ohne "to" endet die Animation auf dem
     eigenen Wert des Elements - und der ist je nach Breite ein
     anderer. */
  .raum--buchhaltung{
    animation: raum-auf-quer 0.62s var(--spannung) 0.05s backwards;
  }
  .marke-bild{
    animation: setzen 0.46s var(--antwort) 0.30s both;
  }
  .raum--pruefung .raum-inhalt,
  .raum--pruefung .raum-frage{
    animation: antreten 0.46s var(--antwort) 0.44s both;
  }
  .raum--buchhaltung .raum-inhalt,
  .raum--buchhaltung .raum-frage{
    animation: antreten 0.46s var(--antwort) 0.52s both;
  }
  .claim{
    animation: setzen 0.34s var(--antwort) 0.66s both;
  }
}

/* Der gruene Raum faehrt auf und zieht den Schnitt hinter sich her -
   auf dem Desktop aus der rechten Kante, auf Mobil aus der unteren.
   Beide Keyframes haben bewusst nur ein "from": das Ziel ist immer der
   Ruhewert des Elements, und der haengt von der Breite ab. */
@keyframes raum-auf-quer{
  from{ clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%); }
}
@keyframes raum-auf-hoch{
  from{ clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%); }
}
@keyframes setzen{
  from{ opacity: 0; transform: translateY(-10px); }
  to{   opacity: 1; transform: none; }
}
@keyframes antreten{
  from{ opacity: 0; transform: translateY(14px); }
  to{   opacity: 1; transform: none; }
}

/* =====================================================================
   DER EINTRITT IN EINEN RAUM

   Der Gegenzug: beim Klick uebernimmt der gewaehlte Raum den ganzen
   Schirm, die Marke tritt zurueck, und erst dann wird navigiert. Aus
   "ich habe einen Link geklickt" wird "ich bin da hineingegangen".

   Es ist dieselbe Mechanik wie beim Annaehern, nur zu Ende gefuehrt -
   kein zweiter Effekt, keine Ueberblendung.
   ================================================================== */
.geht-hinein .raum{ transition-duration: 480ms; }
.geht-hinein .raum--pruefung.ist-ziel{
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  background: var(--weiss-hoch);
}
.geht-hinein .raum--buchhaltung.ist-ziel{
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  background: var(--gruen-hoch);
}
.geht-hinein .marke{
  opacity: 0;
  transform: translateY(-14px);
  transition: opacity 300ms var(--antwort), transform 420ms var(--antwort);
}
/* Waehrend des Uebergangs nimmt die Seite keine weiteren Klicks an. */
.geht-hinein .raeume{ pointer-events: none; }

/* Ein Einzelbild ohne jeden Uebergang. Wird nur beim Zurueckkehren aus
   dem bfcache gesetzt und im naechsten Bild wieder entfernt - siehe die
   Begruendung im Skript am Ende von index.html. */
.ohne-uebergang,
.ohne-uebergang *,
.ohne-uebergang *::before,
.ohne-uebergang *::after{
  transition: none !important;
  animation: none !important;
}

/* =====================================================================
   FUSSBEREICH
   Sehr reduziert. Keine Linkwand, kein SEO-Text. Der Claim wird hier
   NICHT wiederholt.
   ================================================================== */
/* Hausgruen, nicht Tinte. Nachdem der linke Raum hell geworden ist,
   waere eine dunkle Fusszeile die einzige schwarze Flaeche der ganzen
   Seite - ein Rest, kein Element. Gruen setzt stattdessen einen Sockel
   unter beide Raeume und traegt die weisse Wortmarke mit. */
.fuss{
  position: relative;
  z-index: 30;
  background: var(--gruen);
  border-top: 1px solid rgba(255,255,255,0.14);
}
.fuss-inner{
  padding: clamp(22px, 3.4vh, 40px)
           max(var(--rand), env(safe-area-inset-right, 0px))
           max(clamp(24px, 4vh, 44px), env(safe-area-inset-bottom, 0px))
           max(var(--rand), env(safe-area-inset-left, 0px));
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: clamp(14px, 2.2vw, 40px);
}
.fuss-marke{
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--hell);
}
.fuss-nav{
  display: flex;
  flex-wrap: wrap;
  gap: clamp(14px, 1.8vw, 30px);
  margin-left: auto;
}
.fuss-nav a{
  display: inline-block;
  padding: 11px 0;
  font-size: 15px;
  color: var(--hell-2);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(255,255,255,0.28);
  text-underline-offset: 4px;
  transition: text-decoration-color var(--t-kurz) var(--antwort),
              color var(--t-kurz) var(--antwort);
}
.fuss-nav a:hover{ color: var(--hell); text-decoration-color: var(--gruen-signal); }

.fuss-traeger{
  flex-basis: 100%;
  margin: 0;
  font-size: 15px;
  color: var(--hell-3);
}

/* Die Signatur der Agentur. Steht wortgleich im Fussbereich von Seite A
   und Seite B - drei Seiten derselben Marke, dieselbe Handschrift
   darunter. */
.fuss-credit{
  flex-basis: 100%;
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--hell-3);
}
.fuss-credit a{
  display: inline-block;
  padding: 12px 0;
  color: var(--gruen-signal);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(52,224,161,0.42);
  text-underline-offset: 4px;
}
.fuss-credit a:hover{ text-decoration-color: var(--gruen-signal); }

/* =====================================================================
   DAS EINWILLIGUNGSBANNER

   Bewusst hell auf der dunklen Seite. Es ist keine Gestaltungsflaeche,
   sondern Systemebene - es soll sich sichtbar von der Komposition
   abheben und nicht als dritter Raum missverstanden werden. Der
   Nebeneffekt ist der wichtigere: auf Papier ist der Kontrast beider
   Schaltflaechen garantiert, unabhaengig davon, welcher Raum gerade
   darunter liegt.

   Beide Schaltflaechen sind gleich gross, gleich hoch und stehen
   nebeneinander. Ablehnen darf nicht schwerer sein als Zustimmen -
   weder optisch noch in der Tabreihenfolge.
   ================================================================== */
.consent{
  position: fixed;
  z-index: 80;
  left: max(16px, env(safe-area-inset-left, 0px));
  right: max(16px, env(safe-area-inset-right, 0px));
  bottom: max(16px, env(safe-area-inset-bottom, 0px));
  max-width: 620px;
  padding: clamp(18px, 2.4vw, 26px);
  /* Reines Weiss plus gruene Kante. Auf der hellen Flaeche des linken
     Raums traegt ein Schatten allein nicht mehr - der Dialog braucht
     eine gezeichnete Kante, um als aufliegende Ebene lesbar zu bleiben.
     Auf der gruenen Flaeche wirkt beides zusammen. */
  background: var(--weiss-rein);
  color: var(--text);
  border: 2px solid var(--gruen);
  border-radius: 2px;
  box-shadow: 0 2px 6px rgba(10,15,12,0.16), 0 18px 50px rgba(10,15,12,0.24);
}
.consent[hidden]{ display: none; }
.consent:focus{ outline: none; }
.consent:focus-visible{ outline: 3px solid var(--gruen-hell); outline-offset: 3px; }

.consent-titel{
  font-size: clamp(17px, 1rem + 0.3vw, 21px);
  font-weight: 700;
  letter-spacing: -0.015em;
  margin-bottom: 8px;
}
.consent-text{
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-2);
  margin-bottom: 18px;
}
/* inline-block plus Polsterung: als reiner Inline-Link war die
   Trefferflaeche 151 x 20 px und damit unter den 24 px, die WCAG 2.2
   als Mindestgroesse verlangt. Gemessen auf 390 px. */
.consent-text a{
  display: inline-block;
  padding: 4px 0;
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--gruen-hell);
  text-underline-offset: 3px;
}

.consent-knoepfe{
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
/* "1 1 0", nicht "1 1 auto": bei "auto" bemisst sich die Breite am
   Inhalt, und "Einverstanden" ist nun einmal laenger als "Nein danke" -
   gemessen 289 px gegen 267 px. Ein Zustimmen-Knopf, der breiter ist
   als der Ablehnen-Knopf, ist ein Dark Pattern, auch ein unbeabsichtigtes.
   Mit Basis 0 teilen sich beide den Platz exakt gleich. */
.consent-knopf{
  flex: 1 1 0;
  min-width: 150px;
  min-height: 48px;
  padding: 13px 20px;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  background: transparent;
  border: 2px solid rgba(10,15,12,0.22);
  border-radius: 2px;
  cursor: pointer;
  transition: border-color var(--t-kurz) var(--antwort),
              background-color var(--t-kurz) var(--antwort);
}
.consent-knopf:hover{ border-color: var(--gruen); }
.consent-knopf--ja{
  background: var(--gruen);
  border-color: var(--gruen);
  color: var(--hell);
}
.consent-knopf--ja:hover{ background: var(--gruen-hoch); border-color: var(--gruen-hoch); }
.consent-knopf:focus-visible{ outline: 3px solid var(--gruen-hell); outline-offset: 2px; }

/* Der Widerruf. Steht in der Fusszeile jeder Seite - eine erteilte
   Einwilligung muss genauso leicht zuruecknehmbar sein, wie sie
   gegeben wurde. Ohne konfigurierte Messkennung entfernt ihn das
   Skript. */
#consentWieder{ cursor: pointer; }

/* =====================================================================
   MOBIL — 390 FIRST

   Die beiden Raeume werden nicht nebeneinander gequetscht. Die Achse
   kippt: aus dem senkrechten Schnitt wird ein waagerechter, die Raeume
   liegen uebereinander, und die Schraege bleibt - sie ist die Idee.

   Beide Raeume stehen vollstaendig im ersten Blick, ohne Scrollen.
   ================================================================== */
@media (max-width: 900px){
  .raeume{ min-height: 0; }

  .raum--pruefung{
    clip-path: polygon(0 0, 100% 0, 100% 54%, 0 46%);
  }
  .raum--buchhaltung{
    clip-path: polygon(0 46%, 100% 54%, 100% 100%, 0 100%);
  }

  /* Der aktive Zustand auf derselben Achse - fuer Tastatur und fuer
     die seltenen schmalen Geraete mit Zeiger. Der Versatz ist kleiner
     als auf dem Desktop: die Raeume sind hier flacher, und der Text
     muss auch im zurueckgetretenen Raum vollstaendig stehen bleiben. */
  .raeume:has(.raum--pruefung:focus-visible) .raum--pruefung,
  .raeume:has(.raum--pruefung:hover) .raum--pruefung{
    clip-path: polygon(0 0, 100% 0, 100% 59%, 0 51%);
    background: var(--weiss-hoch);
  }
  .raeume:has(.raum--pruefung:focus-visible) .raum--buchhaltung,
  .raeume:has(.raum--pruefung:hover) .raum--buchhaltung{
    clip-path: polygon(0 51%, 100% 59%, 100% 100%, 0 100%);
  }
  .raeume:has(.raum--buchhaltung:focus-visible) .raum--buchhaltung,
  .raeume:has(.raum--buchhaltung:hover) .raum--buchhaltung{
    clip-path: polygon(0 41%, 100% 49%, 100% 100%, 0 100%);
    background: var(--gruen-hoch);
  }
  .raeume:has(.raum--buchhaltung:focus-visible) .raum--pruefung,
  .raeume:has(.raum--buchhaltung:hover) .raum--pruefung{
    clip-path: polygon(0 0, 100% 0, 100% 49%, 0 41%);
  }

  /* Die Inhalte teilen sich jetzt oben und unten statt links und
     rechts. Die Spiegelung bleibt: der obere Raum linksbuendig, der
     untere rechtsbuendig. */
  /* Hoeher als in der ersten Fassung. Der obere Raum endet auf Mobil
     bei rund 47 % der Hoehe - stand der Block auf 25svh, rutschte seine
     letzte Zeile unter die Schraege und wurde abgeschnitten. Gemessen
     auf 768 px. */
  .raum--pruefung .raum-inhalt{
    left: var(--rand);
    right: var(--rand);
    bottom: auto;
    /* Gekoppelt an die tatsaechliche Hoehe der Marke statt an einen
       festen Wert: die Wortmarke skaliert mit der Breite (56.5vw bei
       einem Seitenverhaeltnis von 570:84, also rund 8.3vw hoch), der
       Claim mit der Hoehe. Ein fester Wert passte deshalb immer nur
       auf einer Breite - auf 768 standen Claim und Frage 9 px
       auseinander. */
    top: calc(clamp(30px, 6vh, 74px) + 8.4vw + clamp(48px, 6.8vh, 82px));
    max-width: none;
  }
  .raum--buchhaltung .raum-inhalt{
    left: var(--rand);
    right: var(--rand);
    bottom: clamp(26px, 5vh, 62px);
    max-width: none;
  }

  /* Der Eintritt kippt mit: der gruene Raum faehrt jetzt von unten auf,
     nicht von rechts. */
  .raum--buchhaltung{ animation-name: raum-auf-hoch; }

  .fuss-nav{ margin-left: 0; }
}

/* Sehr schmal und 200 % Zoom. Hier wird nur der Rhythmus enger
   gestellt - nichts steht auf nowrap, es kann also nichts ueberlaufen. */
@media (max-width: 380px){
  .raum-name{ letter-spacing: -0.024em; }
  .fuss-inner{ gap: 12px; }
}

/* =====================================================================
   BEWEGUNGSARMUT
   Wer reduzierte Bewegung eingestellt hat, bekommt keine. Die Seite
   verliert dadurch nichts: alles ist im Ruhezustand vollstaendig da.
   Der Farbwechsel bleibt - er ist die Rueckmeldung, nicht die Bewegung.
   ================================================================== */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* =====================================================================
   LESESEITEN
   Impressum und Datenschutz sind Dokumente, keine Markenflaechen. Sie
   teilen die Marke, aber nicht das Portallayout - ein Rechtstext auf
   schwarzem Grund ist eine Zumutung, kein Design.

   Der Kopfbalken traegt das Hausgruen, damit man sieht, wo man ist -
   und damit die weisse Wortmarke darauf steht wie im Fussbereich.
   ================================================================== */
.recht-kopf{
  background: var(--gruen);
  padding: clamp(22px, 4vh, 44px) var(--rand);
}
.recht-kopf .marke-bild{ width: clamp(180px, 26vw, 300px); }

.recht{
  background: var(--weiss);
  color: var(--text);
}
.recht-inner{
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(30px, 5vh, 68px) var(--rand) clamp(56px, 9vh, 108px);
}
.recht-zurueck{
  display: inline-block;
  margin-bottom: clamp(20px, 3vh, 34px);
  padding: 11px 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-2);
  text-decoration: underline;
  text-decoration-color: var(--linie);
  text-underline-offset: 4px;
}
.recht-zurueck:hover{ color: var(--text); text-decoration-color: var(--gruen-hell); }

.recht h1{
  font-size: clamp(32px, 1.6rem + 2.2vw, 54px);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin-bottom: 10px;
}
.recht-lead{
  font-size: clamp(17px, 1rem + 0.4vw, 21px);
  color: var(--text-2);
  margin-bottom: clamp(26px, 4vh, 44px);
}
.recht h2{
  font-size: clamp(19px, 1.05rem + 0.5vw, 25px);
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: clamp(30px, 4.4vh, 48px) 0 10px;
}
.recht p, .recht li{
  font-size: 17px;
  line-height: 1.62;
  color: var(--text-2);
  margin-bottom: 14px;
}
.recht a{
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--gruen-hell);
  text-underline-offset: 3px;
}
.recht strong{ color: var(--text); }

