/* =======================================================================
   HeiselConnect – Unterseite "Webservices"
   Nur die seiteneigenen Grafiken. Die Huelle steht in page.css, die
   VOR dieser Datei eingebunden wird.

     0. Referenz-Laptop
     1. Leistungen: Kette aus Band und Icon-Kreisen
     2. Responsive-Demo
     3. Breakpoints
   ======================================================================= */

/* ------------------------------------------------- 0. Referenz-Laptop
   .shots--laptop steht bewusst hier und nicht in page.css: #referenz als
   ID kommt auch auf optimierung.html vor (eigene Referenz-Grafik dort,
   .shots--solo), eine ID-Regel in page.css haette also unbeabsichtigt
   auch dort gegriffen – genau das ist einmal passiert (align-items:start
   hat die Referenz-Grafik auf optimierung.html nach oben statt zur
   Textmitte gezogen).

   Die Notebook-Aufnahme (img/mock-konfigurator-notebook.*) wird unveraendert
   verwendet, so wie sie aus vorlagen/Laptop_Mockup_dark.png kommt – kein
   Zuschnitt, keine Maske: der Glow faedet in der Datei selbst sauber auf 0
   aus. Deshalb bekommt die Aufnahme auch weder Formschatten noch
   Bodenschatten noch Schwebe-Animation von der Grundregel in page.css,
   und keine Spiegelung – das PNG bringt seinen Lichtkegel bereits mit.

   Das Geraet nimmt im PNG nur rund 46 % der Bildbreite ein (der Rest ist
   Rand fuer den Glow). Aendert sich das PNG nochmal (andere Aufloesung,
   anderer Rand), muessen alle Prozentwerte unten neu aus der
   Geraete-Bounding-Box berechnet werden – sie sind kein Zufallstreffer. */
/* Unter 860px: dasselbe Verfahren wie ab 860px weiter unten (absolut
   positionierte Aufnahme + aspect-ratio auf .shots-stage), nur mit eigenen
   Werten fuer die schmale Spalte. Die Prozentwerte sind NICHT geschaetzt,
   sondern aus der tatsaechlichen Geraete-Bounding-Box im PNG gerechnet
   (per-Pixel-Alpha-Scan, alpha>230 = Geraet): das Geraet liegt bei
   20,4–66,5% der Bildbreite (Mitte 43,5%) und 39,2–75,5% der Bildhoehe
   (Mitte 57,3%) – NICHT mittig im Bild, es steht im PNG selbst schon
   links der Mitte mit mehr Glow-Rand rechts. Eine simple symmetrische
   Zentrierung des Bildes zentriert deshalb das Bild, aber nicht das
   GERAET – sichtbar als Linksversatz. Die Werte unten zentrieren
   stattdessen das Geraet selbst:

     width: 175%, davon ausgehend soll die Geraetemitte (43,5% der
     Bildbreite) auf 50% der Buehne liegen: left = 50% − 43,5%·175% ≈ −26,1%.

     aspect-ratio auf .shots-stage schneidet oben/unten deutlich in den
     Glow (statt wie zuvor die volle, groesstenteils leere Bildhoehe
     mitzutragen) – der Platz um das Geraet bleibt ein schmaler
     Glow-Saum statt eines toten Bereichs. top schiebt dafuer die
     Geraete-Oberkante (39,2% der Bildhoehe, samt 5%-Saum) an die
     Buehnenoberkante. Ueberstehender Glow (seitlich wie oben/unten)
     wird nicht hier, sondern an der Abschnittskante beschnitten
     (#referenz{ overflow:hidden } weiter unten) – exakt wie ab 860px,
     die Seite bekommt dadurch keinen horizontalen Scrollbalken. */
.shots--laptop .shots-stage{ padding-bottom: 0; aspect-ratio: 1.5; }
.shots--laptop .shot--notebook{
  position: absolute;
  width: 175%;
  left: -26.1%;
  top: -73.6%;
}
.shots--laptop .shot--notebook img{ filter: none; animation: none; }
.shots--laptop .shot--notebook::after{ content: none; }

/* Das Telefon schwebt auf Hoehe der Geraetemitte (aus derselben
   Bounding-Box-Rechnung: 57,3% Bildhoehe landen bei der obigen
   Position/Skalierung auf ~50% der jetzt knapperen Buehnenhoehe). right
   setzt es an den rechten Rand des Geraets (Geraetekante bei 90,3% der
   Buehnenbreite) und ein Stueck darueber hinaus – wie in der 860px-Fassung
   unten, nur mit den Mobil-Werten von oben. */
.shots--laptop .shot--handy{
  top: 50%;
  right: 3%;
  bottom: auto;
  translate: 0 -50%;
}
.shots--laptop .shot--handy img{ animation: none; }
.shots--laptop .shot--handy::after{ content: none; }

/* Ab 860px stehen Notebook und Text in derselben Grid-Zeile UND es gibt
   eine Nachbarspalte, in die die Aufnahme hineinragen darf – deshalb hier
   die volle Groesse statt der mobil sicheren 100%. Anpassungen gegenueber
   dem normalen Fluss:

   1) Bei so viel Breite ist die Aufnahme im normalen Fluss auch
      entsprechend hoch (deutlich hoeher als der Text daneben) und blaeht
      die ganze Zeile – und damit den Abschnitt – auf diese Hoehe auf.
      Deshalb steht .shot--notebook auf position:absolute: die Aufnahme
      traegt nicht mehr zur Hoehe von .shots-stage bei. Die Bezugsgroesse
      liefert stattdessen aspect-ratio auf .shots-stage.

   2) "An der linken oberen Ecke groesser gezogen, bis buendig mit dem
      Text": align-items wechselt von center auf start (beide Spalten
      beginnen jetzt an der Zeilenoberkante). links bleibt derselbe Wert
      wie beim vorherigen PNG (-31.1%) – fixer Wachstums-Ursprung statt
      Zentrierung. Oben ist es kein simples top:0: im Bild liegt vor dem
      Geraet selbst noch ein Glow-Rand von knapp 40% der Bildhoehe (siehe
      Kommentar weiter oben zur Geraete-Bounding-Box). top:0 haette also
      nicht das Geraet, sondern nur leeren Rand an die Textkante gelegt.
      Der negative top-Wert schiebt stattdessen die Bildoberkante so weit
      NACH OBEN aus der Zeile heraus, dass exakt die GERAETE-Oberkante an
      der Zeilenoberkante ankommt.

   3) Erst danach darf frei herauswachsen (rechts und unten), und genau
      dieses Herauswachsen endet jetzt hart an der Abschnittskante
      (overflow:hidden auf #referenz, siehe unten) statt weich auszulaufen
      – im Unterschied zu vorher ist eine Kante hier ausdruecklich
      erwuenscht, damit der Abschnitt trotz des groesseren Bilds kompakt
      bleibt. Die Breite ist so gewaehlt, dass dabei nur ueberschuessiger
      Glow abgeschnitten wird, nicht das Geraet selbst. */
@media (min-width: 860px){
  #referenz .split{ align-items: start; }
  .shots--laptop .shots-stage{ aspect-ratio: 1.6; }
  /* Zielgroesse per Vorgabe: das GERAET (nicht die Bildkante) soll exakt
     von der Zeilenoberkante (= "REFERENZ") bis zur Button-Unterkante
     reichen, also so hoch wie die Textspalte selbst (434.75px bei 561.2px
     Spaltenbreite) – mit gutem Abstand zur Textspalte selbst. left
     rechnet dafuer NICHT auf Zentrierung; stattdessen bleibt die rechte
     Geraetekante bewusst auf demselben Wert wie in der allerersten,
     unbeschnittenen Fassung (93%, sicher vor der Textspalte) und
     links/oben wachsen von dort aus weiter nach aussen – "nach links
     oben vergroessert", wie gewuenscht. */
  .shots--laptop .shot--notebook{
    position: absolute;
    top: -132.9%;
    left: -79.3%;
    width: 258.8%;
  }
  /* Handy im selben Verhaeltnis wie im allerersten Entwurf ueber die
     rechte Geraetekante hinaus (Faktor 258.8/186.5 ≈ 1.387), top gegen
     die neue Geraetemitte. */
  .shots--laptop .shot--handy{
    width: 34.7%;
    top: 62%;
    right: -2.71%;
    bottom: auto;
    translate: 0 -50%;
  }
}

/* "Referenzbereich soll nicht mit dem Glow mitwachsen": die Aufnahme darf
   oben, rechts und unten frei ueber .shots-stage hinausragen (siehe
   aspect-ratio-Kommentar oben) – aber nicht ueber den Abschnitt selbst.
   Dort wird hart geschnitten, bewusst mit sichtbarer Kante statt mit
   einem weiteren Ausblenden. */
#referenz{ overflow: hidden; }

/* Faellt die Aufnahme trotzdem in den Text – unterhalb von 860px der Glow
   (dort bleibt .shots--laptop bei 100% Breite), ab 860px auch mal das
   Handy (z-index: 2, siehe .shot--handy weiter oben) –, liegt der Text
   darueber statt dass das Bild beschnitten wird. z-index: 3 schlaegt
   also nicht nur das Notebook (1), sondern auch das davor schwebende
   Handy (2). */
#referenz .split-text{ position: relative; z-index: 3; }

/* ---- Leistungen: Kette aus Band und Icon-Kreisen ----------------------
   Nach dem Vorbild der Infografik-Vorlage: ein durchgehendes Band legt
   einen Ring um jedes Icon und fuehrt in einer S-Kurve zum naechsten.
   Das Band fuehrt neutral von hell nach dunkel; Gruen bleibt den
   Handlungsaufrufen vorbehalten.

   Ab 860px traegt ein SVG die gesamte Form (Ringe, Verbinder, weisse
   Scheiben inkl. Schatten). Es liegt als Block im Fluss, dadurch hat
   .flow exakt sein Seitenverhaeltnis – und jeder SVG-Punkt (x|y) laesst
   sich als Prozentwert (x/1000 | y/1520) darueberlegen. Genau das machen
   .flow-node und .flow-text: Text bleibt echtes HTML, die Form bleibt
   vektorgenau.

   Darunter wird die Kette zur Schiene: Ringe untereinander am linken
   Rand, Text daneben. Dort zeichnet CSS die Ringe, weil die Texthoehe
   nicht mehr vorhersagbar ist. Die Farbstufen unten sind Stichproben
   desselben Verlaufs, damit beide Darstellungen gleich aussehen. */
.flow{
  position: relative;
  max-width: 940px;
  margin-inline: auto;

  --node: clamp(92px, 17vw, 170px);        /* Aussendurchmesser, gestapelt */
  --ring-w: calc(var(--node) * 0.12);      /* Bandstaerke = 42/352 der Vorlage */
  --row-gap: clamp(1.8rem, 0.9rem + 3vw, 3rem);
}

/* Farbstufen des Verlaufs an den Ringmitten – siehe Verlauf im HTML */
.flow-item:nth-child(1){ --c1: #A2D6A0; --c2: #87C287; --c3: #6EAE74; }
.flow-item:nth-child(2){ --c1: #6EAE74; --c2: #5A9B6D; --c3: #498965; }
.flow-item:nth-child(3){ --c1: #498965; --c2: #3A785C; --c3: #2D6554; }
.flow-item:nth-child(4){ --c1: #2D6554; --c2: #22514E; }

.flow-band{ display: none; }

.flow-items{
  display: grid;
  row-gap: var(--row-gap);
}

.flow-item{
  position: relative;
  display: grid;
  grid-template-columns: var(--node) 1fr;
  column-gap: clamp(1rem, 4vw, 1.9rem);
  align-items: start;
}

/* Schiene: von dieser Ringmitte bis zur naechsten */
.flow-item:not(:last-child)::before{
  content: "";
  position: absolute;
  left: calc(var(--node) / 2);
  top: calc(var(--node) / 2);
  height: calc(100% + var(--row-gap));
  width: var(--ring-w);
  translate: -50% 0;
  background: linear-gradient(180deg, var(--c2), var(--c3));
}

.flow-node{
  position: relative;
  width: var(--node);
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(155deg, var(--c1), var(--c2));
}
/* weisse Scheibe: deckt die Ringmitte ab und wirft den Schatten der Vorlage */
.flow-node::after{
  content: "";
  position: absolute;
  inset: var(--ring-w);
  border-radius: 50%;
  background: #fff;
  box-shadow: 6px 8px 16px rgba(21, 48, 30, 0.26);
}

.flow-icon{
  position: relative;
  z-index: 1;
  width: 46%;
  height: 46%;
  stroke-width: 1.35;
  color: #2a3b30;
}

/* Der Kreis haengt oben in der Zeile – nur so kennt die Schiene ihren
   Startpunkt. Der Text darf sich dagegen zur Kreismitte ausrichten. */
.flow-text{
  align-self: center;
  max-width: 34rem;
}
.flow-text h3{
  font-size: clamp(1.15rem, 0.98rem + 0.85vw, 1.72rem);
  text-transform: uppercase;
  letter-spacing: 0.035em;
  line-height: 1.18;
}
/* etwas dunkler und luftiger als der uebrige Fliesstext: die Zeile steht
   frei im Weissraum und muss ohne Umgebung fuer sich lesbar sein */
.flow-text p{
  margin-top: 0.6rem;
  color: #4b4b53;
  font-size: clamp(1.04rem, 0.96rem + 0.4vw, 1.3rem);
  line-height: 1.62;
}


/* Die Geraete-Attrappen stehen in page.css – beide Unterseiten nutzen sie. */


/* --- Responsive-Demo: derselbe Inhalt ordnet sich um --- */
.rwd{ display: grid; justify-items: center; gap: 1rem; }

.rwd-device{
  width: 100%;
  max-width: 460px;
  aspect-ratio: 16 / 11;
  display: grid;
  place-items: center;
}

.rwd-screen{
  width: 100%;
  height: 100%;
  background: var(--ink);
  border: 1px solid var(--hair);
  border-radius: 18px;
  box-shadow: var(--shadow);
  padding: 12px;
  display: grid;
  /* feste Prozentzeile statt height am Kind: in einer auto-Zeile hätte die
     Prozentangabe keinen Bezug und der Hero-Streifen bliebe 0 hoch */
  grid-template-rows: auto 30% 1fr auto;
  gap: 10px;
  overflow: hidden;
  animation: rwdFrame 9s var(--ease) infinite;
}

.rwd-bar{ display: flex; gap: 6px; }
.rwd-bar i{ width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, 0.22); }

/* Der Hero-Streifen der Attrappe traegt das Markengruen: die Demo ist eine
   Illustration, kein Text – und Grafiken duerfen die Farbe fuehren. Ohne sie
   war die ganze Attrappe grau in grau. */
.rwd-hero{
  border-radius: 10px;
  background: linear-gradient(120deg, rgba(116, 180, 118, 0.5), rgba(116, 180, 118, 0.12));
}

.rwd-grid{
  display: grid;
  gap: 8px;
  grid-template-columns: 1fr 1fr 1fr;
  animation: rwdGrid 9s var(--ease) infinite;
}
.rwd-grid div{
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.07);
  min-height: 26px;
}

.rwd-lines{ display: grid; gap: 6px; }
.rwd-lines span{ height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.14); }
.rwd-lines span:nth-child(2){ width: 78%; }
/* die betonte Zeile – sie greift das Gruen des Hero-Streifens auf */
.rwd-lines span:nth-child(3){ width: 52%; background: rgba(116, 180, 118, 0.55); }

@keyframes rwdFrame{
  0%, 34%   { width: 100%; border-radius: 18px; }
  46%, 88%  { width: 42%;  border-radius: 26px; }
  100%      { width: 100%; border-radius: 18px; }
}
@keyframes rwdGrid{
  0%, 34%   { grid-template-columns: 1fr 1fr 1fr; }
  46%, 88%  { grid-template-columns: 1fr; }
  100%      { grid-template-columns: 1fr 1fr 1fr; }
}

.rwd-label{
  font-family: var(--hc-mono);
  font-size: 0.76rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* die tiefe Fassung des Gruens – sie traegt auf dem hellen Grund die 4,5:1 */
  color: var(--green-deep);
  position: relative;
  height: 1.2em;
  width: 100%;
  text-align: center;
}
.rwd-label span{ position: absolute; inset: 0; }
.rwd-label-d{ animation: rwdLabelD 9s steps(1) infinite; }
.rwd-label-m{ animation: rwdLabelM 9s steps(1) infinite; }
/* Umschaltpunkte liegen jeweils in der Mitte der Verwandlung */
@keyframes rwdLabelD{ 0%, 39% { opacity: 1; } 40%, 92% { opacity: 0; } 93%, 100% { opacity: 1; } }
@keyframes rwdLabelM{ 0%, 39% { opacity: 0; } 40%, 92% { opacity: 1; } 93%, 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce){
  .rwd-screen{ width: 100%; }
  .rwd-grid{ grid-template-columns: 1fr 1fr 1fr; }
  .rwd-label-m{ opacity: 0; }
}

@media (min-width: 860px){
  /* ---- Leistungen: das SVG-Band uebernimmt ---------------------------
     Das SVG steht im Fluss und gibt .flow sein Seitenverhaeltnis vor;
     alle Prozentwerte hier sind daher direkt aus der viewBox gerechnet
     (x/1000, y/1520). Ring links -> Text rechts und umgekehrt. */
  .flow-band{ display: block; width: 100%; height: auto; }

  .flow-items{ position: absolute; inset: 0; display: block; }

  /* volle Flaeche, damit die Kinder auf SVG-Koordinaten sitzen koennen;
     nur der Text faengt Mausereignisse ab, sonst waere er nicht markierbar */
  .flow-item{
    position: absolute;
    inset: 0;
    display: block;
    pointer-events: none;
  }
  .flow-item:not(:last-child)::before{ content: none; }

  .flow-item:nth-child(1){ --x: 38.6%; --y: 13.816%; }
  .flow-item:nth-child(2){ --x: 61.4%; --y: 37.171%; }
  .flow-item:nth-child(3){ --x: 38.6%; --y: 60.526%; }
  .flow-item:nth-child(4){ --x: 61.4%; --y: 83.882%; }

  /* Ring und weisse Scheibe zeichnet hier das SVG – bleibt nur das Icon */
  .flow-node{
    position: absolute;
    left: var(--x);
    top: var(--y);
    width: 26.8%;
    translate: -50% -50%;
    background: none;
  }
  .flow-node::after{ content: none; }

  .flow-text{
    position: absolute;
    top: var(--y);
    width: 41.5%;
    translate: 0 -50%;
    text-align: center;
    pointer-events: auto;
  }
  .flow-item:nth-child(odd)  .flow-text{ left: 58.5%; }
  .flow-item:nth-child(even) .flow-text{ left: 0; }

  .flow-text p{ margin-top: 0.75rem; }
}
