/* Ergänzungen zu sysfacts-a.css für Website Hauptseiten v3 */
.markx{position:absolute;right:-70px;bottom:-90px;width:300px;opacity:.08;pointer-events:none}
.pl-foot{position:relative;height:3px;margin:0 60px}
.pl-foot .tr{position:absolute;left:0;right:0;top:1px;height:.5px;background:var(--line)}
.pl-foot .sg{position:absolute;left:34%;width:32%;top:0;height:3px;background:var(--accent);transform-origin:left;animation:pl-grow 2.4s cubic-bezier(.4,0,.2,1) both}
.pl-foot .ct{position:absolute;left:66%;top:-3.5px;width:9px;height:9px;border-radius:50%;background:var(--paper);animation:pl-pulse 3.2s ease-in-out 2.4s infinite}
@supports (animation-timeline: view()) {
  .pl-foot .sg{animation:pl-grow linear both;animation-timeline:view();animation-range:cover 0% cover 45%}
}
@keyframes pl-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes pl-pulse{0%,100%{box-shadow:0 0 0 0 rgba(147,177,166,.4)}50%{box-shadow:0 0 0 7px rgba(147,177,166,0)}}
/* Kundenlogoband. Die Logos sitzen auf hellen Papier-Kacheln und behalten ihre
   echten Markenfarben. Die frühere Aufhellung per grayscale+invert+screen ist
   an mehrfarbigen Logos gescheitert: Hanebutt wurde zum weißen Klumpen, der
   ausgesparte IHK-Schriftzug verschwand ganz. Eine Kachel funktioniert
   unabhängig davon, welches Logo darauf liegt. */
/* Logos ohne Kacheln, dafuer auf hellem Grund. Die Kacheln waren noetig,
   solange das Band auf Abyss stand: Gemessen liegen neun der zehn Logos
   zwischen 49 und 145 von 255 Helligkeit, sie waeren dort untergegangen. Auf
   Mist tragen sie sich selbst und behalten ihre Markenfarben.
   Auf allen drei Seiten mit Logoband folgt darunter ohnehin eine helle
   Sektion, das Band fuegt sich also ein. */
/* Logos ohne Kacheln. Damit sie sich trotzdem absetzen, traegt das ganze Band
   Weiss statt Mist: Die Logos sind ueberwiegend dunkel (gemessen 50 bis 160 von
   255), auf Weiss gewinnen sie den maximal moeglichen Kontrast, ohne dass eine
   Kachel um jedes einzelne noetig waere. Zwischen der dunklen Kette darueber
   und der Mist-Sektion darunter steht das Band damit als eigene Flaeche.

   Einfarbig setzen waere der staerkere Hebel, faellt aber aus: Modefachschule,
   Bundesregierung und Zwilling bestehen zu 18 bis 24 Prozent aus weissen
   Aussparungen, die dabei verschwinden wuerden. Genau daran ist schon die
   frueherere Aufhellung gescheitert. */
.logoband.plain{display:block;background:var(--sf-white);border-top:.5px solid var(--line-ink);border-bottom:.5px solid var(--line-ink);padding-block:36px 38px;gap:0}
.logoband.plain .lbl{display:block;text-align:center;max-width:none;font-size:10px;letter-spacing:.12em;color:var(--acc-ink);margin:0 0 26px;line-height:1.4}
.logoband.plain .logos{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px}
.logoband.plain .ls{height:80px;background:none;border-radius:0;display:flex;align-items:center;justify-content:center;padding:0 16px;opacity:1}
/* 48px: Die Quellen tragen 52 bis 63px scharf, das laesst Reserve. */
.logoband.plain .ls img{max-height:48px;max-width:100%;object-fit:contain;filter:none;mix-blend-mode:normal}
/* Ausnahme: schnittger.png ist nur 90x32 gross und damit schon bei 34px
   zweifach hochskaliert. Groesser wuerde es endgueltig matschig. Eine hoeher
   aufgeloeste Datei waere die eigentliche Loesung. */
.logoband.plain .ls img[src*="schnittger"]{max-height:34px}
/* Aufzählung der Einstiege in den Angebotskarten.
   Der Marker ist ein 4px-Punkt in der Textfarbe der Karte, nicht in Sage: Die
   Karten stehen mal auf Tiefgrün, mal auf Papier, ein fester Wert würde auf
   einer der beiden Flächen untergehen. currentColor folgt der Karte. */
.offerlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.offerlist li{position:relative;padding-left:15px}
.offerlist li::before{content:"";position:absolute;left:0;top:.52em;width:4px;height:4px;border-radius:50%;background:currentColor;opacity:.7}
.stage .offer .offerlist{font-size:13.5px;line-height:1.5}
.pricecard .offerlist{font-size:13px;line-height:1.5}

/* Hero-Kreiscluster (Logo-Formation) */
.circlecluster{align-self:start;overflow:hidden}
.circlecluster .in{display:grid;grid-template-columns:160px 160px;gap:12px;margin-top:-56px}
/* Im hellen Hero traegt der Cluster das Bildmotiv und sitzt mittig. Der
   Hochzug von -56px stammt aus dem alten dunklen Hero, der oben ausgerichtet
   war; hier stehen beide Spalten auf Mitte. */
/* 200px je Kreis: Die Quellen sind 536x536, bei 400px Export bleibt das auf
   Retina scharf. Spalte 412 = 2x200 plus 12 Abstand. */
/* Doppelte Klasse noetig: .circlecluster img steht weiter unten in dieser
   Datei und gewinnt sonst bei gleicher Spezifitaet ueber die Reihenfolge. */
.circlecluster.herokreise{align-self:center;justify-self:center;width:412px}
.circlecluster.herokreise .in{grid-template-columns:200px 200px}
.circlecluster.herokreise img{width:200px;height:200px}
.herokreise .in{margin-top:0}
.circlecluster img{width:160px;height:160px;border-radius:50%;object-fit:cover;display:block}
/* Mit dem Logo mitgewachsen: 24 auf 30px Logohoehe, Zeile 10.5 auf 12px.
   Das Verhaeltnis der beiden zueinander bleibt damit gleich. */
.navdesc{font-family:var(--font-ui);font-size:12px;letter-spacing:-.1px;color:var(--accent)}
.lp .prinrow{grid-template-columns:280px 1fr;gap:40px}
/* Dunkles Zwischenband statt Mist. Ohne das liefen Sektion 01, die Bruecke
   und Sektion 02 als drei gleiche Mist-Flaechen ineinander — die Bruecke las
   sich als Trenner innerhalb eines Abschnitts statt zwischen zweien. Ab
   Sektion 03 wechselt die Seite ohnehin hell/dunkel; das Band stellt diesen
   Rhythmus auch am Anfang her. */
/* Als Naht statt als Block: 18px Innenrand ergeben 66px statt 144px. */
.sectbridge{display:flex;align-items:center;justify-content:center;gap:22px;padding:18px 60px;background:var(--deep);color:var(--paper);margin:-1px 0;position:relative;z-index:1}

/* UMSCHLAG STATT FORTSCHRITTSLINIE

   Die Naht trug bis hierher dasselbe Motiv wie die Leiste vor dem Footer. Auf
   einer Seite zweimal dieselbe Fortschrittslinie nutzt das Leitmotiv ab; die
   zweite liest sich als Wiederholung, nicht als Aussage. Der Umschlag sagt an
   dieser Stelle ausserdem das Richtige: Er ist der Zustandswechsel im
   Markenzeichen selbst, und genau das leistet eine Naht zwischen zwei
   Sektionen.

   Das Manual erlaubt eine Sequenz je Flaeche. Die Unternehmensseite hatte
   bisher keine, anders als die fuenf uebrigen Seiten.

   Die Bewegung ist der Umschlag selbst, kein Blinken: Alle vier Halbkreise
   stehen zunaechst oben offen, beim Scrollen kippen die hinteren beiden nach
   unten. Der Wechsel sitzt zwischen dem zweiten und dritten, also in der
   Mitte, nicht am Ende — dieselbe Regel wie beim Punkt der Linie (Manual
   Seite 08). Der letzte Halbkreis ist der einzige Sage-Ton der Flaeche.

   Das Zeichen daneben entfaellt: Die Sequenz besteht bereits aus dem
   Markenzeichen, beides nebeneinander waere die Marke doppelt. */
.sectbridge .flipseq{display:flex;gap:10px;align-items:center}
.sectbridge .flipseq i{display:block;width:30px;height:15px;background:var(--paper);border-radius:999px 999px 0 0;opacity:0;
  animation:um-auf .5s linear both}
.sectbridge .flipseq i:nth-child(1){--o:.25;animation-delay:0s}
.sectbridge .flipseq i:nth-child(2){--o:.45;animation-delay:.12s}
.sectbridge .flipseq i:nth-child(3){--o:.7;animation:um-auf .5s linear .24s both,um-kipp .45s cubic-bezier(.4,0,.2,1) .62s both}
.sectbridge .flipseq i:nth-child(4){--o:1;background:var(--accent);animation:um-auf .5s linear .36s both,um-kipp .45s cubic-bezier(.4,0,.2,1) .82s both}
@keyframes um-auf{from{opacity:0}to{opacity:var(--o)}}
@keyframes um-kipp{from{transform:rotate(0)}to{transform:rotate(180deg)}}
/* WIEDER EINGESETZT: sb-dot ist beim Umbau der Naht auf das Umschlag-Motiv
   mitgeloescht worden, weil die Keyframes im selben Block standen. Seitdem
   liefen der Sage-Zielpunkt der Toleranzskala auf der Unternehmensseite
   (.tolziel) und spaeter der Punkt der Technikbruecke ins Leere: Eine
   Animation mit unbekanntem Namen wird stillschweigend verworfen. */
@keyframes sb-dot{from{opacity:0;transform:scale(.4)}to{opacity:1;transform:scale(1)}}
@supports (animation-timeline: view()) {
  .sectbridge .flipseq i{animation:um-auf linear both;animation-timeline:view();animation-range:cover 14% cover 30%}
  .sectbridge .flipseq i:nth-child(2){animation:um-auf linear both;animation-timeline:view();animation-range:cover 18% cover 34%}
  .sectbridge .flipseq i:nth-child(3){animation:um-auf linear both,um-kipp linear both;animation-timeline:view(),view();animation-range:cover 22% cover 38%,cover 40% cover 52%}
  .sectbridge .flipseq i:nth-child(4){animation:um-auf linear both,um-kipp linear both;animation-timeline:view(),view();animation-range:cover 26% cover 42%,cover 50% cover 62%}
}
.sectbridge span{font-family:var(--font-mono);font-weight:500;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
/* STATEMENT: UMSCHLAG UND RINGE BEIM SCROLLEN

   Der Bereich stand bisher fertig da. Beide Motive tragen aber eine Bewegung
   in sich: Der Umschlag ist der Zustandswechsel, die Ringe sind der Radius um
   einen Mittelpunkt. Beide laufen deshalb an einer gemeinsamen Zeitachse
   --stmt, damit sie eine Sequenz ergeben und nicht drei nebeneinander.

   Reihenfolge: Erst ziehen die Ringe von innen nach aussen auf, dann blenden
   die vier Halbkreise nacheinander ein, zuletzt kippen die hinteren beiden.
   Der Endzustand ist die bisherige Gestaltung, unveraendert.

   .statement stand auf overflow:hidden. Das erzeugt einen Scrollcontainer,
   und die Zeitachsen der Kinder haetten sich darauf bezogen statt auf das
   Fenster — sie waeren nie gelaufen. overflow:clip beschneidet die Ringe
   genauso, ohne diesen Nebeneffekt. */
.statement{overflow:clip;view-timeline-name:--stmt}

.statement .flipseq{position:relative;display:flex;gap:8px;align-items:center;justify-content:center;margin-bottom:26px}
/* Alle vier stehen zunaechst oben offen; die hinteren beiden kippen. Der
   Endzustand ist derselbe wie zuvor, nur ueber eine Drehung erreicht. */
.statement .flipseq i{display:block;width:26px;height:13px;background:var(--paper);border-radius:999px 999px 0 0;opacity:0;
  animation:um-auf .5s linear both}
.statement .flipseq i:nth-child(1){--o:.25;animation-delay:.5s}
.statement .flipseq i:nth-child(2){--o:.45;animation-delay:.62s}
.statement .flipseq i:nth-child(3){--o:.7;animation:um-auf .5s linear .74s both,um-kipp .45s cubic-bezier(.4,0,.2,1) 1.12s both}
.statement .flipseq i:nth-child(4){--o:1;background:var(--accent);animation:um-auf .5s linear .86s both,um-kipp .45s cubic-bezier(.4,0,.2,1) 1.32s both}

/* Die Ringe wachsen aus dem Mittelpunkt heraus, innen zuerst. Die
   Verschiebung um die halbe Breite muss in jedem Bild stehen, sonst springt
   der Ring aus der Mitte. */
.ringdeco i{opacity:0;animation:ring-auf .9s cubic-bezier(.4,0,.2,1) both}
.ringdeco i:nth-child(1){animation-delay:0s}
.ringdeco i:nth-child(2){animation-delay:.14s}
.ringdeco i:nth-child(3){animation-delay:.28s}
@keyframes ring-auf{from{opacity:0;transform:translate(-50%,-50%) scale(.82)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}

/* ENTRY STATT COVER, WEIL SONST ZWEI SEITEN NIE FERTIG WERDEN

   cover setzt voraus, dass der Bereich einmal ganz durchs Bild wandert. Auf
   Kontakt und Erstgespraech steht das Statement aber 94px vor dem Seitenende:
   Dort sind hoechstens 39 beziehungsweise 41 Prozent cover erreichbar, die
   Kippung braucht 60. Der Sage-Halbkreis waere dort dauerhaft halb
   eingeblendet stehengeblieben.

   entry laeuft von "Oberkante tritt unten ins Bild" bis "Unterkante ist
   drin". Das ist erreicht, sobald der Bereich einmal ganz zu sehen war, und
   haengt nicht daran, wieviel Seite darunter noch folgt. Die Sequenz endet
   bei 92 Prozent, damit auch bei knappem Platz Luft bleibt. */
@supports (animation-timeline: view()) {
  .ringdeco i{animation:ring-auf linear both;animation-timeline:--stmt;animation-range:entry 12% entry 52%}
  .ringdeco i:nth-child(2){animation:ring-auf linear both;animation-timeline:--stmt;animation-range:entry 19% entry 59%}
  .ringdeco i:nth-child(3){animation:ring-auf linear both;animation-timeline:--stmt;animation-range:entry 26% entry 66%}
  .statement .flipseq i{animation:um-auf linear both;animation-timeline:--stmt;animation-range:entry 40% entry 62%}
  .statement .flipseq i:nth-child(2){animation:um-auf linear both;animation-timeline:--stmt;animation-range:entry 45% entry 67%}
  .statement .flipseq i:nth-child(3){animation:um-auf linear both,um-kipp linear both;animation-timeline:--stmt,--stmt;animation-range:entry 50% entry 72%,entry 70% entry 84%}
  .statement .flipseq i:nth-child(4){animation:um-auf linear both,um-kipp linear both;animation-timeline:--stmt,--stmt;animation-range:entry 55% entry 77%,entry 78% entry 92%}

  /* WEITE FASSUNG: DIESELBE SEQUENZ UEBER RUND DEN DOPPELTEN SCROLLWEG

     Die Sequenz oben ist auf den knappsten Fall zugeschnitten. Sie endet mit
     dem Eintreten des Bereichs, weil auf Kontakt und Erstgespraech 94px nach
     dem Statement die Seite aufhoert und mehr schlicht nicht scrollbar ist.

     Wo Platz ist, laeuft sie ueber cover statt ueber entry und damit deutlich
     ruhiger: 812 statt 441px Scrollweg, also 84 Prozent mehr.

     NUR AUF DER STARTSEITE. Leistungen und Anlaesse haetten mit 79 und 73
     Prozent Spielraum zwar gereicht, wurden dort aber erst bei 95 Prozent der
     Scrollstrecke fertig — die Kippung waere passiert, waehrend schon der
     Footer im Bild steht. Auf beiden Seiten steht das Statement direkt vor
     dem Abschluss. Die Startseite hat 3133px Seite darunter.

     Das Ende bei 62 Prozent ist kein runder Wert, sondern die Obergrenze:
     Dort steht die Oberkante des Bereichs genau an der Fensterkante. Weiter
     gezogen liefe die Kippung, waehrend die Halbkreise schon aus dem Bild
     wandern.

     Bewusst als Zusatzklasse und nicht als Standard: Wird die Klasse bei einer
     neuen Seite vergessen, laeuft die kurze Fassung, und die ist ueberall
     vollstaendig. Umgekehrt waere eine vergessene Ausnahme ein Motiv, das nie
     fertig wird. */
  .statement.weit .ringdeco i{animation-range:cover 6% cover 26%}
  .statement.weit .ringdeco i:nth-child(2){animation-range:cover 11% cover 31%}
  .statement.weit .ringdeco i:nth-child(3){animation-range:cover 16% cover 36%}
  .statement.weit .flipseq i{animation-range:cover 26% cover 38%}
  .statement.weit .flipseq i:nth-child(2){animation-range:cover 29% cover 41%}
  .statement.weit .flipseq i:nth-child(3){animation-range:cover 32% cover 44%,cover 46% cover 55%}
  .statement.weit .flipseq i:nth-child(4){animation-range:cover 35% cover 47%,cover 52% cover 62%}
}

/* Beide Portraitkaesten gleich hoch: Das Raster streckt die Spalten auf die
   groessere der beiden, der weisse Kasten folgte dem aber nicht. Bei zwei
   statt drei Beschreibungszeilen endete der Rahmen 21px hoeher. */
.pinfo{flex:1}
/* Stack-Sektion: vier Felder der mission-critical infrastructure */
.stackgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.stackgrid .card h3{font-size:21px}
.stacknote{font-size:13.5px;margin:22px 0 0;border-top:.5px solid var(--line-ink);padding-top:16px;max-width:860px}

/* ---------- Team & Netzwerk: Gruppen und Aufbau ----------
   Die Knoten liegen jetzt in zwei Gruppen (Kern-Team, Expertennetzwerk). Auf
   dem Kreis sollen die Gruppen nichts bewirken: display:contents nimmt die
   Wrapper aus dem Layout, die Knoten positionieren sich weiter absolut gegen
   .orbitwrap. Erst im gestapelten Modus werden die Gruppen zu echten Bloecken
   (siehe site.css) und ihre Ueberschriften sichtbar. */
.ogroup{display:contents}
.ogrouptitle{display:none}

/* Aufbau von innen nach aussen: erst der Kern, dann die Ringe, dann das eigene
   Team, zuletzt das Netzwerk. Dieselbe Machart wie die Zeitleiste weiter oben
   auf der Seite: Grundregel zeitgesteuert, mit view() am Scrollfortschritt.
   Die Knoten tragen bereits translate(-50%,-50%) — das muss in jedem Keyframe
   mitgeschrieben werden, sonst springen sie beim Start um ihre halbe Groesse. */
@keyframes orb-core{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}
@keyframes orb-ring{from{opacity:0;transform:translate(-50%,-50%) scale(.92)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
@keyframes orb-node{from{opacity:0;transform:translate(-50%,-50%) scale(.86)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}

.orbitwrap{view-timeline-name:--orbit}
.core{animation:orb-core .5s cubic-bezier(.34,1.3,.64,1) both}
.ring{animation:orb-ring .6s cubic-bezier(.4,0,.2,1) .12s both}
.ring:nth-of-type(2){animation-delay:.22s}
.og-kern .onode{animation:orb-node .42s cubic-bezier(.34,1.3,.64,1) both}
.og-netz .onode{animation:orb-node .42s cubic-bezier(.34,1.3,.64,1) both}
.og-kern .onode:nth-child(2){animation-delay:.34s}
.og-kern .onode:nth-child(3){animation-delay:.40s}
.og-kern .onode:nth-child(4){animation-delay:.46s}
.og-kern .onode:nth-child(5){animation-delay:.52s}
.og-netz .onode:nth-child(2){animation-delay:.60s}
.og-netz .onode:nth-child(3){animation-delay:.66s}
.og-netz .onode:nth-child(4){animation-delay:.72s}
.og-netz .onode:nth-child(5){animation-delay:.78s}
.og-netz .onode:nth-child(6){animation-delay:.84s}
.og-netz .onode:nth-child(7){animation-delay:.90s}
.og-netz .onode:nth-child(8){animation-delay:.96s}
.og-netz .onode:nth-child(9){animation-delay:1.02s}
.og-netz .onode:nth-child(10){animation-delay:1.08s}

@supports (animation-timeline: view()) {
  /* Die Selektoren muessen mindestens so spezifisch sein wie die Grundregeln:
     dort setzt die Kurzschrift `animation:` das animation-timeline implizit
     auf auto zurueck. Ein blosses .onode hier wuerde von .og-kern .onode
     ueberstimmt — die Knoten liefen dann weiter an der Dokumentzeit. */
  .core,.ring,.og-kern .onode,.og-netz .onode{animation-timing-function:linear;animation-delay:0s;animation-timeline:--orbit}
  .core{animation-range:cover 10% cover 26%}
  .ring{animation-range:cover 14% cover 32%}
  .ring:nth-of-type(2){animation-range:cover 12% cover 30%}
  .og-kern .onode:nth-child(2){animation-range:cover 20% cover 34%}
  .og-kern .onode:nth-child(3){animation-range:cover 22% cover 36%}
  .og-kern .onode:nth-child(4){animation-range:cover 24% cover 38%}
  .og-kern .onode:nth-child(5){animation-range:cover 26% cover 40%}
  .og-netz .onode:nth-child(2){animation-range:cover 30% cover 44%}
  .og-netz .onode:nth-child(3){animation-range:cover 32% cover 46%}
  .og-netz .onode:nth-child(4){animation-range:cover 34% cover 48%}
  .og-netz .onode:nth-child(5){animation-range:cover 36% cover 50%}
  .og-netz .onode:nth-child(6){animation-range:cover 38% cover 52%}
  .og-netz .onode:nth-child(7){animation-range:cover 40% cover 54%}
  .og-netz .onode:nth-child(8){animation-range:cover 42% cover 56%}
  .og-netz .onode:nth-child(9){animation-range:cover 44% cover 58%}
  .og-netz .onode:nth-child(10){animation-range:cover 46% cover 60%}
}
/* Ohne translate — fuer den gestapelten Modus, in dem die Knoten im Fluss
   stehen statt absolut positioniert. */
@keyframes orb-node-flat{from{opacity:0;transform:scale(.86)}to{opacity:1;transform:scale(1)}}

/* ==================================================================
   Startseite v5: heller Hero
   Nav und Hero stehen auf Papier statt auf Tiefgruen. .topfold traegt die
   Flaeche, damit der Farbwechsel an einer Kante endet und nicht mitten in
   einem Element. Die Navigation erbt darin ihre Farben neu.
   ================================================================== */
.topfold{background:var(--paper);color:var(--ink)}
.topfold nav{border-bottom:.5px solid var(--line-ink)}
/* :not(.btn) ist noetig: Der Erstgespraech-Knopf ist ebenfalls ein <a> in
   .links. Ohne die Ausnahme faerbt diese Regel seine Schrift auf Ink ein,
   und er stuende mit 1,5:1 Kontrast dunkelgruen auf dunkelgruen. */
.topfold nav .links a:not(.btn){color:var(--ink)}
.topfold .navdesc{color:var(--acc-ink)}
.topfold .navtoggle{border-color:var(--line-ink)}
.topfold .navtoggle span{background:var(--ink)}

/* Rechte Spalte auf die Clusterbreite (2x160 + 12 Abstand = 332), damit die
   Komposition eng bleibt und der Text mehr Raum bekommt als beim Foto. */
.herolight{display:grid;grid-template-columns:1fr 412px;gap:60px;padding:90px 60px 80px;align-items:center}
.herolight h1{font-size:72px;font-weight:400;letter-spacing:-1.8px;line-height:.97;margin:0 0 28px}
.herolight .sub{font-size:19px;line-height:1.55;max-width:620px;margin:0 0 38px}
.herocta{display:flex;gap:14px;flex-wrap:wrap}

/* Meta-Zeile: Standorte, Haltungszeile, Telefon. Mono-Versalien laut Manual. */
/* Die Trennlinie zieht sich beim Laden von links auf. Sie liegt als
   Pseudo-Element statt als border-top, weil sich nur so die Breite animieren
   laesst — ein border haette in der Flex-Zeile keinen eigenen Ursprung.
   Verzoegerung 0.5s: erst steht die Headline, dann kommt die Linie nach. */
.herometa{position:relative;display:flex;gap:32px;flex-wrap:wrap;margin-top:52px;padding-top:16px;max-width:640px;
  font-family:var(--font-mono);font-weight:500;font-size:9.5px;letter-spacing:.08em;color:var(--acc-ink)}
.herometa::before{content:"";position:absolute;left:0;right:0;top:0;height:.5px;background:var(--line-ink);
  transform-origin:left;animation:meta-draw .9s cubic-bezier(.4,0,.2,1) .5s both}
@keyframes meta-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.herometa a{color:inherit}

.herophoto{position:relative;border-radius:4px;overflow:hidden;height:420px}
/* Saettigung laut Manual auf 50 bis 60 Prozent: „kein Gruen-Filter im Foto,
   die Marke faerbt ueber Flaechen, nicht ueber Bilder“ (Seite 09). */
.herophoto img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;filter:saturate(.55)}
.shotcap{position:absolute;left:20px;bottom:18px;font-family:var(--font-mono);font-size:9.5px;letter-spacing:.08em;
  color:var(--paper);background:rgba(11,51,42,.78);border-radius:2px;padding:6px 10px}

/* ==================================================================
   Startseite v5: Sektion „Die Uebergaenge“
   Zwei Karten gegenueber: der Alltag beim Kunden auf Papier, die Uebergaenge
   bei uns auf Forest. Der Flaechenwechsel traegt die Aussage, nicht eine Linie.
   ================================================================== */
.transgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.transcard{border:.5px solid var(--line-ink);border-radius:4px;padding:30px 34px;display:flex;flex-direction:column}
.transcard.dark{background:var(--bg2);border-color:transparent;color:var(--paper)}
.tlabel{font-family:var(--font-mono);font-weight:500;font-size:10.5px;letter-spacing:.08em;color:var(--acc-ink);padding-bottom:18px}
.transcard.dark .tlabel{color:var(--accent)}
.trow{border-top:.5px solid var(--line-ink);padding:16px 0;display:flex;flex-direction:column;gap:4px}
.trow:last-child{padding-bottom:0}
.transcard.dark .trow{border-top-color:var(--line)}
.trow b{font-family:var(--font-ui);font-weight:500;font-size:15.5px;letter-spacing:-.3px;color:var(--ink)}
.transcard.dark .trow b{color:var(--paper)}
.trow span{font-size:13.5px;line-height:1.5;color:color-mix(in oklab,var(--ink) 72%,var(--paper))}
.transcard.dark .trow span{color:color-mix(in oklab,var(--paper) 72%,var(--bg))}

.transband{margin-top:14px;border-top:.5px solid var(--line-ink);border-bottom:.5px solid var(--line-ink);
  padding:32px 0;display:flex;justify-content:space-between;align-items:baseline;gap:40px}
.tbig{font-size:28px;letter-spacing:-.6px;line-height:1.2;color:var(--ink);max-width:860px}
.tnote{font-family:var(--font-mono);font-weight:500;font-size:10.5px;letter-spacing:.08em;color:var(--acc-ink);white-space:nowrap}

/* ---------- Versuch: helle Menueleiste auf den Innenseiten ----------
   Damit die Leiste ueber alle Seiten dieselbe Konstante ist wie im hellen
   Kopfbereich der Startseite. Auf .lp gesetzt, damit sich der Versuch pro
   Seite mit einem Wort im HTML an- und abschalten laesst.

   Die Spezifitaet muss .lp nav aus site.css schlagen, wo die klebende Leiste
   ihre Tiefgruen-Flaeche bekommt: .lp.navlight nav ist (0,2,1) gegen (0,1,1).

   :not(.btn) wie im Kopfbereich der Startseite — sonst faerbt die Regel den
   Erstgespraech-Knopf mit ein und er wird unlesbar. */
.lp.navlight nav{background:var(--paper);border-bottom:.5px solid var(--line-ink)}
.lp.navlight nav .links a:not(.btn){color:var(--ink)}
.lp.navlight .navdesc{color:var(--acc-ink)}
.lp.navlight .navtoggle{border-color:var(--line-ink)}
.lp.navlight .navtoggle span{background:var(--ink)}
.lp.navlight nav .links a.on::before{background:var(--acc-ink)}

/* ==================================================================
   Anlaesse als Bild + Liste (Entwurf 3C)
   Links das Situationsbild, rechts vier Anlaesse als Zeilen mit Kundensatz.
   Die Zeilen sind Links auf die Anlaesse-Seite: Der Entwurf hat sie als
   reinen Text, die abgeloeste Fassung hatte vier Verweise. Ohne sie waere
   der Weg in die Tiefe verloren gegangen.
   ================================================================== */
.anlgrid{display:grid;grid-template-columns:560px 1fr;gap:56px;align-items:stretch}
/* Der Rahmen folgt dem Bild, nicht umgekehrt: 7/8 ist genau das
   Seitenverhaeltnis der Aufnahme, dadurch wird nichts beschnitten. Vorher
   stand hier min-height:480px, also 560x480 im Querformat — die drei Personen
   fuellen 65 Prozent der Bildhoehe und haetten dort auf Huefthoehe abgeschnitten
   werden muessen. */
.anlbild{position:relative;border-radius:4px;overflow:hidden;aspect-ratio:7/8}
/* Saettigung wie im Manual (Seite 09): kuehl und entsaettigt. */
.anlbild img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;filter:saturate(.55)}
/* max-width haelt den rechten Rand frei: Ohne sie waechst das Label so weit,
   wie der Text lang ist, und stand bei 320px nur noch 10px vor der Bildkante,
   waehrend links 20px Rand sitzen. Jetzt bricht es dort lieber um. */
.anlcap{position:absolute;left:20px;bottom:18px;max-width:calc(100% - 40px);font-family:var(--font-mono);font-weight:500;font-size:9.5px;letter-spacing:.08em;
  color:var(--paper);background:rgba(11,51,42,.82);border-radius:2px;padding:6px 10px}

/* Die Liste ist 477px hoch, der Bildplatz jetzt 640. Statt sie mittig in den
   Rest zu setzen, verteilen sich die vier Zeilen und der Knopf ueber die volle
   Hoehe: gleiche Oberkante, gleiche Unterkante, mehr Luft dazwischen. */
.anlliste{display:flex;flex-direction:column;justify-content:space-between}
.anlzeile{border-top:.5px solid var(--line-ink);padding:20px 0;display:flex;flex-direction:column;gap:4px;color:inherit}
.anlzeile:last-of-type{border-bottom:.5px solid var(--line-ink)}
.anlzeile:hover{opacity:1;background:color-mix(in oklab,var(--ink) 4%,transparent)}
.anlidx{font-family:var(--font-mono);font-weight:500;font-size:9.5px;letter-spacing:.08em;color:var(--acc-ink)}
.anlzeile b{font-family:var(--font-ui);font-weight:500;font-size:17px;letter-spacing:-.3px;color:var(--ink)}
.anlzeile .muti{font-size:13px;line-height:1.5}
.anlcta{padding-top:22px}

/* ==================================================================
   „Für wen": Ausfalltoleranz als Skala (Entwurf 2B)
   Die Skala laeuft von links (Tage verschmerzbar) nach rechts (null Toleranz).
   Gefuellt ist nur das rechte Drittel — dort stehen wir. Der Zielpunkt ist der
   einzige Sage-Punkt der Sektion: „Sage ist Zeichen, nie Flaeche" (Manual S. 06).
   ================================================================== */
.tolskala{padding-top:40px;view-timeline-name:--tol}
.tolbahn{position:relative;height:2px;background:rgba(14,42,35,.18)}
.tolpunkt{position:absolute;top:-3.5px;width:8px;height:8px;border-radius:50%;border:.5px solid rgba(14,42,35,.4);background:var(--paper)}

/* Die Fuellung waechst beim Scrollen von links auf den Zielpunkt zu und endet
   hinter ihm: .tolziel steht spaeter im Markup und liegt deshalb darueber.
   Danach setzt sich der Punkt, zuletzt zieht der Ring auf.
   Machart wie die Zeitleiste und die Sektionsbruecke: Grundregel zeitgesteuert,
   im @supports-Block auf den Scrollfortschritt umgehaengt. Die Selektoren sind
   dort woertlich dieselben, damit die Kurzschrift `animation:` das
   animation-timeline nicht ueber die Spezifitaet zurueckstellt. */
.tolfuell{position:absolute;right:0;top:0;height:2px;width:34%;background:var(--acc-ink);
  transform-origin:left;animation:pl-grow 1s cubic-bezier(.4,0,.2,1) both}
.tolziel{position:absolute;right:-6px;top:-6px;width:14px;height:14px;border-radius:50%;background:var(--accent);
  animation:sb-dot .4s cubic-bezier(.34,1.4,.64,1) .85s both}
.tolring{position:absolute;right:-17px;top:-17px;width:36px;height:36px;border-radius:50%;border:.5px solid var(--acc-ink);
  animation:tol-ring .5s cubic-bezier(.4,0,.2,1) 1.05s both}
@keyframes tol-ring{from{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}
@supports (animation-timeline: view()) {
  .tolfuell{animation:pl-grow linear both;animation-timeline:--tol;animation-range:cover 16% cover 44%}
  .tolziel{animation:sb-dot linear both;animation-timeline:--tol;animation-range:cover 40% cover 50%}
  .tolring{animation:tol-ring linear both;animation-timeline:--tol;animation-range:cover 46% cover 60%}
}

.tolstufen{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:24px;margin-top:20px}
.tolstufen > div{display:flex;flex-direction:column;gap:4px}
.tolstufen .muti{font-size:12.5px;line-height:1.5}
.tolmark{font-family:var(--font-mono);font-weight:500;font-size:9.5px;letter-spacing:.08em;
  color:color-mix(in oklab,var(--ink) 72%,var(--paper))}
.tolmark.stark{color:var(--acc-ink)}
.tolmark.hier{display:flex;align-items:center;gap:8px;color:var(--ink)}
.tolmark.hier i{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none}
.tolhier{font-family:var(--font-ui);font-weight:500;font-size:13.5px;letter-spacing:-.2px;color:var(--ink);line-height:1.5}

.aspekte{margin-top:52px;display:grid;grid-template-columns:1fr 1fr;gap:12px}
.aspekt{border:.5px solid var(--line-ink);border-radius:4px;padding:26px 30px;display:flex;flex-direction:column;gap:6px}
.aspekt b{font-family:var(--font-ui);font-weight:500;font-size:16px;letter-spacing:-.3px;color:var(--ink)}
.aspekt .muti{font-size:13.5px;line-height:1.5}

.tolfoot{margin-top:28px;display:flex;justify-content:space-between;gap:40px;align-items:baseline}
.tolfoot .muti{font-family:var(--font-mono);font-weight:500;font-size:9.5px;letter-spacing:.08em;line-height:2}
.tolcta{font-family:var(--font-mono);font-weight:500;font-size:10.5px;letter-spacing:.08em;color:var(--acc-ink);white-space:nowrap}

/* ==================================================================
   Leistungen: Bruecke zur Technik + Kompetenzfelder
   Aus dem Entwurf "Leistungen mit Kompetenzfeldern", Variante D.
   Die Gestaltung ist dort durchgehend inline gesetzt; hier in Klassen
   ueberfuehrt, damit die Sektionen responsiv werden.
   ================================================================== */
.techbruecke{background:var(--deep);color:var(--paper);padding:72px 60px;
  display:grid;grid-template-columns:400px 1fr;gap:40px;align-items:center;
  border-top:.5px solid var(--line);border-bottom:.5px solid var(--line)}
.tbinhalt{display:flex;flex-direction:column;gap:28px}
.techbruecke h2{font-size:44px;font-weight:400;letter-spacing:-1px;line-height:1.05;margin:0}
.tbbahn{position:relative;height:2px;background:color-mix(in oklab,var(--paper) 18%,transparent);max-width:640px}
/* Die Fuellung endet bei 62 Prozent, der Punkt sitzt darauf. Nicht am Ende:
   "Der Punkt sitzt nie am Ende" (Manual Seite 08). */
.tbfuell{position:absolute;left:0;top:0;height:2px;width:62%;background:var(--accent);
  transform-origin:left;animation:pl-grow 1s cubic-bezier(.4,0,.2,1) both}
.tbpunkt{position:absolute;top:-4px;left:62%;width:10px;height:10px;border-radius:50%;background:var(--paper);
  animation:sb-dot .4s cubic-bezier(.34,1.4,.64,1) .85s both}
.tbfoot{display:flex;gap:28px;max-width:640px;justify-content:space-between;
  font-family:var(--font-mono);font-size:9.5px;letter-spacing:.08em}
.tbfelder{color:var(--accent)}
.techbruecke{view-timeline-name:--tb}
@supports (animation-timeline: view()) {
  .tbfuell{animation:pl-grow linear both;animation-timeline:--tb;animation-range:entry 30% entry 80%}
  .tbpunkt{animation:sb-dot linear both;animation-timeline:--tb;animation-range:entry 76% entry 94%}
}

/* Vier Zeilen statt vier Spalten: Nummer, Name mit Kuerzeln, Erklaerung, Bild.
   Die Zeile traegt die Trennung ueber eine Haarlinie, nicht ueber eine Flaeche. */
.felder{display:flex;flex-direction:column}
.feld{border-top:.5px solid var(--line-ink);padding:32px 0;
  display:grid;grid-template-columns:80px 380px 1fr 260px;gap:36px;align-items:center}
.feld:last-child{border-bottom:.5px solid var(--line-ink)}
.feldnr{font-family:var(--font-mono);font-weight:500;font-size:10px;letter-spacing:.08em;color:var(--acc-ink)}
.feldname{display:flex;flex-direction:column;gap:8px}
.feldname b{font-size:40px;font-weight:400;letter-spacing:-1px;color:var(--ink);line-height:1}
.feldname .muti{font-family:var(--font-mono);font-size:9px;letter-spacing:.08em}
.feldtext{font-size:14px;line-height:1.55;max-width:420px}
.feldbild{position:relative;height:130px;border-radius:4px;overflow:hidden}
.feldbild img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:saturate(.55)}
.felderfoot{margin-top:28px;display:flex;justify-content:space-between;gap:40px;align-items:baseline}
.felderfoot .muti{font-size:14px;line-height:1.6;max-width:760px}
.feldersum{font-family:var(--font-mono);font-weight:500;font-size:10.5px;letter-spacing:.08em;
  color:var(--acc-ink);white-space:nowrap}
