/* =========================================================================
   Garlef Meyer — Portfolio
   Statisches CSS im Stil des Cargo-Templates "F853". Keine Frameworks,
   keine externen Requests. Design-Tokens als Custom Properties auf :root.
   ========================================================================= */

:root {
  --bg: #ffffff;
  --text: rgba(0, 0, 0, .85);
  --muted: rgba(0, 0, 0, .4);
  --line: rgba(0, 0, 0, .1);
  --accent: #ff0000;
  --font: "Hanken Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --index-size: 4.5rem;
  --body-size: 1.1rem;
  --pad: .5rem;
}

/* Dark-Theme: per Attribut html[data-theme="dark"] aktivierbar (siehe README) */
html[data-theme="dark"] {
  --bg: #191919;
  --text: rgba(255, 255, 255, .85);
  --muted: rgba(255, 255, 255, .4);
  --line: rgba(255, 255, 255, .15);
}

/* --- Schrift: Hanken Grotesk, selbst gehostet, variabel (100–900) -------- */

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/HankenGrotesk-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/HankenGrotesk-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/HankenGrotesk-italic-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/HankenGrotesk-italic-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* --- Basis --------------------------------------------------------------- */

* {
  box-sizing: border-box;
}

html {
  /* 1.08vw gedeckelt, damit die Schrift auf sehr großen/kleinen Screens
     nicht aus dem Ruder läuft */
  font-size: clamp(8px, 1.08vw, 17px);
}

@media (max-width: 767px) {
  html {
    font-size: clamp(9px, 2.688vw, 13px);
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
}

a {
  color: inherit;
  text-decoration: none;
}

a:active {
  opacity: .7;
}

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: .7rem 0;
}

img {
  max-width: 100%;
}

/* --- Index (Startseite / Navigation) -------------------------------------- */

.index {
  padding: var(--pad) 5rem var(--pad) var(--pad);
  padding-bottom: 2.2rem;
}

@media (max-width: 767px) {
  .index {
    padding: .6rem;
    padding-bottom: 2.2rem;
  }
}

.index h1 {
  font-size: var(--index-size);
  font-weight: 400;
  line-height: .95;
  letter-spacing: -.015em;
  font-feature-settings: "tnum";
  color: var(--text);
  margin: 0;
}

@media (max-width: 767px) {
  .index h1 {
    font-size: 2.65rem;
  }
}

/* Hängender Einzug: automatisch für jede Zeile, auch bei Zeilenumbruch.
   inline-block (statt block): die <br>-Zeilenumbrüche im Markup erzeugen
   sonst zusammen mit block einen doppelten Zeilenabstand; außerdem bliebe
   bei block der Klickbereich über die volle Zeilenbreite bestehen, sodass
   ein Klick neben den Text (Index-Hintergrund) fälschlich den Link träfe. */
.index a {
  display: inline-block;
  max-width: 100%;
  padding-left: 1.4em;
  text-indent: -1.4em;
}

.index a.is-active {
  color: var(--accent);
}

/* --- Bodycopy: Captions, Fließtext, Footer -------------------------------- */

.bodycopy {
  font-size: var(--body-size);
  font-weight: 450;
  line-height: 1;
  letter-spacing: 0;
  color: var(--text);
}

/* Leerzeilen-Platzhalter innerhalb der Bodycopy-Overlays (Größe in em, also
   relativ zur 1.1rem-Bodycopy, damit "3 Leerzeilen" wirklich 3 Zeilen hoch sind) */
.spacer-3 {
  height: 3em;
}

.spacer-2 {
  height: 2em;
}

/* --- Overlays: Grundverhalten --------------------------------------------
   Ohne JS (kein ".js" am <html>) sind alle Overlays normale, sichtbare
   Abschnitte im Textfluss unterhalb des Index — so bleibt die Seite ohne
   JavaScript vollständig lesbar. Erst mit JS werden sie zu echten,
   positionierten Overlays, die per Hash-Routing ein-/ausgeblendet werden. */

.overlay {
  background: var(--bg);
  padding: 1rem;
}

html:not(.js) .overlay {
  border-top: 1px solid var(--line);
}

.js .overlay:not(.is-open) {
  display: none;
}

/* Der programmatische Fokus (nach Öffnen per Klick/Hash/Esc) soll keinen
   Fokusring zeigen; das Overlay selbst ist kein interaktives Steuerelement. */
.overlay:focus {
  outline: none;
}

/* Bild-Overlay: oben links, 50% Breite, nur so hoch wie der Inhalt */
.js .overlay-image {
  position: fixed;
  top: 0;
  left: 0;
  width: 50%;
  /* Sicherheitsnetz: falls Bild + Caption trotz max-height am Bild dennoch
     mehr Platz brauchen als der Viewport hoch ist, lieber intern scrollen
     als über den Viewport hinauswachsen. */
  max-height: 100dvh;
  overflow-y: auto;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  z-index: 20;
}

/* Text-/Info-Overlay: oben rechts, 50% Breite, volle Höhe, scrollbar */
.js .overlay-text {
  position: fixed;
  top: 0;
  right: 0;
  width: 50%;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  border-left: 1px solid var(--line);
  z-index: 30;
}

@media (max-width: 767px) {
  .js .overlay-image,
  .js .overlay-text {
    width: 100%;
  }
}

/* --- Slideshow (Bild-Overlay) ---------------------------------------------- */

.slideshow {
  position: relative;
  margin-bottom: .5em;
}

.slide {
  margin: 0;
  display: none;
}

.slide.is-current {
  display: block;
}

.slide img {
  display: block;
  max-width: 100%;
  width: auto;
  height: auto;
  /* Hochformate dürfen das Overlay nicht über den Viewport wachsen lassen,
     sonst ist die Caption-Zeile darunter nicht mehr erreichbar. Hochformate
     werden dadurch schmaler als das Overlay dargestellt — das ist gewollt. */
  max-height: calc(100dvh - 5rem);
}

.slide video { display: block; width: 100%; height: auto; max-height: calc(100dvh - 5rem); }

/* Cursor-Zonen: linke Hälfte = zurück, rechte Hälfte = weiter.
   Eigene SVG-Pfeile als data-URI, kein Wechsel-Animation (transition: 0). */
.zone {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
}

.zone--prev {
  left: 0;
  cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='32'%20height='32'%20viewBox='0%200%2032%2032'%3E%3Cpath%20d='M19%205%20L9%2016%20L19%2027'%20fill='none'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E") 16 16, w-resize;
}

.zone--next {
  right: 0;
  cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='32'%20height='32'%20viewBox='0%200%2032%2032'%3E%3Cpath%20d='M13%205%20L23%2016%20L13%2027'%20fill='none'%20stroke='black'%20stroke-width='3'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E") 16 16, e-resize;
}

/* Nur ein Bild: keine Zonen, kein Wechsel-Cursor */
.slideshow.is-single .zone {
  display: none;
}

/* Caption-Zeile unter der Slideshow: 8/4-Spalten, Gutter .5rem */
.caption-row {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: .5rem;
  align-items: start;
}

.caption-row .more-close {
  text-align: right;
}

/* --- Text-/Info-Overlay: zweispaltige Layouts ------------------------------ */

.cols-2 {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: .5rem;
}

/* Fließtext wie im Buch: erster Absatz ohne Einzug, ab dem zweiten mit */
.prose p {
  margin: 0;
}

.prose p + p {
  text-indent: 3em;
}

.close-row {
  text-align: right;
}

/* Bildraster im Text-Overlay: 2 Spalten, Gutter .5rem */
.image-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: .5rem;
}

.image-grid figure {
  margin: 0;
}

.image-grid img {
  display: block;
  width: 100%;
  height: auto;
}

.image-grid figcaption {
  margin-top: .5em;
  margin-bottom: 2em;
}

/* CV-Abschnitte im Info-Overlay: Label links, Einträge rechts */
.cv-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: .5rem;
}

.cv-row .entries p {
  margin: 0 0 1em 0;
}

.cv-row .entries p:last-child {
  margin-bottom: 0;
}

/* --- Footer ---------------------------------------------------------------- */

.footer {
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 10;
  padding: var(--pad);
  font: 450 1.1rem/1 var(--font);
  color: var(--muted);
  background: var(--bg);
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
}

.footer button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.footer a {
  color: var(--muted);
  text-decoration: none;
}

/* --- Projekt 08: Interferenz, live (interaktiver WebGL-Canvas) ------------ */

.overlay-live .live-canvas {
  display: block;
  width: 100%;
  height: auto;
  max-height: calc(100dvh - 14rem);
  touch-action: none;
  cursor: crosshair;
  background: #071b3f;
}

.overlay-live .live-fallback {
  max-height: calc(100dvh - 14rem);
  overflow: hidden;
}

.overlay-live .live-fallback img {
  display: block;
  width: 100%;
  height: auto;
}

.live-controls {
  margin-top: .5rem;
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: space-between;
}

.live-controls .live-info {
  color: var(--muted);
}

/* Hervorgehobener Weiterlese-Link (z. B. Volltext) */
.read-more {
  display: inline-block;
  margin-top: .6em;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
  text-decoration-color: rgba(0, 0, 0, .35);
}
.read-more:hover {
  color: var(--accent);
  text-decoration-color: currentColor;
}
html[data-theme="dark"] .read-more { text-decoration-color: rgba(255, 255, 255, .4); }

/* Lange Wörter (z. B. Kommunikationsdesign) dürfen Spalten nicht sprengen */
.overlay-text, .caption-row { overflow-wrap: anywhere; hyphens: manual; }
.overlay-text > *, .cols-2 > *, .cv-row > *, .caption-row > * { min-width: 0; }

/* Mobil: Text-/Info-Spalten untereinander statt nebeneinander (keine schmalen Spalten, keine Silbentrennung) */
@media (max-width: 767px) {
  .overlay-text .cols-2,
  .overlay-text .cv-row {
    grid-template-columns: minmax(0, 1fr);
    gap: .35rem;
  }
  .overlay-text .cv-row > :first-child {
    color: var(--muted);
  }
  .overlay-text .cols-2 + br,
  .overlay-text .cv-row + br {
    display: none;
  }
  .overlay-text .cols-2 > * + * {
    margin-top: .8em;
  }
}
