/*
 * startseite.css – Hero, Logos, Projektzeilen (docs/ENTWURF.md 4.2)
 *
 * Umbrüche: breit ≥ 1100 px · mittel 700–1099 px · schmal < 700 px.
 * Voransicht, Träger und Platz stehen in projektansicht.css, weil Archiv und
 * Projektansicht sie ebenfalls brauchen.
 */

/* ------------------------------------------------------------------------
   Hero: Gruß und Vorspann, Spalten 1–4
   ------------------------------------------------------------------------ */

.hero {
  padding-top: clamp(140px, 24vh, 260px);
  padding-bottom: var(--abstand-sektion);
}

.hero__text {
  grid-column: 1 / -1;
  font-size: var(--t-l);
  line-height: var(--zh-l);
  letter-spacing: var(--lw-l);
}

/* Eigene Zeile mit fester Höhe: Der Wechsel der Grüße verschiebt nichts.
   Die Zeile ist zugleich die Maske; etwas Luft nach unten für Unterlängen. */
.hero__gruss {
  position: relative;
  height: calc(var(--zh-l) * 1em + .14em);
  margin-bottom: -.14em;
  overflow: hidden;
  color: var(--text-2);
}

.hero__gruss-wort {
  display: block;
  white-space: nowrap;
}

/* Während des Wechsels liegt der neue Gruß über dem alten. */
.hero__gruss-wort + .hero__gruss-wort {
  position: absolute;
  top: 0;
  left: 0;
}

.hero__vorspann {
  text-wrap: pretty;
}

/* Mittel (700–1099): sieben Spalten, damit der Satz nicht in Silben zerfällt;
   ab 1100 px ein Drittel der Spalten (4 von 12), siehe unten. */
@media (min-width: 700px) {
  .hero__text {
    grid-column: 1 / span 7;
  }
}

@media (min-width: 1100px) {
  /* Das erste Fenster zeigt Kopfzeile, Hero und beide Logoreihen: Der Hero
     füllt, was Kopfzeile (--kopf) und Logos (--logos) vom Fenster übrig
     lassen. Auf niedrigen Fenstern gilt der gewöhnliche Abstand. */
  .hero {
    /* 12 px Rand + Etikett und drei Leistungen (je 20 px) mit 3 × 4 px Luft (basis.css) */
    --kopf: 104px;
    /* Etikett + Abstand + zwei Kachelreihen (Kachel 2:1, also Höhe = halbe Breite) + Seitenrand */
    --logos: calc(20px + 12px + (100vw - 2 * var(--rand) - 7 * var(--spalt)) / 8 + var(--spalt) + var(--rand));
    min-height: calc(100svh - var(--kopf) - var(--logos));
    padding-bottom: clamp(64px, 9vh, var(--abstand-sektion));
  }

  /* Ein Drittel der Spalten: 1–4 von 12 */
  .hero__text {
    grid-column: 1 / span 4;
  }
}

/* ------------------------------------------------------------------------
   Logos: 2 × 8 in gleich großen Zellen mit demselben Abstand wie überall
   (12 px), das Logo steht mittig, ohne Fläche und ohne Rahmen. Das 8er-Raster
   mit gleichem Spaltenabstand trifft jede zweite Zelle exakt auf eine
   Viertel-Linie des 12er-Rasters.
   ------------------------------------------------------------------------ */

.logos {
  row-gap: 12px;
}

.logos__etikett {
  grid-column: 1 / -1;
  color: var(--text-2);
}

.logos__raster {
  /* Stufe des Größenausgleichs: --lb und --lh gelten für B = 46 px. */
  --logo-stufe: calc(28 / 46);
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--spalt);
}

.logos__zelle {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
}

/* Gleiche Fläche für alle; breite Logos enden bei 66 % der Kachelbreite,
   hohe bei 46 % der Kachelhöhe. */
.logos__logo {
  width: min(calc(var(--lb) * var(--logo-stufe)), calc(66% * var(--lm, 1)));
  height: auto;
  max-height: 46%;
  object-fit: contain;
}

[data-thema="dunkel"] .logos__logo {
  filter: invert(1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-thema]) .logos__logo {
    filter: invert(1);
  }
}

@media (min-width: 700px) {
  .logos__raster {
    --logo-stufe: calc(40 / 46);
  }

  .logos__zelle {
    aspect-ratio: 2 / 1;
  }

  .logos__logo {
    width: min(calc(var(--lb) * var(--logo-stufe)), calc(64% * var(--lm, 1)));
  }
}

@media (min-width: 1100px) {
  .logos__raster {
    grid-template-columns: repeat(8, minmax(0, 1fr));
  }
}

/* ------------------------------------------------------------------------
   Projekte: Etikett, Zeilen, Knopf ins Archiv
   ------------------------------------------------------------------------ */

.projekte {
  margin-top: var(--abstand-sektion);
}

.projekte__etikett {
  grid-column: 1 / -1;
  margin-bottom: 12px;
  color: var(--text-2);
}

.projekte__fuss {
  position: relative;
  padding-top: 24px;
}

.projekte__knopf {
  grid-column: 1 / -1;
  justify-self: start;
}

/* Haarlinie als eigenes Element, damit sie sich zeichnen kann. */
.projekt-zeile__linie,
.projekte__linie {
  position: absolute;
  top: 0;
  right: var(--rand);
  left: var(--rand);
  height: 1px;
  background: var(--linie);
}

/* Eine Zeile ist ein Link. Schmal: Info oben, darunter das Mosaik. */
.projekt-zeile {
  position: relative;
  row-gap: 12px;
  padding-block: 12px 48px;
}

/* Die Zeile reicht von Rand zu Rand, ein Ring um sie wäre abgeschnitten:
   Er sitzt um den Projektnamen, wie bei jedem anderen Textlink. */
.projekt-zeile:focus-visible {
  outline: none;
}

.projekt-zeile:focus-visible .projekt-zeile__name {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

.projekt-zeile__info {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  align-items: start;
}

.projekt-zeile__kopf {
  grid-column: 1 / span 6;
}

.projekt-zeile__name {
  width: fit-content;
  font-weight: 600;
}

.projekt-zeile__jahr,
.projekt-zeile__leistungen {
  color: var(--text-2);
}

/* Erster Satz der Beschreibung unter Name und Jahr – wie im Archiv nur breit
   (ENTWURF 4.2, Nachtrag 4. 10. 2026) */
.projekt-zeile__satz {
  display: none;
  color: var(--text-2);
}

/* „Coming soon“: keine Verknüpfung, kein Öffnen – die Zeile ist ein div mit
   dem Zeigeretikett „Coming soon“; die Leistungen bleiben ruhig. */
.projekt-zeile--bald {
  cursor: default;
}

.projekt-zeile--bald:hover .projekt-zeile__leistungen {
  color: var(--text-2);
}

.projekt-zeile__leistungen {
  grid-column: 7 / span 6;
  transition: color .1s linear;
}

@media (hover: hover) {
  .projekt-zeile:hover .projekt-zeile__leistungen {
    color: var(--text);
  }
}

.projekt-zeile__bilder {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  row-gap: 12px;
}

.projekt-zeile__vorschau {
  grid-column: span 6;
}

/* Mosaik: die erste Voransicht in voller Breite und quadratisch. */
.projekt-zeile__bilder > .projekt-zeile__vorschau:first-child {
  grid-column: 1 / -1;
  aspect-ratio: 1 / 1;
}

@media (min-width: 700px) {
  .projekt-zeile__kopf {
    grid-column: 1 / span 4;
  }

  .projekt-zeile__leistungen {
    grid-column: 5 / span 8;
  }

  /* Ab 700 px: alle drei Voransichten gleich hoch, jede im Seitenverhältnis
     ihres Mediums (--ar aus teile/projekt_zeile.php). Der Behälter ist eine
     Flex-Reihe; jede Zelle wächst mit ihrem Verhältnis (flex-grow = Breite/Höhe,
     Basis 0), die Breiten verhalten sich also wie die Verhältnisse, und mit
     aspect-ratio ergibt sich für alle dieselbe Höhe. Zusammen füllen sie die
     Reihe genau, beide Kanten bleiben auf dem Raster. Zelle und Platz der
     Projektansicht haben dasselbe Verhältnis, der Ausschnitt steht im Flug
     (ENTWURF 4.2, 4.3). Ohne Maße 4:5. Zwei Klassen, weil .vorschau in
     projektansicht.css (lädt nach dieser Datei) 4:5 vorgibt. */
  .projekt-zeile__bilder {
    display: flex;
    gap: var(--spalt);
    align-items: flex-start;
  }

  .projekt-zeile .projekt-zeile__vorschau,
  .projekt-zeile__bilder > .projekt-zeile__vorschau:first-child {
    flex: calc(var(--ar, .8)) 1 0;
    min-width: 0;
    aspect-ratio: var(--ar, 4 / 5);
  }

  /* Eine einzelne Voransicht füllt nicht die ganze Reihe. */
  .projekt-zeile__bilder > .projekt-zeile__vorschau:only-child {
    flex-grow: 0;
    width: 50%;
  }
}

@media (min-width: 1100px) {
  .projekt-zeile {
    row-gap: 0;
  }

  /* Infospalte so hoch wie die Bilder: Name und Jahr oben, Leistungen unten.
     Die Versalien des Namens schließen mit der Oberkante der Voransichten ab,
     die Grundlinie der Leistungen mit ihrer Unterkante (wie im Archiv). */
  .projekt-zeile__info {
    grid-column: span 3;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    margin-top: calc(-1 * var(--kappe-m));
    margin-bottom: calc(-1 * var(--sockel-m));
  }

  .projekt-zeile__bilder {
    grid-column: 4 / -1;
  }

  /* Breit: der erste Satz der Beschreibung unter Name und Jahr (wie im Archiv) */
  .projekt-zeile__satz {
    display: block;
    margin-top: 12px;
  }

  .projekte__knopf {
    grid-column: 1 / span 3;
  }
}

@media (prefers-reduced-motion: reduce) {
  .projekt-zeile__leistungen {
    transition: none;
  }
}

/* ------------------------------------------------------------------------
   Leistungen (4.2, Sektion 4): Etikett und Einleitungssatz, darunter links
   die klebende Grafikfläche mit einem Medium je Leistung, rechts die Liste
   mit Haarlinien. Der aktive Eintrag (Klasse ist-aktiv, modul/leistungen.js;
   ohne Skript Hover und Fokus) trägt ein invertiertes Etikett, das von links
   aufgeht; in der Fläche blendet sein Medium ein.

   Drei Lagen: schmal oder ohne feinen Zeiger (Grundzustand): Grafik 3:2 in
   voller Breite, Liste darunter · mittel mit Maus: Grafik Sp. 1–5, Liste
   Sp. 6–12, Satz unter dem Namen · breit mit Maus: Liste Sp. 7–12, Name
   Sp. 7–8, Satz Sp. 9–12, Grafik 4:5 klebend.
   ------------------------------------------------------------------------ */

.leistungen {
  margin-top: var(--abstand-sektion);
}

.leistungen__kopf {
  row-gap: 12px;
}

.leistungen__etikett {
  grid-column: 1 / -1;
  color: var(--text-2);
}

.leistungen__einleitung {
  grid-column: 1 / span 10;
  font-size: var(--t-l);
  line-height: var(--zh-l);
  letter-spacing: var(--lw-l);
}

.leistungen__koerper {
  row-gap: 12px;
  align-items: start;
  margin-top: var(--abstand-block);
}

/* Grafikfläche: alle Medien liegen übereinander, nur das aktive ist zu sehen.
   Immer im Hochformat 3:4 (ENTWURF 4.2, Sektion 4). Der Halter ist die
   Rasterzelle; schmal oder ohne feinen Zeiger steht die Fläche in voller
   Breite über der Liste. */
.leistungen__halter {
  grid-column: 1 / -1;
}

.leistungen__buehne {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--flaeche);
}

.leistungen__bild {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(1.03);
}

/* Das neue Medium blendet über dem alten ein (.35 s, 1.03 → 1); das alte
   bleibt so lange voll sichtbar darunter (Klasse „bleibt“, das Skript setzt
   die Ebene), damit die Fläche zwischendurch nicht durchscheint. Ohne
   Übergang im Grundzustand: Was verdeckt ist, verschwindet still. */
.leistungen__bild.ist-aktiv,
.leistungen__bild.bleibt {
  opacity: 1;
  transform: none;
  transition: opacity .35s var(--ease-aus), transform .35s var(--ease-aus);
}

.leistungen__bild > .medium {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
}

/* Liste: Haarlinie oben als eigenes Element, die letzte Zeile auch unten. */
.leistungen__liste {
  grid-column: 1 / -1;
}

.leistungen__zeile {
  position: relative;
  padding-block: 14px;
}

.leistungen__linie {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 1px;
  background: var(--linie);
}

.leistungen__linie--unten {
  top: auto;
  bottom: 0;
}

.leistungen__name {
  font-weight: 600;
}

/* Der Link ist der Name; seine Trefferfläche deckt die ganze Zeile. Das
   Etikett ist die Auszeichnung, keine Unterstreichung; der Fokusring sitzt um
   das Etikett. (Die Leistungsliste des Profils zeigt dieselben Leistungen
   ohne Link, ENTWURF 4.5.) */
.leistungen__link,
.leistungen__link:hover {
  text-decoration-line: none;
}

.leistungen__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.leistungen__link:focus-visible {
  outline: none;
}

.leistungen__link:focus-visible .leistungen__wort {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

/* Das Wort mit dem Polster des Etiketts (2 px 6 px), nach außen wieder
   abgezogen: Der Text bleibt auf der Rasterlinie, die Zeile bleibt 20 px. */
.leistungen__wort {
  position: relative;
  display: inline-block;
  padding: 2px 6px;
  margin: -2px -6px;
  white-space: nowrap;
}

/* Invertiertes Etikett: eine deckungsgleiche Kopie des Wortes (aria-hidden),
   von links aufgedeckt. clip-path statt Breite oder Skalierung: Die Ecken
   bleiben rund, es wird nur transform/opacity/clip-path bewegt (ENTWURF 5). */
.leistungen__invers {
  position: absolute;
  inset: 0;
  padding: 2px 6px;
  border-radius: var(--radius);
  background: var(--text);
  color: var(--grund);
  clip-path: inset(0 100% 0 0);
  transition: clip-path .25s var(--ease-aus);
  pointer-events: none;
  user-select: none;
}

.leistungen__zeile.ist-aktiv .leistungen__invers {
  clip-path: inset(0 0 0 0);
}

.leistungen__satz {
  margin-top: 4px;
  color: var(--text-2);
  transition: color .25s var(--ease-aus);
}

.leistungen__zeile.ist-aktiv .leistungen__satz {
  color: var(--text);
}

/* Ohne JavaScript setzt niemand ist-aktiv: dann zeigen Hover und Fokus das
   Etikett. Mit Skript gilt allein ist-aktiv, sonst stünden zwei Etiketten,
   wenn der Zeiger ruht und die Tastatur oder die Automatik weiterschaltet. */
html:not(.js) .leistungen__zeile:focus-within .leistungen__invers {
  clip-path: inset(0 0 0 0);
}

html:not(.js) .leistungen__zeile:focus-within .leistungen__satz {
  color: var(--text);
}

@media (hover: hover) {
  html:not(.js) .leistungen__zeile:hover .leistungen__invers {
    clip-path: inset(0 0 0 0);
  }

  html:not(.js) .leistungen__zeile:hover .leistungen__satz {
    color: var(--text);
  }
}

/* In der Projektansicht verschwindet der Text der Seite dahinter
   (projektansicht.css setzt die Textvariablen auf transparent); die Kopie im
   Etikett trägt --grund und braucht die Regel gesondert. */
html.projekt-offen .leistungen__invers {
  color: transparent;
}

/* Mittel und breit mit Maus: Grafik links (mittel Spalte 1–5, breit 1–3),
   Liste daneben. Die Höhe der Grafik richtet sich nach der Liste: Der Halter
   ist ein Größen-Container (container-type: size nimmt die Grafik aus der
   Zeilenhöhe heraus, align-self: stretch gibt ihm die Höhe der Liste); die
   Grafik bleibt 3:4 und ist so hoch wie die Liste, solange das in die Spalten
   passt – sonst so breit wie die Spalten und entsprechend niedriger (klebt
   dann 12 px unter dem oberen Rand, solange die Liste höher ist). */
@media (min-width: 700px) and (hover: hover) {
  .leistungen__koerper {
    row-gap: 0;
  }

  .leistungen__halter {
    grid-column: 1 / span 5;
    align-self: stretch;
    container-type: size;
  }

  .leistungen__buehne {
    position: sticky;
    top: 12px;
    width: min(100%, calc(100cqh * 3 / 4));
  }

  .leistungen__liste {
    grid-column: 6 / -1;
  }
}

/* Breit mit Maus: Etikett neben der Einleitung, Liste ab Linie 7 im Subraster
   (Name Spalte 7–8, Satz Spalte 9–12). */
@media (min-width: 1100px) and (hover: hover) {
  .leistungen__kopf {
    align-items: start;
  }

  /* Die Versalien des Etiketts hängen an der Versalhöhe der Einleitung:
     Kappe der Einleitung (--t-l, 1.18) minus Kappe der Standardschrift. */
  .leistungen__etikett {
    grid-column: 1 / span 3;
    margin-top: calc(var(--t-l) * (var(--zh-l) / 2 - .344) - var(--kappe-m));
  }

  /* Einleitung und Liste beginnen in Spalte 4 (Nachtrag 3. 10. 2026) */
  .leistungen__einleitung {
    grid-column: 4 / -1;
  }

  /* Breit: Grafik quadratisch, so hoch wie die Liste, solange das in die
     Zelle Spalte 1–3 passt – sonst so breit wie die Zelle (bei 1440 px
     345 × 345 gegen 384 px Liste) und klebt, wenn die Liste höher ist. */
  .leistungen__halter {
    grid-column: 1 / span 3;
  }

  .leistungen__buehne {
    width: min(100%, 100cqh);
    aspect-ratio: 1 / 1;
  }

  .leistungen__liste {
    grid-column: 4 / -1;
    display: grid;
    grid-template-columns: subgrid;
  }

  .leistungen__zeile {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: subgrid;
    align-items: start;
  }

  /* Name Spalte 4–5, Satz Spalte 6–12 */
  .leistungen__name {
    grid-column: 1 / span 2;
  }

  .leistungen__satz {
    grid-column: 3 / -1;
    margin-top: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Die Fläche blendet weiter (ENTWURF 7: Überblenden ist erlaubt), ohne Skalierung. */
  .leistungen__bild {
    transform: none;
  }

  .leistungen__bild.ist-aktiv,
  .leistungen__bild.bleibt {
    transition: opacity .35s var(--ease-aus);
  }

  .leistungen__invers,
  .leistungen__satz {
    transition: none;
  }
}
