/* ==========================================================================
   VLISTA — Sektionen
   Hero mit laufendem Bildfeed, Kategorienraster, Fusszeile.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero — Textteil
   -------------------------------------------------------------------------- */

.vl-hero {
  padding-block: clamp(3rem, 2rem + 6vw, 8rem) clamp(2rem, 1.5rem + 3vw, 4rem);
}

.vl-hero__headline {
  max-width: 18ch;
}

.vl-hero__lede {
  margin-top: var(--vl-gap-6);
  max-width: 42ch;
}

.vl-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-gap-5);
  margin-top: var(--vl-gap-8);
}

/* --------------------------------------------------------------------------
   Feed — Kopfleiste
   -------------------------------------------------------------------------- */

.vl-feed {
  position: relative;
  background-color: var(--vl-paper-shade);
  padding-block: var(--vl-gap-7) var(--vl-gap-9);
  overflow: hidden;
}

.vl-feed__bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-bottom: var(--vl-gap-6);
}

/* --------------------------------------------------------------------------
   Feed — Spalten
   Jede Spalte kappt ihren Inhalt; die Bahn darin wird per JS verschoben.
   -------------------------------------------------------------------------- */

/* Bühne der Bahnen. Die weichen Kanten liegen darüber, nicht am Rand der
   Sektion — sonst verdecken sie die Kopfleiste statt die Schnittkanten. */
.vl-feed__stage {
  position: relative;
  /* Deutlich mehr Rand als die übrigen Sektionen. Zwei Gründe: die Bahnen
     stehen als eigener Block in der Fläche — und der Rand ist die Stelle,
     an der das Mausrad wieder die Seite scrollt statt den Feed (siehe
     scripts/feed.js). Ohne ihn käme man am Feed nicht vorbei. */
  padding-inline: clamp(var(--vl-edge), 12vw, 16rem);
}

.vl-feed__cols {
  display: grid;
  grid-template-columns: repeat(var(--vl-feed-cols, 5), 1fr);
  gap: var(--vl-gap-4);
  /* Deutlich höher als eine reine Bildschirmfläche — die Sektion soll sich
     als eigener Bereich anfühlen, durch den man scrollt, nicht als schmaler
     Streifen zwischen zwei anderen. */
  height: clamp(38rem, 92vh, 68rem);
}

.vl-feed__col {
  position: relative;
  overflow: hidden;
}

/* Zweite und vierte Spalte versetzt anlaufen lassen — das nimmt dem
   Raster die Strenge, ohne unruhig zu wirken. */
.vl-feed__col:nth-child(even) {
  margin-top: var(--vl-gap-7);
}

.vl-feed__track {
  display: flex;
  flex-direction: column;
  gap: var(--vl-gap-5);
  will-change: transform;
}

/* --------------------------------------------------------------------------
   Feed — Kachel
   Drei Ebenen reagieren gleichzeitig auf den Zeiger: Bild, Schleier, Beschriftung.
   -------------------------------------------------------------------------- */

.vl-tile {
  position: relative;
  display: block;
  overflow: hidden;
  background-color: var(--vl-paper-deep);
  cursor: pointer;
  flex: none;
}

/* Vier Formen. Welche eine Kachel bekommt, entscheidet das Seitenverhältnis
   des Motivs — so wird kaum beschnitten, und die Bahnen bekommen von selbst
   einen Rhythmus. Die Masse müssen zu SHAPES in build_feed_images.py passen. */
.vl-tile--hoch     { aspect-ratio: 9 / 16; }
.vl-tile--portrait { aspect-ratio: 4 / 5; }
.vl-tile--quadrat  { aspect-ratio: 1 / 1; }
.vl-tile--quer     { aspect-ratio: 16 / 9; }

.vl-tile__media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.01);
  transition: transform var(--vl-dur-slow) var(--vl-ease);
}

/* Platzhalterfläche, solange keine Motive vorliegen.
   Der Seed staffelt die Tönung, damit die Spalten unterscheidbar bleiben
   und die Laufbewegung sichtbar wird. Entfällt mit den echten Bildern. */
.vl-tile__media--empty {
  display: block;
  background-image:
    repeating-linear-gradient(
      135deg,
      transparent 0 22px,
      rgb(16 16 16 / 0.03) 22px 23px
    ),
    linear-gradient(
      160deg,
      hsl(calc(38 + var(--vl-tile-seed, 0) * 9) 8% 91%),
      hsl(calc(38 + var(--vl-tile-seed, 0) * 9) 6% 84%)
    );
}

.vl-tile:hover .vl-tile__media,
.vl-tile:focus-visible .vl-tile__media {
  transform: scale(1.08);
}

/* Weiche Kanten oben und unten, damit die Bahnen nicht abgeschnitten wirken */
.vl-feed__fade {
  position: absolute;
  inset-inline: 0;
  height: clamp(3rem, 8vh, 6rem);
  z-index: 3;
  pointer-events: none;
}

.vl-feed__fade--top {
  top: 0;
  background: linear-gradient(to bottom, var(--vl-paper-shade), transparent);
}

.vl-feed__fade--bottom {
  bottom: 0;
  background: linear-gradient(to top, var(--vl-paper-shade), transparent);
}

/* --------------------------------------------------------------------------
   Kategorien
   -------------------------------------------------------------------------- */

/* Fünf Rubriken plus das Atelier-Motiv ergeben sechs Zellen. Sechs teilt
   sich glatt durch eins, zwei und drei — bei diesen Spaltenzahlen geht das
   Raster ohne Rest auf, das Motiv ist dann eine Zelle wie jede Karte.

   Die Spaltenzahl steht deshalb fest und wird nicht dem `auto-fit`
   überlassen: Sonst gäbe es Breiten mit fünf oder sechs Spalten, in denen
   die letzte Zeile ein Loch behält. Gemessen wird über eine Behälterabfrage
   die Breite des Rasters selbst — nicht die des Fensters, sonst fallen
   Umbruch und Spaltenwechsel auseinander. Die Schwellen sind jeweils
   n × 20rem plus die Haarlinien-Fugen. */
.vl-cats {
  container-type: inline-size;
}

.vl-cats__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--vl-hairline);
  background-color: var(--vl-rule);
  border-block: var(--vl-hairline) solid var(--vl-rule);
  margin-top: var(--vl-gap-8);
}

/* Eine Spalte: das Motiv bekommt eine eigene Zeile und braucht darin ein
   eigenes Seitenverhältnis — neben ihm steht keine Karte, die die Höhe gibt. */
.vl-cat__bild {
  grid-column: 1 / -1;
  aspect-ratio: 21 / 9;
  margin: 0;
  overflow: hidden;
  background-color: var(--vl-paper-deep);
}

.vl-cat__bild img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Zwei Spalten: 5 + 1 = drei volle Zeilen. Von hier an steht das Motiv neben
   einer Karte, die die Zeilenhöhe vorgibt. */
@container (min-width: 40.1rem) {
  .vl-cats__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .vl-cat__bild {
    grid-column: auto;
    aspect-ratio: auto;
  }
}

/* Drei Spalten: 5 + 1 = zwei volle Zeilen. */
@container (min-width: 60.15rem) {
  .vl-cats__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Vier Spalten: die fünf Karten lassen in der zweiten Zeile drei Zellen
   frei — genau so breit wird das Motiv. Mehr als vier Spalten gibt es nicht;
   bei fünf bliebe die zweite Zeile leer, bei sechs die Karten zu schmal. */
@container (min-width: 80.2rem) {
  .vl-cats__grid {
    grid-template-columns: repeat(4, 1fr);
  }

  .vl-cat__bild {
    grid-column: span 3;
  }
}

.vl-cat {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--vl-gap-5);
  padding: var(--vl-gap-8) var(--vl-gap-7) var(--vl-gap-7);
  background-color: var(--vl-paper);
  min-height: 15rem;
  isolation: isolate;
  transition: background-color var(--vl-dur) var(--vl-ease);
}

/* Zweistimmig: schwere Versalien, darunter die kursive Fortsetzung in der
   Serif. Dieselbe Figur wie in den Schlagzeilen, nur eine Stufe kleiner. */
.vl-cat__name {
  display: block;
  font-family: var(--vl-font-display);
  font-size: var(--vl-size-l);
  font-weight: 700;
  line-height: var(--vl-leading-snug);
  letter-spacing: var(--vl-track-tight);
  text-transform: uppercase;
  margin: 0;
}

.vl-cat__name em {
  display: block;
  font-family: var(--vl-font-accent);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
  text-transform: none;
  transition: color var(--vl-dur) var(--vl-ease);
}

/* Die kursive Fortsetzung des Namens hebt sich beim Hover farbig ab, statt
   nur mit der restlichen Karte auf Weiss zu wechseln. */
.vl-cat:hover .vl-cat__name em,
.vl-cat:focus-within .vl-cat__name em {
  color: var(--vl-signal);
}

.vl-cat__linie {
  width: 100%;
  border: 0;
  border-top: var(--vl-hairline) solid var(--vl-rule);
  margin-block: var(--vl-gap-5) 0;
  transition: border-color var(--vl-dur) var(--vl-ease);
}

.vl-cat:hover .vl-cat__linie,
.vl-cat:focus-within .vl-cat__linie {
  border-color: color-mix(in srgb, var(--vl-paper) 32%, transparent);
}

.vl-cat__note {
  color: var(--vl-ink-mute);
  font-size: var(--vl-size-small);
  line-height: 1.5;
  max-width: 32ch;
  transition: color var(--vl-dur) var(--vl-ease);
}

.vl-cat:hover,
.vl-cat:focus-within {
  background-color: var(--vl-ink);
  color: var(--vl-paper);
}

.vl-cat:hover .vl-cat__note,
.vl-cat:focus-within .vl-cat__note {
  color: color-mix(in srgb, var(--vl-paper) 62%, transparent);
}

/* --------------------------------------------------------------------------
   Fusszeile
   -------------------------------------------------------------------------- */

.vl-footer {
  background-color: var(--vl-night);
  color: var(--vl-night-ink);
  padding-block: var(--vl-gap-9) var(--vl-gap-7);
}

.vl-footer__top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--vl-gap-7);
  padding-bottom: var(--vl-gap-8);
  border-bottom: var(--vl-hairline) solid color-mix(in srgb, var(--vl-night-ink) 18%, transparent);
}

/* Die helle Fassung der Marke — der Schriftzug ist hier in Papierweiß,
   damit er auf der dunklen Fußzeile steht (siehe tools/build_logo.py). */
.vl-footer__marke {
  display: block;
  height: 2.6rem;
  width: auto;
  margin-block: var(--vl-gap-8) var(--vl-gap-7);
  /* Siehe .vl-mark img: die Platzhalterfläche aus reset.css würde hier als
     heller Kasten hinter der freigestellten Marke stehen. */
  background-color: transparent;
}

.vl-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--vl-gap-5);
  padding-top: var(--vl-gap-6);
  color: color-mix(in srgb, var(--vl-night-ink) 55%, transparent);
}

.vl-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-gap-4) var(--vl-gap-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Die Zeile ist klein gesetzt; ohne zusätzliche Höhe bleibt das Tippziel
   unter den 24px, die WCAG 2.2 als Mindestmass nennt. */
.vl-footer__links a {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
}

/* --------------------------------------------------------------------------
   Hero mit vollflächigem Bild
   Greift nur, wenn ein Hero-Motiv vorliegt — ohne es bleibt der Hero
   textbündig über die volle Breite.
   -------------------------------------------------------------------------- */

/* Vollflächiger Hero: Bild als Hintergrund über die gesamte Sektion, die
   Textspalte legt sich rechts darüber — wie ein Titelblatt auf freiem
   Papier. Die Sektion hebt dafür die Einrückung der Hülle auf, das Bild
   soll jede Kante berühren. */
.vl-hero--vollflaeche {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0;
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem);
  /* Rechts mehr Luft als links — die Textspalte rückt dadurch etwas von der
     Kante weg, näher zur Mitte, statt bündig am Rand zu kleben. */
  padding-inline: var(--vl-edge) clamp(3rem, 1rem + 8vw, 11rem);
  max-width: none;
  min-height: clamp(30rem, 82vh, 54rem);
  overflow: hidden;
}

.vl-hero--vollflaeche .vl-hero__text {
  position: relative;
  z-index: 1;
  width: min(30rem, 46%);
}

.vl-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background-color: var(--vl-paper-shade);
  margin: 0;
}

/* Blendet die rechte Seite des Motivs sanft ins Papier über — die
   Fliesstext-Farben sind auf Weiss geeicht (siehe --vl-ink-mute), ein
   Motiv wechselt aber von Bild zu Bild, wie hell oder dunkel es dort
   tatsächlich ist. Ohne diesen Übergang ist der Lauftext nicht bei jedem
   Motiv verlässlich lesbar. */
.vl-hero--vollflaeche .vl-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Drei Verläufe übereinander: rechts fürs Lesbarkeit, oben gegen den
     schwebenden Kopf (sonst setzt das Motiv dort hart gegen den freien
     Kopfbereich ab), unten in die Fläche der nächsten Sektion. */
  background:
    linear-gradient(
      to right,
      transparent 38%,
      color-mix(in srgb, var(--vl-paper) 70%, transparent) 58%,
      color-mix(in srgb, var(--vl-paper) 94%, transparent) 78%
    ),
    linear-gradient(
      to bottom,
      color-mix(in srgb, var(--vl-paper) 55%, transparent) 0%,
      transparent 14%
    ),
    linear-gradient(
      to bottom,
      transparent 84%,
      var(--vl-paper-shade) 100%
    );
}

.vl-hero__video,
.vl-hero__bild {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Das Motiv sitzt links im Bild, rechts bleibt der Freiraum für den
     Text — daher hält object-position die linke Kante fest, statt zu
     zentrieren und das Motiv anzuschneiden. */
  object-position: left center;
}

/* Im vollflächigen Hero steht die Schlagzeile schmaler als sonst, sonst
   bräche sie unter dem Text ins Bild aus. */
.vl-hero--vollflaeche .vl-hero__headline {
  font-size: clamp(1.8rem, 0.4rem + 4vw, 4.2rem);
  max-width: none;
}

/* Der Vorspann steht sonst in abgetöntem Schwarz — das ist auf weisses
   Papier gerechnet. Im Hero liegt er über dem Motiv und braucht die volle
   Schriftfarbe, um sich zu behaupten. */
.vl-hero__lede {
  color: var(--vl-ink);
}


.vl-hero__linie {
  /* Als Flex-Element zieht sich ein hr nicht von selbst auf. */
  width: 100%;
  border: 0;
  border-top: var(--vl-hairline) solid var(--vl-rule);
  margin-block: var(--vl-gap-7) 0;
}

/* Herkunftsvermerk am unteren Bildrand, wie eine Bildunterschrift im Satz. */
.vl-hero__bildnote {
  position: absolute;
  inset-inline: var(--vl-gap-6);
  bottom: var(--vl-gap-5);
  color: color-mix(in srgb, var(--vl-paper) 78%, transparent);
  text-shadow: 0 1px 6px rgb(16 16 16 / 0.45);
  pointer-events: none;
}

/* Wer Bewegung abbestellt hat, bekommt das Standbild. Das Anhalten
   übernimmt scripts/main.js — `autoplay` allein liesse sich nicht
   zurücknehmen. */
@media (prefers-reduced-motion: reduce) {
  .vl-hero__video {
    /* Poster bleibt sichtbar, sobald das Video pausiert ist. */
    animation: none;
  }
}

@media (max-width: 900px) {
  .vl-hero--vollflaeche {
    display: block;
    padding: 0;
    min-height: 0;
  }

  .vl-hero--vollflaeche .vl-hero__media {
    position: static;
    aspect-ratio: 4 / 5;
  }

  .vl-hero--vollflaeche .vl-hero__text {
    width: auto;
    padding: clamp(2rem, 1.5rem + 3vw, 3rem) var(--vl-edge);
  }
}

/* Kennzeichnung am Atelierbild: an der unteren Kante, hell auf dem Motiv. */
.vl-cat__bild {
  position: relative;
  margin: 0;
}

.vl-cat__bild-ki {
  position: absolute;
  inset-inline: var(--vl-gap-5);
  bottom: var(--vl-gap-4);
  color: color-mix(in srgb, var(--vl-paper) 78%, transparent);
  text-shadow: 0 1px 6px rgb(16 16 16 / 0.45);
  pointer-events: none;
}
