/* ══════════════════════════ projects.css ══════════════════════════
   #projects: Projekt-Galerie als Scroll-Stapel.

   Vorbild ist die "Card Stack"-Komponente von Inspira UI
   (inspira-ui.com/docs/en/components/cards/card-stack, ein Vue-Port der
   Aceternity-UI-Komponente). Der öffentlich sichtbare Demo-Code zeigt nur
   die VERWENDUNG (CardStack/CardStackItem), nicht die Mechanik dahinter.
   Die echte Mechanik wurde daher direkt aus der live gerenderten Demo
   abgelesen (DOM/Computed-Styles inspiziert): KEINE Skalierung, KEIN
   scroll-gekoppeltes JS: nur position:sticky pro Karte, mit steigendem
   Innenabstand je Kartenindex. Im Original steckt das Ganze zusätzlich in
   einer eigenen, fest hohen Box mit eigenem Scrollbalken; hier bewusst
   OHNE Box. Der Stapel läuft direkt im normalen Seiten-Scroll (Abschnitt
   2), damit er sich in den Rest der Seite einfügt statt als eigenständiges
   Scroll-Fenster darin zu wirken. Der Hinweistext ist dabei bewusst
   kompakt (keine eigene, volle Slot-Höhe wie im Vorbild). Eine leere
   Seite in Slot-Höhe, bevor die erste Karte überhaupt auftaucht, wirkte
   vom Rest der Section abgetrennt statt wie ihr direkter Auftakt. Karten
   liegen normal untereinander, jede in einem eigenen, per position:sticky
   verankerten Slot. Der reine Sticky-Übergang beim Weiterscrollen sorgt
   schon für sich genommen dafür, dass die vorherige Karte oben aus dem
   Slot heraus- und die nächste unten hineinrutscht ("peekt"); ab der
   zweiten Karte rückt jede zusätzlich ein Stück (5/8/11% der Slot-Höhe)
   tiefer in ihren Slot: derselbe scale-multiplier-Wert (0.03) des
   Vorbilds, hier als Innenabstand statt als Skalierung genutzt. Kein JS
   nötig für die Bewegung selbst.

   Titel-Kopf und Tag-Pills sind wörtlich aus der vorherigen Fassung
   übernommen bzw. global aus about.css (Reveal-Mechanik). Derselbe
   Karten-/Pill-Look wie überall sonst auf der Seite, nur die Anordnung
   ist neu. */

#projects{
  display:block;
  padding:calc(var(--nav-h) + var(--gutter) * 1.4) var(--gutter) calc(var(--gutter) * 1.6);
}

.projects-wrap{
  display:flex;flex-direction:column;
  gap:var(--section-gap);
}


/* ─────────────────────────── 1. Kopf ──────────────────────────── */

.projects-intro{
  display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;
  gap:20px 32px;
}

/* Ab 960px: sticky Randspalte (Titel/Text/Hinweis) statt zentrierter
   Karte allein in der Fläche. Auf breiten Screens blieb sonst der ganze
   Bereich rechts und links der 640px-Karte einfach leer. Der Stapel
   bekommt so einen echten Nachbarn statt eine Ozean aus --bg drumherum,
   und die Sidebar bleibt beim Durchblättern des Stapels sichtbar stehen. */
@media (min-width:960px){
  .projects-wrap{
    display:grid;
    grid-template-columns:minmax(240px,320px) 1fr;
    align-items:start;
    gap:0 clamp(32px,5vw,72px);
  }
  .projects-intro{
    position:sticky;top:calc(var(--nav-h) + var(--gutter) + 8px);
    flex-direction:column;align-items:stretch;
    gap:16px;
  }
  /* Karte/Hinweis hängen sich links an die Sidebar statt in der Spalte
     zu zentrieren. Zentriert läge der Stapel auf breiten Screens
     irritierend "in der Mitte des Restplatzes" statt sichtbar neben der
     Sidebar zu stehen. */
  .project-stack-wrap{align-items:flex-start}
  .project-stack-intro,
  .project-stack-card{margin-left:0; margin-right:0}
}

.projects-title{
  position:relative;
  margin:0;
  padding-bottom:14px;
  font-family:'Space Grotesk',ui-sans-serif,system-ui,sans-serif;
  font-size:clamp(32px,5vw,52px);font-weight:600;letter-spacing:-.02em;
  color:var(--ink);
}
.projects-title .accent{color:var(--accent-ink)}
/* Derselbe Signatur-Strich wie .about-title und .contact-title: roter
   Faden, der sich durch alle Haupttitel der Seite zieht. */
.projects-title::after{
  content:'';
  position:absolute;left:0;bottom:0;
  width:44px;height:3px;border-radius:2px;
  background:var(--accent);
}

.projects-text{
  margin:0;
  max-width:46ch;
  font-size:clamp(15px,1.4vw,17px);line-height:1.7;
  color:var(--muted);
}


/* ─────────────────────────── 2. Scroll-Stapel ───────────────────────
   Grundzustand (reduzierte Bewegung): eine ganz ruhige Liste.
   Hinweistext, dann die Karten untereinander auf voller Grösse. Das ist
   ein vollständiges, nur unbewegtes Bild, kein Fehlerzustand.

   @media (prefers-reduced-motion:no-preference) schaltet auf den
   eigentlichen Effekt um: reines CSS, kein JS nötig für die Bewegung,
   und OHNE eigene Scroll-Box (die Seite selbst scrollt, siehe
   Kopf-Kommentar). Jede Karte steckt in einem eigenen .project-stack-slot,
   per position:sticky knapp unter der Navbar verankert. Der native
   Sticky-Übergang beim Weiterscrollen sorgt schon allein dafür, dass die
   vorherige Karte oben aus ihrem Slot heraus- und die nächste unten
   hineinrutscht ("peekt"). Ab der zweiten Karte rückt jede zusätzlich ein
   Stück (5/8/11% der Slot-Höhe, nth-of-type unten) tiefer in ihren Slot:
   derselbe scale-multiplier-Wert (0.03) des Vorbilds, hier als
   Innenabstand statt als Skalierung genutzt. */
.project-stack-wrap{
  display:flex;flex-direction:column;align-items:center;
  gap:var(--spacing-20);
}

.project-stack{
  --slot-h:clamp(420px,58vh,560px);
  position:relative;
  width:100%;
}

.project-stack-intro{
  margin:0 auto var(--spacing-20);
  max-width:720px;
  text-align:center;
  font-size:13px;font-weight:500;letter-spacing:.02em;
  color:var(--muted);
}
.project-stack-intro span{color:var(--accent-ink)}

/* position:relative als Bezugsrahmen für den Cursor-Glow (::before,
   Abschnitt 4). */
.project-stack-card{
  position:relative;
  width:100%;max-width:720px;
  margin:0 auto var(--spacing-20);
  display:flex;flex-direction:column;
  padding:clamp(24px,3.6vw,40px);
  border-radius:var(--radius-card);
  background:var(--surface);
  border:1px solid var(--hairline);
  box-shadow:0 1px 0 rgba(255,255,255,.6) inset, var(--shadow-xl);
  transition:border-color .3s var(--settle), box-shadow .3s var(--settle);
}
.project-stack-card:last-child{margin-bottom:0}

@media (prefers-reduced-motion:no-preference){
  .project-stack-slot{
    position:sticky;
    top:calc(var(--nav-h) + var(--gutter));
    height:var(--slot-h);
  }
  .project-stack-slot .project-stack-card{
    margin:0 auto;
    top:0;
  }
  /* 5/8/11%: erste Karte bekommt schon einen kleinen Vorsprung (wie im
     Vorbild), jede weitere rutscht 3 Prozentpunkte tiefer: top statt
     margin-top, weil Prozentwerte bei top/bottom (anders als bei
     margin/padding) an der Höhe des Containing Blocks bemessen werden,
     hier also korrekt an --slot-h statt an der Breite. */
  .project-stack-slot:nth-of-type(1) .project-stack-card{top:5%}
  .project-stack-slot:nth-of-type(2) .project-stack-card{top:8%}
  .project-stack-slot:nth-of-type(3) .project-stack-card{top:11%}
  .project-stack-slot:nth-of-type(4) .project-stack-card{top:14%}
  .project-stack-slot:nth-of-type(5) .project-stack-card{top:17%}
}

/* Dezenter Farbverlauf fürs Vorzeigeprojekt des Stapels: dasselbe Muster
   wie .skill-group.is-featured. */
.project-stack-card.is-featured{
  background:linear-gradient(160deg, rgba(218,41,28,.06), var(--surface) 55%);
  border-color:rgba(218,41,28,.16);
}

.project-stack-top{
  display:flex;align-items:center;gap:14px;
  margin-bottom:20px;
}
.project-stack-icon{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:52px;height:52px;border-radius:50%;
  background:rgba(218,41,28,.08);
}
.project-stack-icon .project-glyph{
  width:25px;height:25px;
  fill:none;stroke:var(--accent-ink);stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
}

.project-stack-desc{
  margin:0;flex:1;
  /* line-clamp statt freier Höhe: alle Karten im Stapel müssen exakt
     gleich hoch bleiben, egal wie lang ihr jeweiliger Text ist. Sonst
     ändert sich die Stapelhöhe bei jedem Weiterblättern. */
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:4;
  overflow:hidden;
  font-size:16px;line-height:1.7;
  color:var(--muted);
}

.project-stack-foot{
  margin-top:20px;padding-top:20px;
  border-top:1px solid var(--hairline);
}
.project-stack-title{
  margin:0 0 12px;
  font-family:'Space Grotesk',ui-sans-serif,system-ui,sans-serif;
  font-size:clamp(20px,2.2vw,24px);font-weight:600;letter-spacing:-.01em;
  color:var(--ink);
}
.project-stack-foot .project-tags{margin:0}


/* ─────────────────────────── 3. Kartentext ───────────────────────────
   Meta (Art) und Tag-Pills. */

.project-meta{
  display:flex;align-items:center;gap:10px;
}
.project-kind{
  font-size:13.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--accent-ink);
}
.project-tags{
  display:flex;flex-wrap:wrap;gap:8px;
  margin:16px 0 0;padding:0;list-style:none;
}
.project-tag{
  padding:5px 13px;
  border-radius:var(--radius-tag);
  background:var(--bg);
  border:1px solid var(--hairline);
  font-size:12.5px;font-weight:500;
  color:var(--muted);
}


/* ────────────────── 4. Cursor-Glow (nur echter Zeiger) ─────────────
   Identisches Muster wie about.css Abschnitt 5: --mx/--my kommen von
   js/projects.js bei jeder Zeigerbewegung, hier nur als Aussehen
   übersetzt. Läuft auf allen Karten, sichtbar wird der Schein aber vor
   allem auf der jeweils obersten. Zurückliegende Karten sind zu einem
   grossen Teil von der nächsten verdeckt und bekommen deshalb kaum
   Zeigerereignisse ab. */
@media (hover:hover) and (pointer:fine){
  .project-stack-card{--mx:50%; --my:50%}

  .project-stack-card::before{
    content:'';
    position:absolute;inset:0;z-index:0;
    border-radius:inherit;
    background:radial-gradient(260px circle at var(--mx) var(--my), rgba(218,41,28,.10), transparent 70%);
    opacity:0;
    transition:opacity .35s var(--settle);
    pointer-events:none;
  }
  .project-stack-card:hover::before{opacity:1}
}


