/* ============================================================
   plexcreates — Stylesheet

   Haltung: dunkel, ruhig, kuratiert. Das Video traegt, die
   Typografie fuehrt. Eine Akzentfarbe, sparsam eingesetzt —
   sie markiert nur, wo etwas lebt oder anklickbar ist.
   ============================================================ */

:root {
  --bg:        #08090a;
  --ink:       #f2f2f0;
  --dim:       rgba(242, 242, 240, 0.52);
  --faint:     rgba(242, 242, 240, 0.3);
  --hair:      rgba(242, 242, 240, 0.13);
  --hair-soft: rgba(242, 242, 240, 0.07);

  /* Die eine Farbe */
  --acc:       #ff4a21;
  --acc-soft:  rgba(255, 74, 33, 0.5);

  --inset: clamp(1.1rem, 2.8vw, 2.4rem);

  --ease:  cubic-bezier(0.22, 1, 0.36, 1);
  --swift: cubic-bezier(0.33, 1, 0.68, 1);

  --sans: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

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

body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.page-home { height: 100svh; overflow: hidden; }

::selection { background: var(--acc); color: #fff; }

a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

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

/* ------------------------------------------------------------
   Hintergrund
   ------------------------------------------------------------ */

.bg { position: fixed; inset: 0; z-index: -3; overflow: hidden; background: var(--bg); }

/* Das Video laeuft unangetastet: keine Skalierung, keine
   Dauerbewegung, kein Filter. Jede davon zwingt den Browser, jeden
   Frame neu zu rechnen — und genau das kostet Bilder pro Sekunde. */
.bg-inner { position: absolute; inset: 0; }

.bg video {
  width: 100%; height: 100%;
  object-fit: cover;
}

/* Abdunkeln uebernimmt eine Ebene, kein Filter — die kostet nichts.
   Gleichmaessig ueber die ganze Flaeche, dazu ein weicher
   Randabfall. Kein Schatten hinter der Wortmarke. */
.bg-grade {
  position: absolute; inset: 0;
  background:
    radial-gradient(142% 116% at 50% 50%, rgba(4, 5, 6, 0) 52%, rgba(4, 5, 6, 0.58) 100%),
    linear-gradient(rgba(4, 5, 6, 0.48), rgba(4, 5, 6, 0.48));
}

/* ------------------------------------------------------------
   Eye Candy: Licht am Cursor, Korn, Rahmen
   ------------------------------------------------------------ */

.grain {
  position: fixed; inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Der einzige Farbakzent im Bild: ein duenner Strich oben */
.edge {
  position: fixed;
  left: 0; right: 0;
  top: var(--inset);
  height: 2px;
  z-index: 6;
  pointer-events: none;
  background: var(--acc);
  opacity: 0;
}

.is-ready .edge { opacity: 1; transition: opacity 1.3s var(--ease) 0.5s; }

/* ------------------------------------------------------------
   Raster der Startseite
   ------------------------------------------------------------ */

.shell {
  position: relative;
  z-index: 5;
  height: 100svh;
  display: grid;
  padding: calc(var(--inset) + clamp(0.9rem, 2vw, 1.6rem));
}

/* ------------------------------------------------------------
   Kopf
   ------------------------------------------------------------ */

/* Nur auf den Unterseiten: eine schlichte Kopfzeile, kein Glas */
.top {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: clamp(46px, 5.4vh, 58px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 clamp(0.9rem, 2vw, 1.6rem);
  opacity: 0;
}

.is-ready .top { opacity: 1; transition: opacity 1s var(--ease) 0.55s; }

/* Der Kopfinhalt blendet beim Scrollen aus. Das laeuft ueber eine
   eigene Variable auf den Kindern, damit es sich nicht mit der
   Einblendung der Leiste beim Seitenaufbau in die Quere kommt. */
.top > * { opacity: var(--fade, 1); }

/* Auf den Unterseiten fuehrt die Marke zurueck zur Startseite.
   Sie steht absolut links, damit die Links exakt mittig bleiben. */
.mark {
  position: absolute;
  left: clamp(0.9rem, 2vw, 1.6rem);
  font-family: var(--sans);
  font-size: clamp(0.9rem, 1.4vw, 1.05rem);
  font-weight: 500;
  letter-spacing: -0.045em;
  color: var(--dim);
  transition: color 0.35s var(--ease);
}

.mark:hover { color: var(--ink); }

.nav-links {
  display: flex;
  gap: clamp(1.3rem, 2.8vw, 2.6rem);
  list-style: none;
}

/* Auf der Startseite sitzt die Navigation unter der Wortmarke und
   nimmt genau deren Breite ein: aussen buendig, innen verteilt. */
.page-home .nav { width: 100%; margin-top: clamp(0.9rem, 2.4vh, 1.8rem); }

.page-home .nav-links {
  width: 100%;
  gap: 0;
  justify-content: space-between;
}

/* Gleiche Schrift und gleicher Sperrsatz wie die Wortmarke */
.nav-links a {
  position: relative;
  isolation: isolate;
  display: block;
  font-family: var(--sans);
  font-size: clamp(0.95rem, 1.5vw, 1.18rem);
  font-weight: 400;
  letter-spacing: -0.045em;
  color: var(--dim);
  transition: color 0.3s var(--ease), font-weight 0.35s var(--ease);
}

/* Das gefuellte Rechteck liegt ausserhalb des Textflusses und
   hinter der Schrift, damit es die Verteilung in der Zeile nicht
   verschiebt. */
.nav-links a::before {
  content: "";
  position: absolute;
  inset: -0.4em -0.62em;
  z-index: -1;
  background: var(--acc);
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 0.28s var(--ease), transform 0.45s var(--ease);
  pointer-events: none;
}

.nav-links a:hover::before,
.nav-links a:focus-visible::before { opacity: 1; transform: none; }

/* Ein unsichtbarer fetter Zwilling haelt die Breite fest.
   Sonst ruckt die Zeile, sobald ein Wort fett wird. */
.nav-links a::after {
  content: attr(data-text);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
  pointer-events: none;
  user-select: none;
}

.nav-links a:hover { color: #fff; font-weight: 700; }

.nav-links a.active { color: var(--ink); font-weight: 700; }

/* ------------------------------------------------------------
   Wortmarke
   ------------------------------------------------------------ */

/* Mittig, aber ein Stueck ueber der geometrischen Mitte */
.hero {
  place-self: center;
  margin-bottom: clamp(1.5rem, 7vh, 6rem);
}

/* Exakt dieselbe Schrift wie die Ueberschrift auf den Unterseiten */
.wordmark,
.page-head h1 {
  font-family: var(--sans);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 1;
}

.wordmark {
  font-size: clamp(2.6rem, 12vw, 11rem);
  white-space: nowrap;
}

/* Jeder Buchstabe faehrt aus seiner eigenen Blende hoch.
   Die Blende ist rundum groesser als die Glyphe: oben fuer die
   Oberlaenge, unten fuers p, seitlich weil der negative Sperrsatz
   die Buchstaben sonst in den Nachbarkasten schiebt und dort
   abgeschnitten wird. Die negativen Aussenabstaende holen den
   Platz vollstaendig wieder aus dem Layout. */
.wordmark .col {
  display: inline-block;
  overflow: hidden;
  vertical-align: baseline;
  padding: 0.26em 0.1em 0.36em;
  margin: -0.26em -0.1em -0.36em;
}

.wordmark .col > span {
  display: inline-block;
  transform: translateY(160%);
}

.is-ready .wordmark .col > span {
  transform: none;
  transition: transform 1.05s var(--ease);
}

/* ------------------------------------------------------------
   Unterseiten
   ------------------------------------------------------------ */

.page-sub .bg-inner { animation: none; transform: scale(1.06); }
.page-sub .bg video { filter: blur(9px) brightness(0.42); }
.page-sub .bg-grade { background: rgba(6, 7, 8, 0.82); }

.page {
  position: relative;
  z-index: 5;
  max-width: 2000px;
  margin: 0 auto;
  padding: clamp(6rem, 14vh, 9rem) clamp(1rem, 2.2vw, 2rem) clamp(3rem, 7vh, 5rem);
}

.page-head { margin-bottom: clamp(2.5rem, 6vh, 4.5rem); }

.page-head h1 { font-size: clamp(2rem, 6vw, 4.2rem); }

.page-head p {
  margin-top: 1.1rem;
  max-width: 52ch;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--dim);
}

/* Hoechstens drei nebeneinander, danach stapeln.
   Alle Kacheln gleich gross, gleicher Abstand, 16:9. */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.7rem, 1.4vw, 1.2rem);
}

/* ------------------------------------------------------------
   Kacheln

   Grundsatz gegen das Ruckeln: waehrend eines Hovers darf nur
   noch die Grafikkarte arbeiten. Bewegt werden ausschliesslich
   transform und opacity — beides kann der Compositor ohne
   Neuzeichnen. Kein filter, kein box-shadow, kein blend mode in
   einer Uebergangszeit.

   Die Entsaettigung steckt deshalb nicht in einem CSS-Filter,
   sondern in einer zweiten, bereits entsaettigten Bilddatei. Beim
   Hover wird nur das farbige Bild darueber eingeblendet.
   ------------------------------------------------------------ */

.tile {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #101113;
  transform: translateZ(0);
  contain: paint;
}

/* Nur dieser Kasten wird skaliert — einmal als Textur hochgeladen,
   danach kostet der Zoom nichts mehr. */
.tile-media {
  position: absolute;
  inset: 0;
  transform: scale(1.02);
  transition: transform 0.75s var(--ease);
  will-change: transform;
}

.tile:hover .tile-media,
.tile:focus-visible .tile-media { transform: scale(1.07); }

.tile .im {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  backface-visibility: hidden;
}

/* das farbige Bild liegt oben und wird eingeblendet */
.tile .im-full {
  opacity: 0;
  transition: opacity 0.5s var(--ease);
  will-change: opacity;
}

.tile:hover .im-full,
.tile:focus-visible .im-full { opacity: 1; }

/* Kontur: der Schatten wird einmal gezeichnet, bewegt wird nur
   die Deckkraft */
.tile::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px var(--hair);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
  will-change: opacity;
}

.tile:hover::before, .tile:focus-visible::before { opacity: 1; }

/* Akzentkante faehrt beim Hover an der Unterkante ein */
.tile::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--acc);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.6s var(--ease);
  will-change: transform;
  z-index: 3;
}

.tile:hover::after, .tile:focus-visible::after { transform: scaleX(1); }

.tile-label {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  padding: 3rem 1rem 0.95rem;
  background: linear-gradient(180deg, transparent, rgba(6, 7, 8, 0.88));
  opacity: 0;
  transform: translate3d(0, 8px, 0);
  transition: opacity 0.45s var(--ease), transform 0.55s var(--ease);
}

.tile:hover .tile-label,
.tile:focus-visible .tile-label { opacity: 1; transform: translate3d(0, 0, 0); }

.tile-label h3 { font-size: 0.95rem; font-weight: 500; letter-spacing: -0.02em; }

/* ------------------------------------------------------------
   Projektseite
   ------------------------------------------------------------ */

.back {
  display: inline-block;
  margin-bottom: clamp(1.2rem, 3vh, 2.2rem);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
  transition: color 0.3s var(--ease);
}

.back:hover { color: var(--acc); }

.page-work .page-head { margin-bottom: clamp(1.4rem, 3.5vh, 2.4rem); }

/* Begleittext auf einer Projektseite */
.work-note {
  margin-top: clamp(1.6rem, 4vh, 2.6rem);
  max-width: 56ch;
}

.work-note p {
  color: var(--dim);
  font-size: 0.95rem;
  margin-bottom: 0.9rem;
}

.work-note p:last-child { margin-bottom: 0; }
.work-note em { font-style: italic; color: var(--ink); }

/* Namen im Text und in den Fakten fuehren zur jeweiligen Seite */
.work-note a,
.work-facts dd a {
  color: var(--ink);
  border-bottom: 1px solid var(--hair);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}

.work-note a:hover,
.work-facts dd a:hover { color: var(--acc); border-color: var(--acc); }

.work-facts {
  margin-top: clamp(1.8rem, 4vh, 2.8rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--hair-soft);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1.3rem;
  max-width: 58ch;
}

/* Renderseiten: ruhiges Grau statt Video. Das Bild soll das
   einzige sein, was hier Aufmerksamkeit bekommt. */
.page-render { background: #1a1b1e; }

.shots { position: relative; z-index: 5; }

/* Volle Breite bis kurz vor den Rand. Die Hoehe ergibt sich aus
   dem Seitenverhaeltnis — Hochformate werden also hoeher als der
   Bildschirm, dafuer scrollt man. Nichts wird beschnitten und
   nichts wird kleingerechnet. */
.shots { padding-bottom: clamp(1rem, 2.6vw, 2.4rem); }

.shot { width: 100%; padding: clamp(0.9rem, 2.4vw, 2.2rem); }
.shot + .shot { padding-top: 0; }

.shot img,
.shot video {
  display: block;
  width: 100%;
  height: auto;
}

/* Kapitelmarke, z. B. vor dem Behind-the-Scenes-Teil */
.chapter {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  padding: clamp(3.5rem, 11vh, 8rem) clamp(0.9rem, 2.4vw, 2.2rem) clamp(2.5rem, 7vh, 5rem);
}

.chapter-rule {
  flex: none;
  width: clamp(2rem, 6vw, 5rem);
  height: 2px;
  background: var(--acc);
}

.chapter h2 {
  font-size: clamp(0.95rem, 1.6vw, 1.15rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.about { max-width: 62ch; }

.panel { padding-top: 0.3rem; }

.panel h2 {
  font-size: clamp(1.3rem, 2.6vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  margin-bottom: 1.3rem;
}

.panel p { color: var(--dim); margin-bottom: 1.1rem; font-size: 0.95rem; }
.panel p:last-child { margin-bottom: 0; }
.panel strong { color: var(--ink); font-weight: 500; }

.tag-group { margin-top: clamp(1.6rem, 3.5vh, 2.4rem); }

.tag-title {
  display: block;
  margin-bottom: 0.7rem;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.tags { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.panel > .tags { margin-top: 1.9rem; }

.tag {
  font-family: var(--mono);
  font-size: 0.63rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.4rem 0.75rem;
  color: var(--dim);
  border: 1px solid var(--hair-soft);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}

.tag:hover { color: var(--ink); border-color: var(--acc); }

.facts {
  margin-top: 2.2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--hair-soft);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1.3rem;
}

.fact dt {
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}

.fact dd { margin-top: 0.4rem; font-size: 0.9rem; }
.fact dd a { border-bottom: 1px solid var(--hair); transition: border-color 0.35s var(--ease), color 0.35s var(--ease); }
.fact dd a:hover { color: var(--acc); border-color: var(--acc); }

/* ------------------------------------------------------------
   Lightbox
   ------------------------------------------------------------ */

.lightbox {
  position: fixed; inset: 0;
  z-index: 200;
  display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(6, 7, 8, 0.9);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  opacity: 0; visibility: hidden;
  transition: opacity 0.4s var(--ease), visibility 0.4s var(--ease);
}

.lightbox.open { opacity: 1; visibility: visible; }

.lightbox img {
  max-width: 100%; max-height: 82vh;
  transform: scale(0.98);
  transition: transform 0.6s var(--ease);
}

.lightbox.open img { transform: none; }

.lightbox-caption {
  margin-top: 1.1rem; text-align: center;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--dim);
}

.lightbox-close {
  position: absolute;
  top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem);
  width: 38px; height: 38px;
  border: 1px solid var(--hair);
  background: none;
  cursor: pointer;
  display: grid; place-items: center;
  color: var(--ink);
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease);
}

.lightbox-close:hover { background: var(--acc); border-color: var(--acc); }

/* ------------------------------------------------------------
   Footer der Unterseiten
   ------------------------------------------------------------ */

.footer {
  position: relative;
  z-index: 5;
  padding: 1.5rem clamp(1rem, 2.2vw, 2rem);
  border-top: 1px solid var(--hair-soft);
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

.footer a:hover { color: var(--acc); }

/* ------------------------------------------------------------
   Reveal beim Scrollen
   ------------------------------------------------------------ */

.reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

/* ------------------------------------------------------------
   Responsive
   ------------------------------------------------------------ */

@media (max-width: 980px) {
  .grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 620px) {
  .grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .wordmark { font-size: clamp(2.1rem, 13.5vw, 4rem); }
  .nav-links { gap: 1.1rem; }
  .nav-links a, .mark { font-size: 0.88rem; }
  .work-facts { grid-template-columns: 1fr; gap: 1rem; }
}

/* Unter dieser Breite wuerde die Marke links in die mittig
   gesetzten Links laufen. "Home" fuehrt ohnehin zum selben Ziel. */
@media (max-width: 520px) {
  .mark { display: none; }
}

@media (max-width: 420px) {
  .shell { padding: calc(var(--inset) + 0.35rem); }
  .wordmark { font-size: 12.4vw; }
  .nav-links a { font-size: 0.8rem; }
}

/* ------------------------------------------------------------
   Geraete ohne Mauszeiger

   Auf dem Handy gibt es kein Hover. Ohne diesen Block blieben die
   Kacheln dauerhaft entsaettigt und ohne Titel — der Besucher
   wuesste nicht, wie die Projekte heissen.
   ------------------------------------------------------------ */

@media (hover: none) {
  .tile .im-full { opacity: 1; }
  .tile-label { opacity: 1; transform: none; }
  .tile::after { transform: scaleX(1); }

  .nav-links a { color: var(--ink); }
  .nav-links a::before { display: none; }
}

/* kein blauer Kasten beim Antippen */
a, button { -webkit-tap-highlight-color: transparent; }

/* ------------------------------------------------------------
   Reduzierte Bewegung
   ------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .wordmark .col > span { transform: none; }
  .top { opacity: 1; }
}
