/* Schrift: Avenir Medium ist die Markenschrift. Sie wird nur benutzt, wenn sie auf dem Gerät des Besuchers vorhanden ist
   (Mac, iPhone, iPad). Sie wird nicht mit hochgeladen, denn sie ist eine Bezahlschrift.
   Alle anderen Geräte zeigen die ähnliche freie Schrift Nunito Sans, selbst gehostet (Lizenz: assets/fonts/LICENSE-Nunito-Sans.txt).
   Die Seiten Impressum und Datenschutz haben einen eigenen Stil (legal.css) mit der Schrift Archivo, unverändert aus der 1. Variante. */
@font-face {
  font-family: "Avenir Lokal";
  src: local("Avenir-Medium"), local("Avenir Medium");
  font-weight: 500;
  font-style: normal;
}

@font-face {
  font-family: "Nunito Sans";
  src: url("../fonts/nunito-sans-latin-wght-normal.woff2") format("woff2");
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
}

/* Farben und Grundwerte.
   Der erste Abschnitt (Text, UN und WEISS) ist so breit wie der Bildschirm, links und rechts abzüglich --side
   (am Computer 0, auf dem Handy ein kleiner Rand). Alle Maße darin stammen aus der Entwurfsdatei "Datei Starter"
   (das Quadrat ist dort 283,46 Einheiten breit) und wachsen mit der Breite mit.
   --edge ist die Luft über und unter dem Schriftzug im Band.
   Schriftgröße des Textes im ersten Abschnitt: --tf Einheiten der Entwurfsdatei plus --fs-add, im schwarzen Block: --tfs Einheiten plus --fs-add.
   Am Computer sind es 9 und 8 Einheiten (der Entwurf hat 10), auf dem Handy in beiden Fällen 5 Einheiten plus 8 Pixel (etwa 14 bis 15 Pixel, gleich groß).
   --gap-s ist der halbe Standardabstand (Logo, Symbol und Kontakt). */
:root {
  --white: #fff;
  --black: #1d1d1b;
  --dot: rgba(29, 29, 27, 0.22);
  --dot-strong: rgba(29, 29, 27, 0.8);
  --halo: 0 0 3px #fff, 0 0 3px #fff, 0 0 7px #fff;
  --gap: 3cm;
  --pad: clamp(1.25rem, 5vw, 2rem);
  --side: 0px;
  --wv: calc(100vw - 2 * var(--side));
  --edge: clamp(0.65rem, 1.6vw, 1.5rem);
  --tf: 9;
  --tfs: 8;
  --fs-add: 0px;
  --measure: 21em;
  --gap-s: calc(var(--gap) / 2);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  color-scheme: light;
}

/* Grundlagen */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  display: flow-root;
  background: var(--white);
  color: var(--black);
  font-family: "Avenir Lokal", "Nunito Sans", "Helvetica Neue", Arial, sans-serif;
  font-weight: 500;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
strong {
  font-weight: 500;
}

img,
video {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
}

::selection {
  background: var(--black);
  color: var(--white);
}

.dark ::selection {
  background: var(--white);
  color: var(--black);
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Punktraster: liegt fest hinter der ganzen Seite. Nur schwarze Flächen decken es ab. */
.dots {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(circle, var(--dot) 0.6px, transparent 1.1px),
    radial-gradient(circle, var(--dot) 0.6px, transparent 1.1px);
  background-size: 10px 10px;
  background-position: 0 0, 5px 5px;
}

/* Zweite Ebene: dunklere Punkte im Umkreis von 150 Pixeln um die Maus (Position setzt main.js) */
.dots--focus {
  --dot: var(--dot-strong);
  opacity: 0;
  transition: opacity 0.5s ease;
  -webkit-mask-image: radial-gradient(circle 150px at var(--mx, -500px) var(--my, -500px), #000, transparent);
  mask-image: radial-gradient(circle 150px at var(--mx, -500px) var(--my, -500px), #000, transparent);
}

.has-pointer .dots--focus {
  opacity: 1;
}

/* Teil 1: Der erste Abschnitt in voller Bildbreite. Oben liegt der Text, der Schriftzug sitzt im Band darunter.
   Der Abschnitt reicht von der Oberkante des Entwurfs bis zur Oberkante der Schriftzeile (225,72 von 283,46 Einheiten).
   Ist er niedriger als der Bildschirm (Handy), steht er mittig im ersten Bildschirm. */
.stage {
  position: relative;
  z-index: 1;
  margin: max(0px, calc((100vh - var(--wv)) / 2)) var(--side) 0;
  aspect-ratio: 283.46 / 225.72;
  container-type: inline-size;
}

@supports (height: 100svh) {
  .stage {
    margin-top: max(0px, calc((100svh - var(--wv)) / 2));
  }
}

/* Text im Quadrat: Lage und Zeilenabstand stammen aus der Entwurfsdatei (Zeilenabstand 12 bei Schrift 10, also 1,2).
   Jede Zeile ist einzeln im Blocksatz gesetzt, damit die Umbrüche genau wie im Entwurf bleiben. Die Breite des Blocks
   wächst und schrumpft mit der Schrift (13,86 Schriftbreiten, das sind 138,62 Einheiten bei Schrift 10). */
.claim {
  position: absolute;
  left: calc(112.01 / 283.46 * 100%);
  top: calc(82.98 / 225.72 * 100%);
  width: 13.862em;
  margin: 0;
  font-size: calc(var(--tf) * var(--wv) / 283.46 + var(--fs-add));
  line-height: 1.2;
  text-shadow: var(--halo);
}

/* Die Schrift richtet sich genau nach der Breite des Abschnitts (Container-Einheit cqw, sie zählt die Bildlaufleiste nicht mit) */
@supports (width: 1cqw) {
  .claim {
    font-size: calc(var(--tf) * 100cqw / 283.46 + var(--fs-add));
  }
}

.claim .ln {
  display: block;
  white-space: nowrap;
  text-align: justify;
  text-align-last: justify;
}

.claim .ln:last-child {
  text-align-last: left;
}

/* Das Band: UN und WEISS. Es liegt zuerst unten im Quadrat und bleibt beim Scrollen oben am Rand stehen.
   --p ist der Fortschritt des UN (0 = oben im Quadrat, 1 = neben WEISS), main.js setzt ihn beim Scrollen.
   Ohne JavaScript oder bei "Bewegung reduzieren" steht das UN gleich neben WEISS. */
.band {
  --p: 1;
  position: sticky;
  top: 0;
  z-index: 10;
  padding: var(--edge) var(--side);
  background: var(--white);
}

/* Auf der Startseite ragt das Band um den Luftrand in den Abschnitt darüber, so beginnt die Schriftzeile genau am unteren Ende des Abschnitts */
.stage ~ .band {
  margin-top: calc(-1 * var(--edge));
}

.js .band {
  background: transparent;
}

.js .stage ~ .band {
  --p: 0;
}

/* Solange das Band oben klebt, ist es weiß und trägt dasselbe Punktraster (es liegt genau am Ursprung des festen Rasters).
   So verdeckt es den Inhalt, der darunter durchläuft, aber nicht die Punkte. */
.js .band.is-pinned {
  background:
    radial-gradient(circle, var(--dot) 0.6px, transparent 1.1px) 0 0 / 10px 10px,
    radial-gradient(circle, var(--dot) 0.6px, transparent 1.1px) 5px 5px / 10px 10px,
    var(--white);
  box-shadow: 0 1px 0 rgba(29, 29, 27, 0.14);
}

.js .band.is-pinned::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  background-image:
    radial-gradient(circle, var(--dot-strong) 0.6px, transparent 1.1px),
    radial-gradient(circle, var(--dot-strong) 0.6px, transparent 1.1px);
  background-size: 10px 10px;
  background-position: 0 0, 5px 5px;
  transition: opacity 0.5s ease;
  -webkit-mask-image: radial-gradient(circle 150px at var(--mx, -500px) var(--my, -500px), #000, transparent);
  mask-image: radial-gradient(circle 150px at var(--mx, -500px) var(--my, -500px), #000, transparent);
}

.has-pointer .band.is-pinned::after {
  opacity: 1;
}

.mark {
  display: block;
  line-height: 0;
  transition: transform 0.35s var(--ease);
}

.mark:hover,
.mark:focus-visible {
  transform: translateY(-2px);
}

/* Tastaturrahmen um den Schriftzug selbst, nicht um die ganze Breite des Bandes */
.mark:focus-visible {
  outline: none;
}

.mark:focus-visible .wordmark {
  outline: 2px solid currentColor;
  outline-offset: 6px;
}

/* Der Schriftzug besteht aus zwei gleich großen Zeichnungen, die genau übereinanderliegen: WEISS und das UN. */
.wordmark {
  position: relative;
  display: block;
  width: calc(258.79 / 283.46 * 100%);
  aspect-ratio: 258.79 / 43.6;
  margin-left: calc(12.86 / 283.46 * 100%);
  fill: currentColor;
  animation: fade 1.1s ease 0.1s backwards;
}

/* overflow: visible, denn die runde Form der beiden S reicht oben und unten minimal über die Zeichenfläche hinaus
   (optischer Ausgleich, wie bei runden Buchstaben üblich). Ohne diese Zeile schneidet die Zeichenfläche diesen Rest ab. */
.wordmark svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Das UN ist ein eigenes Element mit eigener Ebene und fährt senkrecht um 212,38 Einheiten nach unten in die Zeile von WEISS.
   Der Weg ist in Prozent der eigenen Höhe (43,6 Einheiten) angegeben: 212,38 durch 43,6 sind 487,11 Prozent.
   Früher lag das UN als Pfad in derselben Zeichnung außerhalb von deren Rand. Beim Hochscrollen wurde es dort von Safari
   nicht mehr gezeichnet, das UN verschwand. Als eigenes Element bewegt sich nur noch die fertige Ebene. */
.wm-un {
  transform: translate3d(0, calc(-487.11% * (1 - var(--p))), 0);
  will-change: transform;
}

/* Teil 2: Schwarzer Block über die ganze Bildbreite, mindestens 10 cm hoch (wächst bei Bedarf mit dem Text).
   Der Block ist selbst ein Container, damit die Schrift nach derselben Breite rechnet wie im ersten Abschnitt
   (Breite des Blocks minus die Ränder des ersten Abschnitts). */
.stripe {
  position: relative;
  z-index: 1;
  container-type: inline-size;
  display: grid;
  place-items: center;
  min-height: 10cm;
  margin-top: var(--gap);
  background: var(--black);
  color: var(--white);
}

.stripe-text {
  --fs: calc(var(--tfs) * var(--wv) / 283.46 + var(--fs-add));
  width: min(100% - 2 * var(--pad), var(--measure));
  margin-block: 1.6em;
  font-size: var(--fs);
}

@supports (width: 1cqw) {
  .stripe-text {
    --fs: calc(var(--tfs) * (100cqw - 2 * var(--side)) / 283.46 + var(--fs-add));
  }
}

.stripe h2 {
  margin: 0 0 0.8em;
  font-size: 1.3em;
  line-height: 1.2;
  text-align: center;
  text-wrap: balance;
}

.stripe p {
  margin: 0;
  line-height: 1.35;
  text-align: justify;
}

/* Logo mit Video (3 mal 3 cm, wie auf Impressum und Datenschutz), es steht in der Fußzeile über Impressum und Datenschutz.
   Die schwarze Kachel ist der Rahmen, im Feld des weißen UN läuft das Video. */
.logo {
  position: relative;
  display: block;
  width: 3cm;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--black);
  line-height: 0;
  transition: transform 0.35s var(--ease);
}

.logo:hover,
.logo:focus-visible {
  transform: translateY(-3px);
}

.logo-base {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.logo-field {
  position: absolute;
  top: 25.761%;
  left: 9.998%;
  width: 80.004%;
  height: 48.487%;
}

.logo-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  opacity: 0;
  will-change: opacity;
}

/* Mit JavaScript: erst ein leeres weißes Feld, in dem das Video das UN aufbaut. Das Video ist vor dem Start unsichtbar.
   Vor dem Start ist die ganze Fläche des Feldes weiß, sonst scheinen am Rand die schwarzen Lücken des ruhenden Logos
   als dunkle Balken durch. Läuft das Video, zieht sich die weiße Fläche nach 0,3 Sekunden 1 Pixel nach innen,
   sonst blitzt am Videorand ein heller Strich unter dem Video hervor. */
.js .logo-field {
  background: linear-gradient(var(--white), var(--white)) center / 100% 100% no-repeat;
}

.js .logo.is-playing .logo-field {
  animation: logo-inset 0.001s steps(1, end) 0.3s forwards;
}

@keyframes logo-inset {
  from {
    background-size: 100% 100%;
  }

  to {
    background-size: calc(100% - 2px) calc(100% - 2px);
  }
}

.js .logo.is-playing .logo-video {
  opacity: 1;
}

/* Das ruhende Logo darunter bleibt bis zum Ende des ersten Laufs unsichtbar (die schwarze Kachel bleibt).
   Sonst zeichnet sich sein Umriss am Rand des weißen Feldes ab, auch nur um einen Bildschirmpunkt. */
.js .logo:not(.is-rest):not(.is-replay) .logo-base {
  visibility: hidden;
}

/* Übergang ins ruhende Logo: Die weiße Fläche fällt sofort weg (das Video deckt das Feld noch voll ab),
   danach blendet nur das Video aus und gibt das Logo darunter frei. Die weiße Fläche wird nicht mit ausgeblendet,
   denn das hellte die schwarzen Formen kurz auf und sah aus wie ein Blinken. */
.js .logo.is-rest .logo-field,
.js .logo.is-replay .logo-field {
  background: transparent;
}

.js .logo.is-rest .logo-video {
  opacity: 0;
  transition: opacity 0.3s ease;
}

.js .logo.is-replay .logo-video {
  opacity: 1;
  transition: opacity 0.25s ease;
}

/* Teil 3: Kontakt. Vom unteren Rand des schwarzen Blocks bis zur Oberkante der Buchstaben von "Kontakt" sind es 2 cm.
   Die Zeile beginnt 0,23 Schrifthöhen über den Großbuchstaben, darum rückt die Überschrift um so viel nach oben. */
.contact {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2cm var(--pad) 0;
  text-align: center;
}

.contact h2 {
  margin: -0.23em 0 2rem;
  font-size: clamp(1.5rem, 5vw, 2rem);
  line-height: 1.25;
  text-shadow: var(--halo);
}

.address {
  font-size: 1.1rem;
  font-style: normal;
  line-height: 1.8;
  text-shadow: var(--halo);
}

.address p {
  margin: 0 0 1rem;
}

.address p:last-child {
  margin-bottom: 0;
}

.address .space {
  margin-bottom: 1.5rem;
}

/* Instagram-Symbol zwischen Telefonnummer und Logo. Über und unter dem sichtbaren Symbol ist gleich viel Platz:
   0,65 rem gleichen den Rest der Zeile unter der Telefonnummer aus (die Zeile ist höher als die Ziffern). */
.social {
  position: relative;
  display: block;
  width: 1.75rem;
  height: 1.75rem;
  margin: calc(var(--gap-s) - 0.65rem) auto 0;
  color: var(--black);
  filter: drop-shadow(0 0 2px #fff) drop-shadow(0 0 4px #fff);
  transition: transform 0.35s var(--ease);
}

.social::after {
  content: "";
  position: absolute;
  inset: -0.9rem;
}

.social:hover,
.social:focus-visible {
  transform: translateY(-2px);
}

.social svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.social .dot {
  fill: currentColor;
  stroke: none;
}

.link {
  position: relative;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
  padding-bottom: 2px;
  text-decoration: none;
  transition: background-size 0.3s var(--ease);
}

.link::after {
  content: "";
  position: absolute;
  inset: -0.85rem -0.5rem;
}

.link:hover,
.link:focus-visible {
  background-size: 100% 1px;
}

/* Fußzeile: Logo, darunter Impressum und Datenschutz, darunter das Copyright.
   Der sichtbare Abstand vom unteren Rand des Logos bis zur Oberkante der Buchstaben von "Impressum" ist so groß wie der sichtbare Abstand
   von "Impressum" bis zur Oberkante der Buchstaben der Copyright-Zeile (gemessen). */
.site-footer {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--gap-s) var(--pad) 2rem;
  font-size: 0.875rem;
  text-align: center;
  text-shadow: var(--halo);
}

.site-footer .logo {
  margin-bottom: 1.47em;
}

.site-footer nav {
  display: flex;
  gap: 1.75rem;
  margin-bottom: 0.75rem;
}

.site-footer p {
  margin: 0;
}

/* Mauszeiger als kleines Quadrat (nur mit Maus, wird per JavaScript aktiviert) */
.cursor {
  --c: #1d1d1b;
  --e: #fff;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  width: 10px;
  height: 10px;
  background: var(--c);
  box-shadow: 0 0 0 1px var(--e);
  opacity: 0;
  pointer-events: none;
  will-change: transform;
  transition: opacity 0.25s ease, width 0.3s var(--ease), height 0.3s var(--ease), background-color 0.3s ease;
}

.cursor.on-dark {
  --c: #fff;
  --e: #1d1d1b;
}

.has-pointer .cursor {
  opacity: 1;
}

.has-pointer .cursor.is-hidden {
  opacity: 0;
}

.cursor.is-link {
  width: 34px;
  height: 34px;
  background: transparent;
  border: 2px solid var(--c);
  box-shadow: 0 0 0 1px var(--e), inset 0 0 0 1px var(--e);
}

.cursor.is-down {
  width: 7px;
  height: 7px;
}

.cursor.is-link.is-down {
  width: 26px;
  height: 26px;
}

.has-pointer,
.has-pointer * {
  cursor: none !important;
}

/* Sanftes Einblenden: beim Laden und beim Scrollen */
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
}

.reveal {
  animation: rise 0.9s var(--ease) backwards;
  animation-delay: calc(var(--i, 0) * 120ms + 80ms);
}

/* Reihenfolge beim Einblenden (statt Stilangaben im HTML, das erlaubt strengere Sicherheitsregeln am Server) */
.reveal--1 {
  --i: 1;
}

.js .rv {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}

.js .rv.is-in {
  opacity: 1;
  transform: none;
}

/* Kleine Bildschirme: engere Abstände und ein kleiner Rand neben dem ersten Abschnitt.
   Der Abschnitt steht ganz oben: Die Oberkante des UN ist genauso weit vom oberen Bildrand entfernt wie sein linker Rand vom linken Bildrand.
   Links sind es --side plus 12,86 Einheiten, oben 13,34 Einheiten plus der Abstand des Abschnitts (Einheit = Breite des Abschnitts durch 283,46). */
@media (max-width: 40rem) {
  :root {
    --gap: 2.4cm;
    --side: clamp(0.75rem, 3vw, 2rem);
    --tf: 5;
    --tfs: 5;
    --fs-add: 8px;
    --measure: 24em;
  }

  /* Schwarzer Block: seitlicher Abstand des Textes zum Bildrand doppelt so groß wie bisher, Schriftgröße gleich.
     Bisher war die Breite min(100% - 2 * --pad, --measure), der Abstand also (100% - Breite) / 2.
     Doppelter Abstand heißt: neue Breite = 2 * bisherige Breite - 100%.
     Auf Handys (320 bis 430 Pixel) wirkt das genau so. Darüber (bis 640 Pixel) hält die Untergrenze von 17 Schriftbreiten die Spalte lesbar. */
  .stripe-text {
    width: max(calc(2 * min(100% - 2 * var(--pad), var(--measure)) - 100%), 17em);
  }

  .stage {
    margin-top: calc(var(--side) - 0.48 * var(--wv) / 283.46);
  }

  /* Größere Schrift braucht einen breiteren Textblock: Er endet wie WEISS am rechten Rand des Schriftzugs (271,65 von 283,46 Einheiten)
     und reicht so weit nach links, wie die längste Zeile es braucht (13,95 Schriftbreiten). */
  .claim {
    left: auto;
    right: calc(11.81 / 283.46 * 100%);
    width: 13.95em;
  }
}

/* Sehr schmale Handys: Quadrat mit kleinerem Rand, damit der Text lesbar bleibt, und Silbentrennung im Blocksatz, sonst entstehen zu große Lücken */
@media (max-width: 23rem) {
  :root {
    --side: 0.5rem;
  }

  .stripe p {
    -webkit-hyphens: auto;
    hyphens: auto;
  }
}

/* Weniger Bewegung: nichts fährt, das UN steht gleich neben WEISS */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .wordmark {
    animation: none;
  }

  .js .rv {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .js .stage ~ .band {
    --p: 1;
  }

  .js .logo-field {
    background: transparent;
  }

  .js .logo-video {
    opacity: 0;
  }

  .dots--focus,
  .js .band.is-pinned::after {
    display: none;
  }

  * {
    transition-duration: 0.01ms !important;
  }
}
