/* =========================================================
   COMPONENTS – wiederverwendbare Bausteine.
   Jedes Motiv des Entwurfs ist genau einmal definiert und
   wird per Klasse angewandt, nicht pro Sektion nachgebaut.
   ========================================================= */

/* =========================================================
   RULE – die linke Linie bei x = 130
   Im Entwurf ist sie keine durchlaufende Linie, sondern setzt
   sich aus Abschnitten zusammen: sie begleitet das Hero, setzt
   an den beiden Headlines aus und läuft ab dem Kartenraster
   ohne Unterbrechung bis zum CTA-Banner.
   Jeder Abschnitt sitzt deshalb in dem Element, zu dem er
   gehört, statt als ein Element über die ganze Seite zu laufen.
   ========================================================= */
.rule {
  position: absolute;
  width: 1px;
  background: var(--c-rule-dark);
  pointer-events: none;
}

/* 1. über dem Foto – beginnt 38 über der Dachspitze der
      Bildmarke und ist zugleich die Trennlinie im Logo.
      + --gutter, weil die Spine absolut im vollbreiten .stack sitzt
      und sonst am Fensterrand statt an der Inhaltskante stünde. */
.rule--hero {
  left: calc(var(--gutter) + var(--edge-rule) * var(--u));
  top: calc(92 * var(--u));
  height: calc(var(--hero-height) - 92 * var(--u));
  background: var(--c-rule-light);
  z-index: 5;
}

/* 2. kurzer Anlauf über „Unsere Schwerpunkte" (Entwurf: 112
      lang, endet 31 über der Headline) */
.rule--lead {
  left: 0;
  top: calc(-143 * var(--u));
  height: calc(112 * var(--u));
}

/* 3. ab dem Kartenraster durchgehend. Reicht 41 über das
      Raster hinauf und unten bis an die Bandkante, wo der
      Abschnitt im Expertise-Band nahtlos anschließt. */
.rule--grid {
  left: calc((var(--edge-rule) - var(--edge-cards)) * var(--u));
  top: calc(-41 * var(--u));
  bottom: calc(-1 * var(--focus-pad-bottom) * var(--u));
}
/* Bezug ist hier die Bandkante, nicht der eingerückte Inhalt –
   deshalb die Kante ausdrücklich. + --gutter, weil auch dieser
   Abschnitt absolut im vollbreiten Band sitzt (wie .rule--hero). */
.rule--exp {
  left: calc(var(--gutter) + var(--edge-rule) * var(--u));
  top: 0;
  bottom: 0;
}

/* =========================================================
   ROOFLINE – die Dachsilhouette als Anschnitt
   Nachgemessene Kontur der Hero-Unterkante: flach bis 75%,
   Schräge hoch zur Traufe, Plateau, dann die flachere
   Dachschräge bis zum rechten Rand.
   ========================================================= */
.roofline {
  clip-path: polygon(
    0 0,
    100% 0,
    100%          calc(100% - var(--roof-y2) * var(--u)),
    var(--roof-x3) calc(100% - var(--roof-y1) * var(--u)),
    var(--roof-x2) calc(100% - var(--roof-y1) * var(--u)),
    var(--roof-x1) 100%,
    0 100%
  );
}

/* =========================================================
   BUTTON – Rechteck mit abgeschrägter Ecke oben links

   Die Kontur ist EINE Fläche, kein border plus rotierte Linie:
   ::before wird flächig eingefärbt und per clip-path mit der
   evenodd-Regel innen wieder ausgestanzt – übrig bleibt exakt
   der Rahmen. Die frühere Konstruktion setzte die Schrägkante
   als gedrehtes 1px-Element mit fest eingetragener Länge (38)
   und Winkel (-32deg); beides passte nicht zum Notch (Diagonale
   ist 37,74) und mobil erst recht nicht (dort stand 31 bei einer
   Diagonale von 42,2). An den Knickpunkten standen dadurch die
   Enden der gedrehten Linie über.

   Die Innenkontur ist die um --btn-bw parallel nach innen
   versetzte Außenkontur. Für die Schräge heißt das nicht einfach
   „B einrücken": ihre Schnittpunkte mit den Innenkanten wandern
   um B*(L-X)/Y bzw. B*(L-Y)/X. Deshalb die beiden Rechnungen –
   sie halten die Randstärke über die ganze Schräge konstant.
   Alle Notch-Größen sind einheitenlose Tokens, die Rechnung
   bleibt damit reine Zahlenarithmetik.
   ========================================================= */
.btn {
  /* Eckmaße der Kontur, einmal benannt */
  --btn-l:  hypot(var(--btn-notch-x), var(--btn-notch-y));   /* Länge der Schräge */
  --btn-nx: calc(var(--btn-notch-x) * var(--u));
  --btn-ny: calc(var(--btn-notch-y) * var(--u));
  --btn-b:  calc(var(--btn-bw) * var(--u));
  /* Schnittpunkte der nach innen versetzten Schräge mit den
     Innenkanten – nicht einfach um B eingerückt, sonst liefe die
     Randstärke über die Schräge keilförmig zu. */
  --btn-ix: calc((var(--btn-notch-x) + var(--btn-bw) * (var(--btn-l) - var(--btn-notch-x)) / var(--btn-notch-y)) * var(--u));
  --btn-iy: calc((var(--btn-notch-y) + var(--btn-bw) * (var(--btn-l) - var(--btn-notch-y)) / var(--btn-notch-x)) * var(--u));

  /* Außenkontur – clippt die Hover-Füllung */
  --btn-pts-out: var(--btn-nx) 0, 100% 0, 100% 100%, 0 100%, 0 var(--btn-ny);

  /* Rahmen = Außenring, dann auf den Innenring springen und ihn
     gegenläufig zurücklaufen. Entscheidend: der Sprung endet auf
     demselben Punkt, an dem der Innenring beginnt und schließt –
     Hin- und Rückweg fallen damit exakt aufeinander und schließen
     keine Fläche ein. Ohne diesen doppelt durchlaufenen Steg legt
     evenodd zwei verschiedene Verbindungsstrecken schräg durch den
     Rahmen und löscht die Schräge in ihrer Mitte weg. */
  --btn-pts-frame:
    var(--btn-pts-out),
    var(--btn-nx) 0,                                   /* Außenring schließen */
    var(--btn-ix) var(--btn-b),                        /* Steg nach innen */
    var(--btn-b) var(--btn-iy),
    var(--btn-b) calc(100% - var(--btn-b)),
    calc(100% - var(--btn-b)) calc(100% - var(--btn-b)),
    calc(100% - var(--btn-b)) var(--btn-b),
    var(--btn-ix) var(--btn-b);                        /* Innenring schließen, Steg zurück */

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: calc(var(--btn-h) * var(--u));
  padding: 0 calc(var(--btn-pad) * var(--u));
  font-size: var(--fs-small);
  font-weight: 400;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
  clip-path: polygon(var(--btn-pts-out));
  transition: color var(--t-mid) var(--ease);
}
.btn > span { position: relative; z-index: 3; }

/* Kontur: Fläche minus Innenfläche = Rahmen in einem Stück */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--line);
  clip-path: polygon(evenodd, var(--btn-pts-frame));
  z-index: 2;
}
/* Füllung, die bei Hover von unten einläuft.
   Kontur und Füllung sind bewusst an --line/--fill gebunden und nicht an
   currentColor – sonst färbt sich beim Hover auch der Text mit ein. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--fill);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform var(--t-mid) var(--ease);
  z-index: 1;
}
.btn:hover::after, .btn:focus-visible::after { transform: scaleY(1); }

.btn--light { --line: var(--c-white); --fill: var(--c-white); --ink: var(--c-white); }
.btn--light:hover, .btn--light:focus-visible { --ink: var(--c-blue); }
.btn--dark  { --line: var(--c-blue);  --fill: var(--c-blue);  --ink: var(--c-blue); }
.btn--dark:hover, .btn--dark:focus-visible { --ink: var(--c-white); }

/* =========================================================
   CARD – Weiße Kachel auf sandfarbenem Sektionsgrund.
   Das Bild sitzt randlos oben, der Text hält allseits Innenabstand.
   Die untere Kante der Kachel ist die Hover-Linie (bündig, volle
   Breite), der Pfeil sitzt absolut in der unteren rechten Ecke –
   er zieht die Kachel nicht in die Höhe. Die Höhe kommt aus dem
   Raster (siehe .focus__grid): alle Karten sind gleich hoch, das
   Maß gibt die Karte mit dem längsten Text vor.
   ========================================================= */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--c-white);
}
.card__media {
  display: block;
  overflow: hidden;
  flex: 0 0 auto;
  height: calc(var(--card-img) * var(--u));
}
.card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}

/* Allseitiger Innenabstand, damit der Text nicht am farbigen
   Kartenrand klebt. Der obere Wert ist zugleich der Abstand
   Bild → Headline – gegenüber früher (54) verkleinert. */
.card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  padding: calc(30 * var(--u)) calc(28 * var(--u)) calc(34 * var(--u));
}
.card__title {
  font-size: var(--fs-card-title);
  line-height: 1.22;
}
.card__text {
  margin-top: calc(12 * var(--u));
  font-size: var(--fs-small);
  line-height: calc(30 / 20);   /* Zeilenabstand im Entwurf: 30 */
}
.card__text + .card__text { margin-top: calc(24 * var(--u)); }

/* Link-Affordanz: derselbe Pfeil wie bei „Doppelte Expertise", absolut in
   der unteren rechten Ecke. Absolut, damit er die Kachel nicht in die Höhe
   zieht – der Textblock reserviert unten nur den nötigen Platz (siehe
   a.card .card__body). Beim Hover wandert er nach rechts (wie link-arrow).
   Nur auf verlinkten Karten; die Kontakt-Kachel trägt ihren Button. */
.card__arrow {
  position: absolute;
  right: calc(28 * var(--u));
  bottom: calc(22 * var(--u));
  font-size: calc(26 * var(--u));
  line-height: 1;
  color: var(--c-blue);
  transition: transform var(--t-fast) var(--ease);
}
a.card:hover .card__arrow,
a.card:focus-visible .card__arrow { transform: translateX(calc(10 * var(--u))); }
/* Unterer Freiraum für den absolut gesetzten Pfeil – nur auf den
   verlinkten Karten; die Kontakt-Kachel braucht ihn nicht. */
a.card .card__body { padding-bottom: calc(58 * var(--u)); }

/* Nur die Kontakt-Kachel trägt einen Button. Höhe kommt aus --btn-h
   (einheitlich für alle Buttons). */
.card__btn {
  align-self: flex-start;
  margin-top: calc(40 * var(--u));
}

/* Untere Kante der Kachel: bündig am Kartenboden über die volle Breite,
   füllt sich bei Hover von links nach rechts über die ganze Kachel.
   Bleibt ein eigenes Element (kein border-bottom): nur so trägt sie das
   Selbstzeichnen beim Scrollen und die blaue Hover-Füllung im ::after. */
.card__line {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--c-card-line);
}
.card__line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c-blue);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--t-mid) var(--ease);
}

/* Hover-Affordanz nur auf den verlinkten Karten. Die Kontakt-
   Kachel ist kein Link und darf sich deshalb auch nicht so
   verhalten – deshalb a.card statt .card.

   Der Zoom stand auf 1.045 und war damit die lauteste Bewegung
   der Seite: er zog den Blick stärker an als die Linie, die den
   Hover eigentlich anzeigt. Auf 1.028 atmet das Bild nur noch,
   die Linie bleibt der Hauptakteur. */
a.card:hover .card__media img { transform: scale(1.028); }
a.card:hover .card__line::after,
a.card:focus-visible .card__line::after { transform: scaleX(1); }

/* Kontakt-Kachel: kein Bild. Statt bündig oben (früher padding-top:0)
   jetzt ein etwas größerer oberer Innenabstand, damit der Text auf der
   sandfarbenen Fläche nicht am oberen Rand klebt. */
.card--contact .card__body { padding-top: calc(48 * var(--u)); }

/* =========================================================
   TEXTLINK MIT PFEIL
   ========================================================= */
.link-arrow {
  display: inline-block;
  /* line-height 1, damit der Strich seinen Abstand von der Schrift
     nimmt und nicht von der geerbten Zeilenhöhe – sonst wandert er
     mit jedem Zeilenabstand mit. Der Rest der Differenz zur
     Schriftunterkante steckt in --link-pad (siehe unten). */
  line-height: 1;
  padding-bottom: calc(var(--link-gap) - var(--link-descent));
  font-size: var(--fs-body);
  font-weight: var(--link-weight);
  color: var(--c-blue);
  border-bottom: var(--link-line) solid currentColor;
}
.link-arrow span {
  display: inline-block;
  margin-left: calc(14 * var(--u));
  transition: transform var(--t-fast) var(--ease);
}
.link-arrow:hover span { transform: translateX(calc(10 * var(--u))); }

/* =========================================================
   UNTERSTRICH-HOVER (Navigation, Footer-Links)
   Diese Links tragen im Entwurf keinen ruhenden Strich und sind
   dort auch NICHT fetter gesetzt (nachgemessen: Stammbreite wie
   der Fließtext). Sie übernehmen deshalb nur die Strichlage und
   -stärke des Link-Musters, nicht --link-weight.
   ========================================================= */
/* line-height 1 auch hier: damit endet die Box eine Unterlänge
   unter der Schrift, und der Strich lässt sich – wie beim
   Pfeil-Link – direkt von der Schriftunterkante aus setzen,
   unabhängig von der geerbten Zeilenhöhe (Nav 1.81, Footer 1.68). */
.uline { position: relative; display: inline-block; line-height: 1; }
/* Der Strich läuft in Leserichtung ein und in Leserichtung wieder
   hinaus – er schrumpft nicht dorthin zurück, wo er herkam. Dafür
   liegt der Ursprung im Ruhezustand rechts und wechselt erst beim
   Hover nach links. Man kann das Detail nicht benennen, aber ein
   zurückschnappender Strich wirkt mechanisch, dieser hier nicht. */
.uline::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: calc(var(--link-descent) - var(--link-gap));
  width: 100%; height: var(--link-line);
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform var(--t-fast) var(--ease);
}
.uline:hover::after, .uline:focus-visible::after {
  transform: scaleX(1);
  transform-origin: 0 50%;
}
