/* ===========================================================================
   Leinwand – Aufhänger und Rolle
   ---------------------------------------------------------------------------
   Eine Leinwand, die oben an einer Rolle hängt. Dieser Teil ist nur der
   Aufhänger mit der Rolle; das Tuch kommt HINTER der Rolle heraus (nicht
   vorne wie im Foto), die Rolle bleibt also immer sichtbar davor.

   Alles stammt aus dem Foto (freisteller-bauen.py schneidet es frei) und
   wird aus drei Stücken zusammengesetzt:

        [ links ][ ---- Mitte, wird gedehnt ---- ][ rechts ]

   Links und rechts behalten ihr Seitenverhältnis (Halter, Klammer), nur die
   Mitte wird breiter oder schmaler. So bleibt die Rolle bei jeder Breite
   stimmig. masse.css enthält alle Maße der Stücke.

   EINE stetige Regel, kein Umschaltpunkt: Die Breite folgt dem Fenster, die
   Rollenhöhe wächst dabei nur langsam und ist begrenzt. Auf großen Bildschirmen
   wird so nur die Mitte breiter, Rolle, Halter und Kette bleiben gleich groß. Auf
   dem Handy bleiben die Enden größer, als es die reine Proportion ergäbe, und
   die Mitte gibt nach.

   ÜBERGREIFEND gilt die Körnung (koernung.css), die über allem liegt. Sie
   verschmilzt Foto-Ausschnitte und Seitenfarbe zu einer Aufnahme.
   =========================================================================== */

.leinwand {
  /* Seitenrand links und rechts, je in Prozent der Breite. */
  --rand: 1.5;
  /* Rollenhöhe: Auf dem Handy (ab 335 px Breite) --rolle-min, danach wächst sie nur
     langsam mit der Breite (--rolle-zuwachs je Pixel Breite) und hört bei
     --rolle-max auf. So wird nur die Mitte breiter, nicht die ganze Rolle größer:
     Auf großen Bildschirmen bleiben Rolle, Halter und Kette in ihrer Größe. */
  /* Festgelegt am 17.10.2026 mit Daniel. Hinweis: Das Maximum (31) liegt unter dem
     Minimum (34), und dann gewinnt in clamp() das Minimum. Die Rolle ist also
     überall 34 px hoch und nur die Mitte wird breiter. */
  --rolle-min: 34px;
  --rolle-max: 31px;
  --rolle-zuwachs: .017;
  /* Wie weit das Tuch heraus ist. Die Abrollanimation setzt das später. */
  --tuch-laenge: 0px;
  --oben-q: -51.6;
  /* Kette: Lila (Kachel aus dem Foto, umgefärbt), damit sie zu Logo und Video passt.
     --kette-ton dreht den Farbton in Grad (0 = Lila). Der Faktor sagt, wie weit die
     Glieder rutschen, wenn das Tuch um 1 px herausfährt. */
  --kette-ton: 0deg;
  --kette-faktor: .5;
  /* Wie stark sich die Tuchkanten biegen: 0 = Lineal, 1 = Standard. */
  --kante-staerke: .25;
  /* Wie hell das Weiß ist. 1 = wie im Foto (grell), darunter wirkt es wie Stoff in
     einem dunklen Raum. Rolle und Tuch getrennt, damit sich beide abstimmen lassen. */
  --weiss-rolle: .9;
  --weiss-tuch: .86;

  container-type: inline-size;   /* cqw = Breite des Containers, nicht des Fensters */
  position: relative;
}

.leinwand__rahmen {
  --breite: calc(100cqw * (100 - 2 * var(--rand)) / 100);
  --rh: clamp(
    var(--rolle-min),
    calc(var(--rolle-min) + (var(--breite) - 335px) * var(--rolle-zuwachs)),
    var(--rolle-max)
  );
  /* Länge eines Quellpixels auf dem Bildschirm. */
  --e: calc(var(--rh) / var(--q-rolle-h));

  position: relative;
  width: var(--breite);
  margin-inline: auto;
  /* Abstand zum oberen Seitenrand, in Quellpixeln (wächst mit der Rolle mit).
     0 = die Halter sitzen ganz oben, negativ = sie ragen über den Rand hinaus,
     als kämen sie von weiter oben. -51 entspricht etwa -32 px bei 1440 px Breite. */
  margin-top: calc(var(--e) * var(--oben-q));
  /* Das Tuch verlängert die Seite: Wer weiter herausfährt, kann nach unten scrollen. */
  margin-bottom: var(--tuch-laenge);
}

/* --- Rolle: drei Stücke, alle gleich hoch ---------------------------------- */
.leinwand__rolle {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns:
    calc(var(--e) * var(--q-links-b))
    1fr
    calc(var(--e) * var(--q-rechts-b));
  height: calc(var(--e) * var(--q-stueck-h));
  filter: brightness(var(--weiss-rolle));
}
.leinwand__rolle img { display: block; width: 100%; height: 100%; }

/* Die Mitte wird nur in der Breite gedehnt. Zwei Pixel Überlappung auf jeder
   Seite, damit zwischen den Stücken nie eine Naht aufblitzt. */
.leinwand__mitte {
  position: relative;
}
.leinwand__mitte::before {
  content: "";
  position: absolute;
  inset: 0 -2px;
  background: url("bilder/rolle-mitte.webp") 0 0 / 100% 100% no-repeat;
}

/* --- Kette: zwei Stränge, bewegt sich mit dem Tuch und schwingt ----------------------
   Wie im Foto läuft sie als Schlaufe: Fährt das Tuch heraus, rutscht der vordere
   Strang nach unten und der hintere gleich weit nach oben. Beide sind dieselbe
   Foto-Kachel (siehe freisteller-bauen.py); die Glieder verschieben sich im Strang.

   SIE HÄNGT NICHT STARR. Eine Kette ist biegsam: Sie besteht aus drei Abschnitten,
   die ineinander gehängt sind. Jeder pendelt ein wenig, und zwar zeitversetzt und
   mit anderer Dauer, nach unten zu stärker. Dadurch biegt sie sich beim Schwingen
   wie eine echte Kette, statt als Stab zu pendeln. --kette-schwung (1 = Ruhe) lässt
   sie stärker schwingen, solange sich das Tuch bewegt, und sie beruhigt sich danach.
   Gedreht wird mit der Eigenschaft rotate (nicht transform), damit sich nichts
   gegenseitig überschreibt. */
@property --kette-schwung {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

.leinwand__kette {
  --abschnitt: calc(var(--e) * var(--q-kette-h) / 3);
  position: absolute;
  z-index: 3;
  left: calc(var(--e) * var(--q-kette-x));
  top:  calc(var(--e) * var(--q-kette-oben));
  width:  calc(var(--e) * var(--q-kette-b));
  height: var(--abschnitt);
  filter: hue-rotate(var(--kette-ton));
}
.leinwand--ohne-kette .leinwand__kette { display: none; }

.kette__teil {
  position: absolute;
  left: 0; width: 100%;
  height: var(--abschnitt);
  transform-origin: 50% 0;
}
.kette__teil--1 { top: 0;    --teil-y: 0px;                           animation: kette-pendel-1 7.9s ease-in-out infinite; }
.kette__teil--2 { top: 100%; --teil-y: var(--abschnitt);              animation: kette-pendel-2 6.7s ease-in-out -1.3s infinite; }
.kette__teil--3 { top: 100%; --teil-y: calc(var(--abschnitt) * 2);    animation: kette-pendel-3 5.9s ease-in-out -2.4s infinite; }

@keyframes kette-pendel-1 {
   0%, 100% { rotate: calc(var(--kette-schwung) * -.45deg); }
  31%       { rotate: calc(var(--kette-schwung) *  .70deg); }
  58%       { rotate: calc(var(--kette-schwung) * -.20deg); }
  82%       { rotate: calc(var(--kette-schwung) *  .55deg); }
}
@keyframes kette-pendel-2 {
   0%, 100% { rotate: calc(var(--kette-schwung) *  .80deg); }
  27%       { rotate: calc(var(--kette-schwung) * -.90deg); }
  64%       { rotate: calc(var(--kette-schwung) *  .30deg); }
  86%       { rotate: calc(var(--kette-schwung) * -.60deg); }
}
@keyframes kette-pendel-3 {
   0%, 100% { rotate: calc(var(--kette-schwung) * -1.30deg); }
  23%       { rotate: calc(var(--kette-schwung) *  1.60deg); }
  52%       { rotate: calc(var(--kette-schwung) * -.70deg); }
  79%       { rotate: calc(var(--kette-schwung) *  1.00deg); }
}
/* Die Stränge schwingen zusätzlich ein wenig für sich, gegenläufig: So wird der
   Spalt zwischen ihnen lebendig und sie wirken nicht wie ein Block. */
.leinwand__strang { transform-origin: 50% 0; }
@keyframes kette-strang-a {
   0%, 100% { rotate: calc(var(--kette-schwung) * -.25deg); }
  47%       { rotate: calc(var(--kette-schwung) *  .35deg); }
  78%       { rotate: calc(var(--kette-schwung) * -.10deg); }
}
@keyframes kette-strang-b {
   0%, 100% { rotate: calc(var(--kette-schwung) *  .30deg); }
  39%       { rotate: calc(var(--kette-schwung) * -.35deg); }
  73%       { rotate: calc(var(--kette-schwung) *  .15deg); }
}
@media (prefers-reduced-motion: reduce) {
  .kette__teil, .leinwand__strang { animation: none; }
}

.leinwand__strang {
  --versatz: 0px;
  position: absolute;
  top: 0; bottom: 0;
  width: calc(var(--e) * var(--q-kette-streng-b));
  /* --teil-y hält die Glieder über die Abschnittsgrenzen hinweg durchgehend */
  background: url("bilder/kette.webp") 0 calc(var(--versatz) - var(--teil-y)) / 100% calc(var(--e) * var(--q-kette-teilung)) repeat-y;
}
.leinwand__strang--vorn {
  left: 0;
  --versatz: calc(var(--tuch-laenge) * var(--kette-faktor));
  animation: kette-strang-a 8.3s ease-in-out infinite;
}
/* Der hintere Strang hängt daneben (kleiner Spalt), ist dunkler und um ein halbes Glied versetzt. */
.leinwand__strang--hinten {
  right: 0;
  --versatz: calc(var(--e) * var(--q-kette-teilung) * .5 - var(--tuch-laenge) * var(--kette-faktor));
  filter: brightness(.66) saturate(.9);
  animation: kette-strang-b 9.7s ease-in-out -2.2s infinite;
}

/* Unten wie im Foto: Jeder Strang endet in einer schwarzen Kunststoffklemme, ein Steg
   verbindet beide zur Schlaufe. Hängt am untersten Abschnitt und schwingt mit. */
.kette__klemme {
  position: absolute;
  top: 100%;
  width: calc(var(--e) * 17);
  height: calc(var(--e) * 13);
  margin-top: calc(var(--e) * -2);
  border-radius: calc(var(--e) * 2.5) calc(var(--e) * 2.5) calc(var(--e) * 4) calc(var(--e) * 4);
  background:
    linear-gradient(to right, rgba(255,255,255,.14), rgba(255,255,255,0) 40%, rgba(0,0,0,.4)),
    #1c1a21;
  box-shadow: 0 calc(var(--e) * 1) calc(var(--e) * 2) rgba(0,0,0,.55);
}
.kette__klemme--vorn   { left: 0; }
.kette__klemme--hinten { right: 0; filter: brightness(.8); }
.kette__steg {
  position: absolute;
  top: 100%;
  left: calc(var(--e) * 7);
  right: calc(var(--e) * 7);
  height: calc(var(--e) * 6);
  margin-top: calc(var(--e) * 8);
  border-radius: 0 0 calc(var(--e) * 5) calc(var(--e) * 5);
  background:
    linear-gradient(to bottom, rgba(255,255,255,.18), rgba(255,255,255,0) 50%, rgba(0,0,0,.35)),
    #4a3070;
}

/* --- Tuch: kommt HINTER der Rolle heraus ------------------------------------ */
.leinwand__tuch {
  position: absolute;
  z-index: 1;
  left:  calc(var(--e) * (var(--q-kante-links)  + 7));
  right: calc(var(--e) * (var(--q-kante-rechts) + 7));
  top:   calc(var(--e) * (var(--q-oben) + 6));
  /* Reicht immer bis knapp hinter den Saum. Eingerollt steckt es dadurch
     ganz hinter Rolle und Saum. */
  height: calc(var(--e) * (var(--q-saum-oben) + 2 - var(--q-oben) - 6) + var(--tuch-laenge));
  /* Schatten der Rolle auf dem Tuch: beginnt weich an der Rollenunterkante (das
     Tuch steckt oben hinter der Rolle) und ist immer gleich groß, egal wie weit
     das Tuch heraus ist. Dazu fällt das Licht zu den Seiten hin leicht ab. */
  --schatten-start: calc(var(--e) * (var(--q-rolle-h) - 6));

  /* Seitenkanten mit ruhiger Welle statt Lineal. Die Maske besteht aus der Mitte
     und zwei Kantenstreifen, die sich nach unten wiederholen. Sie wandert mit dem
     Tuch (--tuch-laenge), die Falten fahren also mit heraus. */
  --kante-b: calc(var(--e) * var(--q-kante-b) * var(--kante-staerke));
  --kante-h: calc(var(--e) * var(--q-kante-h));
  /* Die Mitte überlappt die Kantenstreifen. Stießen beide genau aneinander, ergäbe sich
     bei Bruchteilen von Pixeln eine dünne dunkle Naht (zwei halb gedeckte Pixel addieren
     sich nicht zu voll). Die Welle reicht höchstens bis 0,59 der Streifenbreite, die Mitte
     beginnt bei 0,62: dort ist der Streifen schon überall deckend, es gibt keine Naht. */
  --kante-ueb: calc(var(--kante-b) * .62);
  -webkit-mask:
    linear-gradient(#000, #000) var(--kante-ueb) 0 / calc(100% - 2 * var(--kante-ueb)) 100% no-repeat,
    var(--tuch-kante-links)  0    var(--tuch-laenge) / var(--kante-b) var(--kante-h) repeat-y,
    var(--tuch-kante-rechts) 100% var(--tuch-laenge) / var(--kante-b) var(--kante-h) repeat-y;
          mask:
    linear-gradient(#000, #000) var(--kante-ueb) 0 / calc(100% - 2 * var(--kante-ueb)) 100% no-repeat,
    var(--tuch-kante-links)  0    var(--tuch-laenge) / var(--kante-b) var(--kante-h) repeat-y,
    var(--tuch-kante-rechts) 100% var(--tuch-laenge) / var(--kante-b) var(--kante-h) repeat-y;
}

/* Tuchfarbe, Schatten und Falten liegen auf einer eigenen Ebene (::before), damit die
   Helligkeit des Weiß (filter) NICHT auf das wirkt, was auf dem Tuch liegt, zum Beispiel
   eine Projektion. Die Maske der Kanten sitzt auf dem Tuch selbst und schneidet beides. */
.leinwand__tuch::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom,
      transparent calc(var(--schatten-start) - var(--e) * 8),
      rgba(0,0,0,.30) calc(var(--schatten-start) - var(--e) * 1),
      rgba(0,0,0,0) calc(var(--schatten-start) + var(--e) * 40)),
    /* feine Saumlinie an den Kanten: gibt dem Stoff eine Dicke */
    linear-gradient(to right, rgba(0,0,0,.20), rgba(0,0,0,0) calc(var(--e) * 5), rgba(0,0,0,0) calc(100% - var(--e) * 5), rgba(0,0,0,.20)),
    linear-gradient(to right, rgba(0,0,0,.16), rgba(0,0,0,0) 14%, rgba(0,0,0,0) 86%, rgba(0,0,0,.16)),
    /* sehr weiche, unregelmäßige Falten im Licht: Stoff hängt nie ganz glatt */
    linear-gradient(to right,
      rgba(255,255,255,0) 8%, rgba(255,255,255,.03) 19%, rgba(255,255,255,0) 31%,
      rgba(0,0,0,.035) 47%, rgba(0,0,0,0) 58%,
      rgba(255,255,255,.028) 71%, rgba(255,255,255,0) 82%),
    #e2e1e6;
  filter: brightness(var(--weiss-tuch));
}

/* --- Saum (Endstab des Tuchs): sitzt unten am Tuch und fährt mit --------------- */
.leinwand__saum {
  position: absolute;
  z-index: 2;
  left: 0; right: 0;
  top: calc(var(--e) * var(--q-saum-oben) + var(--tuch-laenge));
  height: calc(var(--e) * var(--q-saum-h));
  display: grid;
  grid-template-columns:
    calc(var(--e) * var(--q-links-b))
    1fr
    calc(var(--e) * var(--q-rechts-b));
  filter: brightness(var(--weiss-tuch));
}
.leinwand__saum img { display: block; width: 100%; height: 100%; }
.leinwand__saum-mitte {
  position: relative;
}
.leinwand__saum-mitte::before {
  content: "";
  position: absolute;
  inset: 0 -2px;
  background: url("bilder/saum-mitte.webp") 0 0 / 100% 100% no-repeat;
}
