/* ==========================================================================
   anjabooth – Theme
   Alles Stellbare steht in :root. Kein Framework, kein JS.
   Regel Nr. 1: kein Scroll-Hijacking. Keine scroll-snap, kein Parallax,
   kein Abfangen von Rad/Touch. Einzige Ausnahme: der Kartenstapel aus
   Hero und Projekten (position: sticky) – natives Scrollen, nur die Karten bleiben hängen.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* Farben – light-dark(hell, dunkel), folgt der Systemeinstellung.
     Für einen manuellen Schalter reicht color-scheme: dark auf :root. */
  --color-bg: light-dark(#fbfaf8, #1c1b19);
  --color-text: light-dark(#1c1b19, #f3f1ec);
  --color-text-prose: light-dark(#3b382f, #cfcbc2);
  --color-text-muted: light-dark(#55524b, #b3aea3);
  --color-text-label: light-dark(#8a8578, #8f8a7e);
  --color-text-hover: light-dark(#6e6a61, #cfcecb);
  --color-surface: light-dark(#efece5, #2a2927);
  --color-rule: light-dark(rgba(28, 27, 25, 0.12), rgba(251, 250, 248, 0.14));
  --color-focus: light-dark(#1c1b19, #f3f1ec);
  --color-media-fallback: light-dark(#2b2d2e, #111110);

  /* Overlay auf Bildern – liegt immer auf dunklem Bildgrund, daher in beiden Modi gleich */
  --overlay-text: #fbfaf8;
  --overlay-text-strong: rgba(251, 250, 248, 0.9);
  --overlay-text-soft: rgba(251, 250, 248, 0.82);
  --overlay-scrim: rgba(11, 11, 12, 0.78);
  --overlay-scrim-end: rgba(11, 11, 12, 0);

  /* Typografie */
  --text-xs: 0.75rem;                                  /* 12px */
  --text-sm: 0.8125rem;                                /* 13px */
  --text-base: 1rem;                                   /* 16px */
  --text-md: clamp(1.0625rem, 0.95rem + 0.4vw, 1.1875rem);   /* 17–19px Fließtext */
  --text-lg: clamp(2rem, 1.25rem + 3.5vw, 4.25rem);        /* Projekttitel 32px (Handy) bis 68px (Desktop) */
  --text-xl: clamp(1.5rem, 1rem + 2vw, 2.75rem);             /* Kontakt-Mail */
  --text-display: clamp(2.75rem, 1.5rem + 5vw, 5.5rem);      /* Hero-Name 44–88px */
  --tracking-label: 0.14em;
  --tracking-meta: 0.1em;
  --leading-tight: 1.05;
  --leading-prose: 1.65;

  /* Layout */
  --gutter: clamp(1.25rem, 1rem + 3vw, 4.5rem);        /* 20–72px Seitenrand (Handy: siehe unten) */
  --content-max: 100vw;                                /* 1440px */
  --prose-max: 40rem;
  --section-narrow: 96rem;                             /* 1536px: Über mich + Auszeichnungen */
  --space-section: clamp(3.5rem, 2rem + 7vw, 9rem);    /* 56–144px zwischen Sektionen */
  --space-project: clamp(1.75rem, 1rem + 4vw, 5.5rem); /* 28–88px zwischen Projekten */
  --space-label: clamp(1.75rem, 1.25rem + 1.5vw, 2.5rem);

  /* Bildkarten (Hero + Projekte): Höhe folgt dem Viewport, die Form damit dem Bildschirm.
     --card-ratio-max begrenzt die Flachheit auf Ultrawide: der Browser nimmt die größere
     der beiden Höhen (Ratio vs. min-height). Fokuspunkt pro Bild über object-position. */
  --card-height: clamp(24rem, 82svh, 50rem);
  --card-ratio-max: 21 / 9;
  --card-pad: clamp(1.25rem, 1rem + 2vw, 3.5rem);          /* Innenabstand der Text-Overlays (Hero + Projekte) */
  --card-pad-bottom: clamp(1.5rem, 1rem + 2.5vw, 4rem);
  --desc-lines: 4;                 /* Projektbeschreibung: maximal so viele Zeilen */
  --portrait-ratio: 4 / 5;

  /* Kundenlogos: werden als Maske in --logo-color eingefärbt (einfarbig),
     Box mit fester Höhe – SVGs ohne width/height und weiße Logos sind damit egal. */
  --logo-height: clamp(2.75rem, 1rem + 4vw, 6rem);         /* wächst mit dem Platz: 44–96px */
  --logo-max-width: clamp(8rem, 4rem + 16vw, 24rem);
  --logo-gap: 4rem 1.5rem;         /* Zeilen- / Spaltenabstand (Handy) */
  --logo-color: var(--color-text);
  --logo-cols: 2;                  /* Spalten der Logo-Leiste: 2 Handy, 3 ab Tablet */

  /* Kopfzeile (Glas-Pille) */
  --header-h: 3.25rem;             /* nur Richtwert für scroll-margin; echte Höhe = Pille + 2 × --tab-pad */
  --header-gap: 1.5rem;
  --tab-pad: 0.3rem;
  --tab-bar-inset: 0.5rem;         /* Handy: Leiste etwas schmaler als der Inhalt */
  /* fluid von 360px (4 Tabs passen gerade) bis 768px (volle Größe) */
  --tab-font: clamp(0.6875rem, 0.44vw - 0.18rem, 0.8125rem);       /* 11–13px */
  --tab-tracking: clamp(0.02em, 0.145vw, 0.08em);
  --tab-pad-x: clamp(0.5rem, 0.06rem + 1.96vw, 1rem);
  --radius-card: clamp(1.25rem, 1rem + 1.5vw, 2.5rem);   /* Bildkarten + Porträt */
  --radius-pill: 9999px;   /* immer 50 % der Höhe, egal wie hoch das Element ist */
  --tab-hover-bg: light-dark(rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.07));
  --tab-active-bg: light-dark(rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.16));
  --tab-active-shadow: light-dark(
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 1px 0 rgba(255, 255, 255, 0.25)
  ), 0 2px 8px -2px var(--glass-shadow);
  /* Hell: leicht graues Glas (wie die iOS-Segmentleiste), damit die weiße
     aktive Pille sich abhebt – auf dem Seitenhintergrund landet die Leiste bei ≈ #eeece8 */
  --glass-bg: light-dark(rgba(234, 232, 228, 0.75), rgba(28, 27, 25, 0.5));
  --glass-bg-solid: light-dark(rgba(236, 234, 230, 0.96), rgba(28, 27, 25, 0.94));
  --glass-border: light-dark(rgba(255, 255, 255, 0.65), rgba(255, 255, 255, 0.14));
  --glass-highlight: light-dark(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.18));
  --glass-sheen: light-dark(rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.06));
  --glass-shadow: light-dark(rgba(20, 20, 19, 0.12), rgba(0, 0, 0, 0.5));

  /* Button auf Bildern – deckend, in beiden Modi gleich */
  --button-bg: #ffffff;
  --button-bg-hover: #efece5;
  --button-text: #1c1b19;

  --duration: 160ms;
}
@media (max-width: 40em) {
  :root { --gutter: 0.875rem; }   /* 14px Seitenrand auf dem Handy */
}

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

html {
  -webkit-text-size-adjust: 100%;
  /* Sanftes Scrollen nur bei Anker-Klicks (Menü). Rad, Touch und Tastatur
     bleiben nativ – das ist kein Scroll-Hijacking. */
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-prose);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  padding: 0 var(--gutter);
  /* Footer bleibt unten, auch bei kurzen Seiten: body als Spalte, main füllt den Rest */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

img,
svg { display: block; max-width: 100%; height: auto; }

h1, h2, h3, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
  transition: color var(--duration) ease;
}
a:hover { color: var(--color-text-hover); }

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}
.hero :focus-visible,
.project :focus-visible,
.contact--card :focus-visible {
  outline-color: var(--overlay-text);
}

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

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -100%;
  z-index: 100;
  padding: 0.5rem 0.75rem;
  background: var(--color-text);
  color: var(--color-bg);
  text-decoration: none;
}
.skip-link:focus { top: 0.5rem; }

/* --------------------------------------------------------------------------
   Kopfzeile
   -------------------------------------------------------------------------- */
/* Schwebende Tab-Leiste im iOS-Stil: Glas-Kapsel, so breit wie ihr Inhalt,
   jeder Link eine eigene Pille. Steht zuerst normal im Fluss über dem Hero
   und heftet sich beim Scrollen oben an. Kein JS, kein Scroll-Effekt. */
.site-header {
  position: sticky;
  top: var(--header-gap);
  z-index: 50;
  display: flex;
  justify-content: center;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  margin: var(--header-gap) auto;
  padding: var(--tab-pad);
  border-radius: var(--radius-pill);
  border: 1px solid var(--glass-border);
  overflow: hidden;                 /* Blur-Layer sauber an der runden Kante beschneiden */
  isolation: isolate;
  -webkit-mask-image: -webkit-radial-gradient(#fff, #000);   /* Safari: Ecken des Blur-Layers glätten */
  background:
    linear-gradient(to bottom, var(--glass-sheen), transparent 55%),
    var(--glass-bg);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  box-shadow:
    inset 0 1px 0 var(--glass-highlight),
    inset 0 -1px 0 rgba(0, 0, 0, 0.04),
    0 1px 2px var(--glass-shadow),
    0 12px 32px -12px var(--glass-shadow);
}

/* Nie umbrechen: Schrift, Laufweite und Padding schrumpfen fluid;
   Notausgang bei zu vielen Punkten: seitlich scrollen (ohne sichtbare Leiste). */
.site-nav { max-width: 100%; }
.site-nav__list {
  display: flex;
  flex-wrap: nowrap;
  justify-content: safe center;   /* bei Überlauf linksbündig, damit alles erreichbar bleibt */
  align-items: center;
  gap: 0.125rem;
  font-size: var(--tab-font);
  letter-spacing: var(--tab-tracking);
  text-transform: uppercase;
  color: var(--color-text-muted);
  overflow-x: auto;
  scrollbar-width: none;
}
.site-nav__list::-webkit-scrollbar { display: none; }

.site-nav__link {
  display: block;
  padding: 0.55rem var(--tab-pad-x);
  line-height: 1.5;
  border-radius: var(--radius-pill);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--duration) ease, color var(--duration) ease, box-shadow var(--duration) ease;
}
.site-nav__link:hover {
  color: var(--color-text);
  background: var(--tab-hover-bg);
}
.site-nav__link:focus-visible {
  outline-offset: 0;
}
/* Aktive Pille: Klasse kommt aus js/nav.js (Scrollposition);
   ohne JS greifen die generierten :target-Regeln in partials/header.html.twig */
.site-nav__link.is-active {
  color: var(--color-text);
  background: var(--tab-active-bg);
  box-shadow: var(--tab-active-shadow);
}

/* Handy: Leiste über die volle Breite, Tabs gleichmäßig verteilt (wie die iOS-Tab-Bar).
   Tabs wachsen, schrumpfen aber nie unter ihre Textbreite – passen sie nicht
   mehr nebeneinander, scrollt die Leiste seitlich (js/nav.js hält den aktiven
   Tab im Bild). */
@media (max-width: 40em) {
  .site-header { width: calc(100% - 2 * var(--tab-bar-inset)); }
  .site-nav { width: 100%; }
  .site-nav__list { gap: 0; scroll-padding-inline: 0.5rem; }
  .site-nav__list > li { flex: 1 0 auto; }
  .site-nav__link { text-align: center; padding-inline: 0.3rem; }
  /* Läuft die Leiste über, blenden die Ränder aus – so sieht man, dass es weitergeht */
  .site-nav__list.is-overflowing {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 1.25rem, #000 calc(100% - 1.25rem), transparent);
    mask-image: linear-gradient(to right, transparent, #000 1.25rem, #000 calc(100% - 1.25rem), transparent);
  }
}
/* Sehr schmale Handys (≤ 368px): noch etwas enger, damit vier deutsche Menüpunkte passen */
@media (max-width: 23em) {
  :root { --tab-tracking: 0.01em; }
  .site-nav__link { padding-inline: 0.15rem; }
}

/* Ohne backdrop-filter oder bei reduzierter Transparenz: fast deckend */
@supports not (backdrop-filter: blur(1px)) {
  :root { --glass-bg: var(--glass-bg-solid); }
}
@media (prefers-reduced-transparency: reduce) {
  :root { --glass-bg: var(--glass-bg-solid); }
  .site-header { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* --------------------------------------------------------------------------
   Sektionen
   -------------------------------------------------------------------------- */
.site-main {
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}

/* Abstand nach unten statt Padding oben: so landen #anker-Sprünge
   direkt auf der Sektion und nicht im Leerraum davor. */
.section {
  margin-bottom: var(--space-section);
  scroll-margin-top: calc(var(--header-h) + 2 * var(--header-gap));
}
/* Die letzte Sektion bekommt keinen Abstand nach unten – den liefert der Footer
   (margin-top) auf allen Seiten gleich, auch auf Impressum/Datenschutz. */
.section:last-child { margin-bottom: 0; }

.section__label {
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-label);
  margin-bottom: var(--space-label);
}

.section__intro {
  max-width: var(--prose-max);
  margin-bottom: var(--space-label);
}

.prose {
  font-size: var(--text-md);
  line-height: var(--leading-prose);
  color: var(--color-text-prose);
}
.prose > * + * { margin-top: 1em; }
.prose h2, .prose h3 {
  color: var(--color-text);
  font-weight: 500;
  line-height: 1.25;
  margin-top: 2em;
}
.prose h2 { font-size: 1.35em; }
.prose h3 { font-size: 1.1em; }
.prose ul { list-style: disc; padding-left: 1.25em; }
.prose ol { list-style: decimal; padding-left: 1.25em; }
.prose li + li { margin-top: 0.35em; }

/* --------------------------------------------------------------------------
   Bild mit Text-Overlay (Hero, Projekt, Kontakt mit Bild): gleiche Mechanik
   Container relative, Bild füllt, Scrim = Verlauf von unten, Text absolut unten.
   -------------------------------------------------------------------------- */
.hero,
.project,
.contact--card {
  position: relative;
  overflow: hidden;
  color: var(--overlay-text);
  /* Safari 26 (iOS/macOS) färbt Status- und Adressleiste nach der background-color
     hängender Elemente (sticky/fixed) – und liest dabei auch deren Kinder, also
     die Karten im Stapel. Darum trägt die Karte die Seitenfarbe als background-color;
     die dunkle Fläche, bis das Bild geladen ist, liegt als background-image darüber
     (Verläufe wertet Safari nicht aus). Siehe github.com/andesco/safari-color-tinting */
  background-color: var(--color-bg);
  background-image: linear-gradient(var(--color-media-fallback), var(--color-media-fallback));
  border-radius: var(--radius-card);
}

.hero__media,
.project__media,
.contact__media {
  position: absolute;
  inset: 0;
}

.hero__image,
.project__image,
.contact__image,
.hero__placeholder,
.project__placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Leichte Hürde gegen Drag-and-drop-Speichern; kein echter Schutz */
.hero__image,
.project__image,
.contact__image {
  -webkit-user-drag: none;
  user-select: none;
}

.hero__placeholder { background: linear-gradient(160deg, #2e3a3d 0%, #4a555a 45%, #8a7b66 100%); }
.project__placeholder { background: linear-gradient(120deg, #1e2a33 0%, #3c5361 55%, #7c8b8c 100%); }

.hero__scrim,
.project__scrim,
.contact__scrim {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 62%;
  background: linear-gradient(to top, var(--overlay-scrim), var(--overlay-scrim-end));
  pointer-events: none;
}

.hero__text,
.project__text,
.contact__text {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0 var(--card-pad) var(--card-pad-bottom);
  text-shadow: #303030 0 0 20px;
}

/* Hero + Projektkarten: gleiche Grundhöhe ------------------------------- */
.hero,
.project {
  width: 100%;                     /* explizit, sonst überträgt aspect-ratio die min-height auf die Breite */
  aspect-ratio: var(--card-ratio-max);
  min-height: var(--card-height);
}
@media (min-width: 48em) {
  :root {
    --logo-cols: 3;
    --logo-gap: 3.5rem 3rem;
  }
}

/* Namensblock: Breite = Name */
.hero__brand {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  width: fit-content;
  max-width: 100%;
}

.hero__title {
  font-size: var(--text-display);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
}

.hero__role {
  /* Fallback-Größe; js/hero-fit.js skaliert den Claim auf die Breite des Namens */
  font-size: clamp(0.875rem, 0.75rem + 0.5vw, 1.25rem);
  line-height: 1.15;
  letter-spacing: var(--tracking-label);
  white-space: nowrap;
  color: var(--overlay-text-soft);
}

.hero__intro {
  /* Fallback-Größe; js/hero-fit.js skaliert die Zeile auf die Breite des Namens */
  margin-top: 0.4rem;
  font-size: clamp(0.9375rem, 0.85rem + 0.3vw, 1.0625rem);
  line-height: 1.35;
  white-space: nowrap;
  color: var(--overlay-text-strong);
}
.hero__intro > * + * { margin-top: 0.6em; }

/* Kürzen im Backend abgeschaltet: ganzer Text */
.project__desc.is-unclamped {
  display: block;
  -webkit-line-clamp: none;
  line-clamp: none;
  overflow: visible;
}

/* Kartenstapel (Hero + Projekte) ---------------------------------------- */
/* Jede Karte bleibt unter der Tab-Leiste hängen (position: sticky), die nächste
   schiebt sich beim Scrollen darüber – der Hero ist Karte 0, die Projekte folgen.
   Reines CSS, natives Scrollen – kein Abfangen des Rads, keine Sprungmarken.
   Jede Karte liegt ein paar Pixel tiefer als die vorige, so bleibt vom Stapel
   eine Kante sichtbar.
   .stack (modular.html.twig) umschließt Hero und Projekte-Sektion und liefert --n
   (Karten insgesamt); die Karten tragen --i (Hero: 0, Projekte: --k + Versatz). */
.stack {
  --stack-top: calc(var(--header-h) + 2 * var(--header-gap));
  --stack-step: 0.5rem;            /* Versatz pro Karte */
  --stack-shadow: 2rem;            /* maximale Reichweite des Schattens nach oben */
  /* Scrollweg vom Viewport-Unterrand bis zur Unterkante der hängenden Karte */
  --stack-gap: max(
    calc(100svh - var(--stack-top) - var(--card-height)),
    calc((var(--n, 1) - 1) * var(--stack-step) + 1rem)
  );
}
/* Block, kein Flex: so fällt der Außenabstand der Projekte-Sektion aus dem
   Stapel heraus und der Hero wird am Listenende zusammen mit den Karten
   hochgeschoben (sticky endet am Inhaltskasten des Containers). */
.stack > .projects { margin-top: var(--space-project); }
.projects__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-project);
}
.projects__item { --i: var(--k, 0); }
.stack--hero .projects__item { --i: calc(var(--k, 0) + 1); }   /* Hero ist Karte 0 */
.stack__item {
  position: sticky;
  top: calc(var(--stack-top) + var(--i, 0) * var(--stack-step));
  /* Am Ende der Liste schiebt der Container den ganzen Stapel nach oben und
     richtet dabei alle Unterkanten aus. Damit die Kanten dann nicht alle auf
     einer Höhe landen (und sich die Schatten summieren), sind die vorderen
     Karten unten um den Versatz höher – als transparentes Padding. Die nächste
     Karte zieht sich um dieses Padding nach oben, damit die sichtbaren Abstände
     gleich bleiben. (Ein negativer Außenabstand unten ginge nicht: sticky
     rechnet mit dem Margin-Box-Rand, das Padding wäre wirkungslos.) */
  --stack-pad: calc((var(--n, 1) - 1 - var(--i, 0)) * var(--stack-step));
  padding-bottom: var(--stack-pad);
  /* Schatten darf nur nach oben (auf die Karte darunter) fallen, nie seitlich
     oder nach unten auf den Seitenhintergrund. Im hängenden Zustand ragen
     über dieser Karte nur noch die Kanten der vorigen heraus (--i × --stack-step),
     also schrumpft die Reichweite kurz vor dem Andocken auf genau dieses Maß. */
  clip-path: inset(calc(-1 * var(--i, 0) * var(--stack-step)) 0 0 0 round var(--radius-card));
}
.stack__item + .stack__item,
.stack--hero .projects__list > .stack__item:first-child {
  margin-top: calc(-1 * (var(--n, 1) - var(--i, 0)) * var(--stack-step));   /* = Padding der vorigen Karte */
}
/* Auch die unterste Karte des Stapels muss samt Versatz in den Viewport passen
   (kleine Handys): Kartenhöhe notfalls unter --card-height drücken. */
.stack__item > .hero,
.projects__item .project {
  min-height: min(
    var(--card-height),
    calc(100svh - var(--stack-top) - (var(--n, 1) - 1) * var(--stack-step) - 1rem)
  );
}
/* Schatten der Überlappung: eigene Ebene unter der Karte (::before liegt vor
   .project in der Malreihenfolge), sichtbar nur auf der Karte darunter.
   Blendet per Scroll-Timeline erst ein, wenn die Karte die vorige tatsächlich
   überdeckt – vorher läge der Schatten in der Lücke auf dem Hintergrund.
   Ohne Scroll-Timeline (ältere Browser): Schatten immer an, aber beschnitten. */
.projects__item::before {
  content: "";
  position: absolute;
  inset: 0 1rem var(--stack-pad);  /* seitlich eingerückt: Schatten endet vor der Kartenkante, kein harter Schnitt */
  border-radius: var(--radius-card);
  box-shadow: 0 -8px 24px -4px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}
/* Ohne Hero liegt unter der ersten Karte nichts */
.stack:not(.stack--hero) .projects__item:first-child::before { display: none; }
@supports (animation-timeline: view()) {
  .projects__item::before {
    opacity: 0;
    animation: stack-shadow linear both;
    animation-timeline: view();
    animation-range: entry var(--stack-gap) entry calc(var(--stack-gap) + 8rem);
  }
  @keyframes stack-shadow { to { opacity: 1; } }
  /* Während des Schiebens volle Reichweite, auf den letzten Pixeln vor dem
     Andocken (Oberkante bei --stack-top + --stack-shadow … + --i × --stack-step)
     auf die Kantenhöhe des Stapels zurück. cover 0 = Oberkante am unteren
     Viewport-Rand, die Längen sind der Scrollweg ab dort. (exit-Bereiche
     greifen bei sticky-Elementen nicht, die Karte verlässt den Viewport nie.) */
  .stack__item {
    animation: stack-clip linear both;
    animation-timeline: view();
    animation-range:
      cover calc(100svh - var(--stack-top) - var(--stack-shadow))
      cover calc(100svh - var(--stack-top) - min(var(--stack-shadow), var(--i, 0) * var(--stack-step)));
  }
  @keyframes stack-clip {
    from { clip-path: inset(calc(-1 * var(--stack-shadow)) 0 0 0 round var(--radius-card)); }
    to   { clip-path: inset(calc(-1 * min(var(--stack-shadow), var(--i, 0) * var(--stack-step))) 0 0 0 round var(--radius-card)); }
  }
}

.project__text {
  max-width: min(100%, 44rem + 2 * var(--card-pad));
  right: auto;
}

/* Überzeile (header.kicker): kleine Zeile direkt über dem Titel */
.project__kicker {
  font-size: var(--text-sm);
  font-weight: 600;   /* Questrial hat nur Regular – der Browser fettet synthetisch, wie beim Hero-Namen */
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--overlay-text-soft);
  margin-bottom: -0.2rem;   /* enger an den Titel als der Standardabstand (gap) */
}

.project__title {
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: 1.12;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  /* Lange Wörter (NIEDERRHEIN) dürfen nie über die Karte hinauslaufen:
     erst trennen (lang="de"), im Notfall irgendwo umbrechen. */
  hyphens: auto;
  overflow-wrap: anywhere;
}

.project__meta {
  font-size: var(--text-md);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--overlay-text-soft);
}

.project__desc {
  font-size: clamp(0.9375rem, 0.85rem + 0.3vw, 1rem);
  line-height: 1.55;
  color: var(--overlay-text-strong);
  max-width: 40rem;
  /* Auf maximal --desc-lines Zeilen kürzen, Rest mit „…“ */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--desc-lines);
  line-clamp: var(--desc-lines);
  overflow: hidden;
}
.project__desc > * + * { margin-top: 0.6em; }

.project__link {
  margin-top: 0.75rem;
}

/* Button auf Bildern: deckend weiß, dunkle Schrift, Kapsel mit Pfeil-Icon */
.button {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.7em 1.1em 0.7em 1.3em;
  border-radius: var(--radius-pill);
  border: 0;
  background: var(--button-bg);
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, 0.6);
  color: var(--button-text);
  text-shadow: none;                /* Overlay-Textschatten nicht auf den Button vererben */
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition:
    background-color var(--duration) ease,
    box-shadow var(--duration) ease,
    transform var(--duration) ease;
}
.button:hover {
  color: var(--button-text);
  background: var(--button-bg-hover);
  box-shadow: 0 10px 28px -10px rgba(0, 0, 0, 0.65);
}
.button:active { transform: scale(0.97); }
.button:focus-visible { outline-offset: 3px; }

.button__icon {
  width: 0.85em;
  height: 0.85em;
  flex: none;
  transition: transform var(--duration) ease;
}
.button:hover .button__icon { transform: translate(1px, -1px); }
.button--internal:hover .button__icon { transform: translateX(2px); }

/* Über mich ------------------------------------------------------------
   Foto und Text nebeneinander (ab Tablet), Foto-Seite per Modifier; der
   Einleitungssatz liegt als Overlay auf der Unterkante des Fotos.
   Handy: Foto, Text untereinander. Das Foto bleibt beim
   Scrollen stehen (sticky), solange der Text länger ist als das Bild. */
.about {
  --about-gap: clamp(2rem, 1rem + 4vw, 5rem);
  /* Foto und Text als Block zentrieren: Breite so wählen, dass die Textspalte (3/5)
     genau --prose-max ist – sonst bliebe rechts vom Text Leerraum. */
  max-width: min(var(--section-narrow), calc(var(--prose-max) * 5 / 3 + var(--about-gap)));
  margin-inline: auto;
  margin-top: calc(var(--space-section) * 0.75);   /* mehr Luft nach dem Kartenstapel */
  display: grid;
  grid-template-areas:
    "label"
    "media"
    "text";
  gap: 1.5rem;
}
.about__label { grid-area: label; margin-bottom: calc(var(--space-label) - 1.5rem); }

.about__media {
  grid-area: media;
  position: relative;
  aspect-ratio: var(--portrait-ratio);
  overflow: hidden;
  border-radius: var(--radius-card);
  background: var(--color-surface);
  --about-pad: clamp(1.25rem, 1rem + 1.5vw, 2.25rem);   /* Innenabstand des Overlays, schmaler als bei den breiten Karten */
}
.about__image { width: 100%; height: 100%; object-fit: cover; }
.about__scrim {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 45%;
  background: linear-gradient(to top, var(--overlay-scrim), var(--overlay-scrim-end));
  pointer-events: none;
}

.about__text { grid-area: text; max-width: var(--prose-max); }
@media (min-width: 48em) {
  .about__text { max-width: none; }   /* Breite kommt aus der Spalte, siehe .about */
}
.about__lead {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  margin: 0;
  padding: 0 var(--about-pad) var(--about-pad);
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.25rem);   /* 24–36px */
  line-height: 1.2;
  color: var(--overlay-text);
  text-shadow: #303030 0 0 20px;
}
/* Ohne Foto: ganz normal über dem Text */
.about__lead--plain {
  position: static;
  grid-area: text;
  padding: 0;
  color: var(--color-text);
  text-shadow: none;
  align-self: end;
}

/* Textspalte als Bildkarte (header.layout.text_bg): Bild füllt, dunkler
   Scrim darüber, Text in den Overlay-Farben – wie Hero und Projekte. */
.about__text--card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: var(--card-pad);
  border-radius: var(--radius-card);
  background: var(--color-media-fallback);
  color: var(--overlay-text);
}
.about__text-bg {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.about__text-bg-image { width: 100%; height: 100%; object-fit: cover; }
.about__text-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(11, 11, 12, 0.72);
}
.about__text--card .prose { color: var(--overlay-text-strong); }

@media (min-width: 48em) {
  .about {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    grid-template-areas:
      "label label"
      "media text";
    column-gap: var(--about-gap);
    align-items: start;
  }
  .about--image-right {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    grid-template-areas:
      "label label"
      "text media";
  }
  .about__media {
    position: sticky;
    top: calc(var(--header-h) + 2 * var(--header-gap));
  }
}

/* Kunden --------------------------------------------------------------- */
/* Logos: 2 pro Zeile auf dem Handy, ab Tablet maximal 4 */
.clients__list {
  display: grid;
  grid-template-columns: repeat(var(--logo-cols), minmax(0, 1fr));
  gap: var(--logo-gap);
  align-items: center;
}

.clients__item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--logo-height);
  padding: 0;
}
.clients__item a { display: block; width: 100%; max-width: var(--logo-max-width); }

.clients__logo {
  display: block;
  width: 100%;
  max-width: var(--logo-max-width);
  height: var(--logo-height);
  background-color: var(--logo-color);
  -webkit-mask: var(--logo) center / contain no-repeat;
  mask: var(--logo) center / contain no-repeat;
  opacity: 0.8;
  transition: opacity var(--duration) ease;
}
.clients__item:hover .clients__logo { opacity: 1; }

/* Auszeichnungen & Nominierungen ---------------------------------------
   Karte mit großer, weit gesperrter Überschrift, darunter die Liste.
   Hell: hellgraue Karte mit schwarzer Schrift, dunkel: fast schwarze Karte
   mit weißer Schrift – alles über die --awards-*-Farben unten.
   Mit Hintergrundbild liegt die Liste immer auf dunklem Bildgrund (Overlay-Farben).
   Jeder Eintrag ist eine kompakte Zeilengruppe: „JAHR Preis“ (Preis fett),
   darunter Art · Kategorie und die Produktion gedämpft. Keine Linien, keine Badges.
   Questrial hat nur einen Schnitt – der Browser fettet synthetisch, wie beim Hero-Namen. */
.awards {
  max-width: var(--section-narrow);
  margin-inline: auto;
  --award-size: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);      /* 18–24px Jahr + Preis */
  --award-gap: clamp(1.1rem, 0.8rem + 1vw, 1.75rem);        /* Abstand zwischen Einträgen */
  --awards-card-bg: light-dark(#e9e6df, #0b0b0c);
  --awards-text: light-dark(#1c1b19, #fbfaf8);
  --awards-text-strong: light-dark(rgba(28, 27, 25, 0.88), rgba(251, 250, 248, 0.9));
  --awards-text-soft: light-dark(rgba(28, 27, 25, 0.7), rgba(251, 250, 248, 0.82));
  --awards-text-muted: light-dark(rgba(28, 27, 25, 0.58), rgba(251, 250, 248, 0.62));
}
.awards__title {
  margin: 0 0 var(--space-label);
  font-size: clamp(1.375rem, 0.9rem + 2.2vw, 2.75rem);      /* 22–44px */
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--awards-text);
  overflow-wrap: anywhere;
}
.awards__card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: var(--card-pad) var(--card-pad) var(--card-pad-bottom);
  border-radius: var(--radius-card);
  background: var(--awards-card-bg);
  color: var(--awards-text);
}
/* Mit Bild: immer dunkler Bildgrund, daher in beiden Modi die Overlay-Farben */
.awards__card--image {
  background: var(--color-media-fallback);
  --awards-text: var(--overlay-text);
  --awards-text-strong: var(--overlay-text-strong);
  --awards-text-soft: var(--overlay-text-soft);
  --awards-text-muted: rgba(251, 250, 248, 0.62);
}
.awards__bg { position: absolute; inset: 0; z-index: -2; }
.awards__bg-image { width: 100%; height: 100%; object-fit: cover; }
.awards__scrim { position: absolute; inset: 0; z-index: -1; background: rgba(11, 11, 12, 0.78); }
.awards__intro { color: var(--awards-text-strong); }

.awards__list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 48rem;
}
.award + .award { margin-top: var(--award-gap); }
.award > * { margin: 0; }

.award__head {
  font-size: var(--award-size);
  line-height: 1.25;
  color: var(--awards-text);
  overflow-wrap: anywhere;
}
.award__year {
  font-weight: 400;
  color: var(--awards-text-soft);
  font-variant-numeric: tabular-nums;
  margin-right: 0.15em;
}
.award__name { font-weight: 600; }
.award__kind {
  margin-top: 0.1rem;
  font-size: var(--text-md);
  line-height: 1.4;
  color: var(--awards-text-strong);
}
.award__detail {
  margin-top: 0.05rem;
  font-size: var(--text-base);
  line-height: 1.45;
  color: var(--awards-text-muted);
}

/* Kontakt -------------------------------------------------------------- */
.contact__email {
  font-size: var(--text-xl);
  font-weight: 500;
  line-height: 1.15;
  overflow-wrap: anywhere;
}
.contact__email a { text-decoration-thickness: 2px; }

.contact__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--text-base);
  align-items: center;
}
.contact__link a {
  display: block;
  line-height: 0;
  opacity: 1;
  transition: opacity 0.2s ease;
}
.contact__link a:hover,
.contact__link a:focus-visible { opacity: 0.7; }
.contact__logo {
  display: block;
  height: 1.35rem;
  width: auto;
}
.contact__logo--crew-united { height: 1.7rem; }

/* Kontakt mit Hintergrundbild: gleiche Karte wie Hero/Projekt, Text als Overlay unten */
.contact--card {
  width: 100%;
  aspect-ratio: var(--card-ratio-max);
  min-height: var(--card-height);
}
.contact--card .section__label { color: var(--overlay-text-soft); margin-bottom: 0; }
.contact--card .section__intro { color: var(--overlay-text-strong); margin-bottom: 0; }
.contact--card a { color: inherit; }
.contact--card a:hover { color: var(--overlay-text-soft); }
.contact--card .contact__links { margin-top: 0.2rem; }

/* --------------------------------------------------------------------------
   Unterseiten (Impressum, Datenschutz)
   -------------------------------------------------------------------------- */
/* Unterseiten (Impressum, Datenschutz): volle Breite des Inhaltsbereichs */
.page {
  width: 100%;
  padding: clamp(2rem, 1rem + 4vw, 5rem) 0 0;
}

.page__title {
  font-size: var(--text-lg);
  font-weight: 500;
  line-height: 1.15;
  margin-bottom: var(--space-label);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.site-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 1.5rem;
  width: 100%;                      /* als Flex-Item im body sonst nur so breit wie der Inhalt */
  max-width: var(--content-max);
  margin-inline: auto;
  margin-top: calc(var(--space-section) / 2);   /* Abstand zum Inhalt darüber, auf allen Seiten gleich */
  padding-bottom: .5rem;
  font-size: var(--text-base);
  color: var(--color-text-label);
}

.site-footer__links {
  display: flex;
  gap: 1.5rem;
}
.site-footer__links a { text-decoration: none; }
.site-footer__links a:hover { color: var(--color-text); }

/* --------------------------------------------------------------------------
   Bewegung: keine. Falls später ein sanftes Einblenden gewünscht ist,
   hier ergänzen und in prefers-reduced-motion abschalten.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

@media print {
  .site-nav, .visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link { display: none; }
}
