/* ==========================================================================
   Portfolio-Generator — /portfolio
   --------------------------------------------------------------------------
   Two stylesheets in one file, because they are two different media and share
   exactly one thing: the tokens.

   1. THE TOOL (screen). Looks like lukaszerbst.com and is meant to: the same
      grey the portfolio sits on, the same three faces, the same outlined
      wordmark, the site's orange replaced throughout by the dimmed black —
      exactly the way /share and /collect dress a document page.

   2. THE DOCUMENT (screen preview AND print). An A4 landscape sheet, 297 × 210
      mm, drawn once and shown twice: on screen it floats at a scale the browser
      can fit, in print it is the paper. Everything inside it is expressed in
      millimetres so the two agree by construction rather than by tuning.

   The tool's classes are `pg-`, the document's are `pd-`, and nothing crosses.
   ========================================================================== */

:root {
  /* Straight out of assets/css/main.css — same values, not lookalikes. */
  --pg-dark:  #171919;
  --pg-light: #e6e6e6;

  --pg-fg:    var(--pg-dark);
  --pg-muted: rgba(23, 25, 25, 0.62);
  --pg-faint: rgba(23, 25, 25, 0.42);
  --pg-line:  rgba(23, 25, 25, 0.16);
  --pg-hair:  rgba(23, 25, 25, 0.09);

  --pg-font-title: "Montserrat Alternates", system-ui, sans-serif;
  --pg-font-body:  "Forum", Georgia, serif;

  --pg-head-h: 5.4rem;
  --pg-bar-h:  4.2rem;
  --pg-pad:    clamp(1.1rem, 4vw, 3rem);
}

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

.pg-html { height: 100%; }

.pg {
  min-height: 100dvh;
  height: 100dvh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  /* Not `1fr`, and not left implicit. A grid item's default `min-width: auto`
     means it may not shrink below its content, and that minimum propagates all
     the way up: on a 390 px phone one long word in a work's blurb widened the
     row, the list, the main column, the page grid and finally the header —
     measured at 465 px of layout inside a 390 px window. `minmax(0, 1fr)` is
     what lets the column be as narrow as the screen. */
  grid-template-columns: minmax(0, 1fr);
  background: linear-gradient(to bottom, #e5e5e5, #f2f2f2) fixed;
  color: var(--pg-fg);
  font-family: var(--pg-font-body);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

/* ── Header ─────────────────────────────────────────────────────────────── */

.pg-head {
  display: grid;
  /* Marke · Titel · Sprache · Schritte · Schließen. Die Sprache steht neben
     der Schrittanzeige, weil sie zum Dokument gehört und nicht zur Marke. */
  /* Marke · Titel · Schritte · Sprache · Diskette · Schließen. */
  grid-template-columns: auto 1fr auto auto auto auto;
  align-items: end;
  column-gap: clamp(0.9rem, 3vw, 2rem);
  min-width: 0;
  padding: max(1.4rem, env(safe-area-inset-top)) var(--pg-pad) 1.1rem;
  border-bottom: 1px solid var(--pg-hair);
}

/* The landing page's wordmark: outlined, stacked, lower case. */
.pg-brand {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  line-height: 0.84;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  color: transparent;
  -webkit-text-stroke: 0.5pt var(--pg-dark);
  transition: opacity 150ms ease;
}
.pg-brand:hover { opacity: 0.6; }
@supports not ((-webkit-text-stroke: 1px #000) or (text-stroke: 1px #000)) {
  .pg-brand { color: var(--pg-dark); }
}

.pg-head__title {
  margin: 0 0 0.1em;
  font-family: var(--pg-font-title);
  font-weight: 400;
  font-size: clamp(0.8rem, 1.5vw, 1rem);
  letter-spacing: 0.16em;
  text-transform: lowercase;
  color: var(--pg-muted);
  align-self: end;
}

/* The four steps, as a line rather than a widget. */
.pg-progress { min-width: 0; }
.pg-progress ol {
  display: flex;
  align-items: baseline;
  gap: clamp(0.7rem, 2vw, 1.6rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
.pg-progress li {
  display: flex;
  align-items: baseline;
  gap: 0.45em;
  font-family: var(--pg-font-title);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--pg-faint);
  transition: color 200ms ease;
}
.pg-progress__n {
  font-variant-numeric: tabular-nums;
  font-size: 0.7rem;
  opacity: 0.7;
}
.pg-progress li.is-current { color: var(--pg-fg); }
.pg-progress li.is-done    { color: var(--pg-muted); }
.pg-progress li.is-done .pg-progress__n::after { content: ""; }

/* ── Der Sprachschalter ───────────────────────────────────────────────────
   Drei Kürzel im Kopf, klein und leise: er gehört zum Dokument, nicht zur
   Bedienung, und soll die Schrittanzeige daneben nicht überstimmen. */
.pg-lang {
  display: flex;
  align-items: center;
  gap: 0.1rem;
  align-self: end;
}
.pg-lang__opt {
  border: 0;
  background: none;
  padding: 0.15rem 0.3rem;
  font-family: var(--pg-font-title);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--pg-faint);
  cursor: pointer;
  border-radius: 2px;
  transition: color 160ms ease, background 160ms ease;
}
.pg-lang__opt:hover { color: var(--pg-fg); }
.pg-lang__opt.is-on { color: var(--pg-fg); background: rgba(23, 25, 25, 0.07); }
.pg-lang__opt:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 2px; }
/* Während geholt wird, ist der Schalter stumm — ein zweiter Klick mitten im
   Tausch brächte zwei Sprachen durcheinander. */
.pg-langbusy .pg-lang { opacity: 0.5; pointer-events: none; }

.pg-leave {
  display: grid;
  place-items: center;
  width: 2.2rem; height: 2.2rem;
  margin-bottom: -0.2rem;
  border-radius: 50%;
  color: var(--pg-muted);
  transition: color 150ms ease, background 150ms ease;
}
.pg-leave svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.3; }
.pg-leave:hover { color: var(--pg-fg); background: rgba(23, 25, 25, 0.06); }

/* ── Die Suche ────────────────────────────────────────────────────────────
   Eine eigene Zeile unter allem anderen, über die volle Breite des Kopfes.
   Kein Kasten mit Rahmen: eine Linie unter der Zeile genügt, denn der Kopf
   hat schon einen Rahmen nach unten, und zwei Rechtecke ineinander sind eine
   Fassung zu viel für ein Feld, das nur mitliest. */
.pg-search {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--pg-hair);
  transition: border-color 160ms ease;
}
.pg-search:focus-within { border-color: var(--pg-line); }
.pg-search__icon {
  width: 0.85rem; height: 0.85rem;
  stroke: var(--pg-faint); stroke-width: 1.4; fill: none;
}
.pg-search:focus-within .pg-search__icon { stroke: var(--pg-fg); }

.pg-search__input {
  min-width: 0;
  border: 0;
  background: none;
  padding: 0.15rem 0;
  font-family: var(--pg-font-title);
  font-size: 0.86rem;
  color: var(--pg-fg);
  /* Ohne das setzt Safari eine eigene Schrift und eine eigene Höhe ins Feld
     und macht aus der Zeile eine Stufe. */
  -webkit-appearance: none;
  appearance: none;
}
.pg-search__input::placeholder { color: var(--pg-faint); }
.pg-search__input:focus { outline: none; }
/* Die eigene Löschtaste steht schon daneben — Chromes zweite wäre eine zu viel. */
.pg-search__input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.pg-search__clear {
  display: grid; place-items: center;
  width: 1.3rem; height: 1.3rem;
  border: 0; border-radius: 999px;
  background: none;
  color: var(--pg-faint);
  cursor: pointer;
}
.pg-search__clear svg { width: 0.62rem; height: 0.62rem; stroke: currentColor; stroke-width: 1.5; }
.pg-search__clear:hover { color: var(--pg-fg); background: rgba(23, 25, 25, 0.06); }

.pg-search__count {
  font-family: var(--pg-font-title);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  color: var(--pg-faint);
  white-space: nowrap;
}
.pg-search__count.is-empty { color: var(--pg-fg); }

/* Gefiltert: die ausgeschiedenen Zeilen sind fort — nicht blass, sondern weg.
   Eine Liste, die beim Tippen nur die Farbe wechselt, ist kein Filter. */
.pg-row.is-filtered-out { display: none; }
/* Und der Griff verschwindet, weil in dieser Sicht nicht gezogen wird
   (Begründung in portfolio-generator.js am `pointerdown`). Er behält seinen
   Platz im Raster, damit die Karten nicht seitlich springen, sobald man
   das erste Zeichen tippt. */
.pg-list.is-filtered .pg-grip { visibility: hidden; }

.pg-noscript {
  margin: 0;
  padding: 1rem var(--pg-pad);
  background: rgba(23, 25, 25, 0.06);
  font-size: 0.95rem;
}

/* ── The scrolling middle ───────────────────────────────────────────────── */

.pg-main {
  overflow-y: auto;
  overflow-x: hidden;
  min-width: 0;
  scrollbar-width: thin;
  /* Kein Scroll-Anchoring. Der Browser sucht sich sonst eine Karte am oberen
     Rand als Anker und hält SIE fest — und das ist ausgerechnet die, auf deren
     Zählknopf man gerade geklickt hat. Er folgt ihr dann nach oben und nimmt
     die ganze Liste mit: gemessen sprang alles Sichtbare um genau eine
     Zeilenhöhe (185 px), also um das, was stehen bleiben sollte. Ohne Anker
     ändert sich `scrollTop` nicht, und weil eine nach OBEN einsortierte Karte
     nur Zeilen über dem Ausschnitt verschiebt, steht darunter alles still. */
  overflow-anchor: none;
  padding: clamp(1.4rem, 5vh, 3.4rem) var(--pg-pad) 2rem;
}

.pg-step[hidden] { display: none; }
.pg-step {
  max-width: 78rem;
  margin: 0 auto;
  animation: pg-rise 320ms cubic-bezier(0.22, 0.7, 0.3, 1) both;
}
@keyframes pg-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.pg-q {
  margin: 0 0 clamp(1.4rem, 4vh, 2.6rem);
  font-family: var(--pg-font-title);
  font-weight: 400;
  font-size: clamp(1.25rem, 3vw, 1.85rem);
  line-height: 1.2;
  letter-spacing: -0.005em;
}

.pg-hint {
  margin: 1.2rem 0 0;
  font-size: 0.98rem;
  color: var(--pg-muted);
}

/* ── The choice cards (format, focus) ───────────────────────────────────── */

.pg-choices { display: grid; gap: clamp(0.8rem, 2vw, 1.4rem); }
.pg-choices--two  { grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr)); }
.pg-choices--four { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }

.pg-choice {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  text-align: left;
  padding: clamp(1rem, 2.4vw, 1.6rem);
  background: rgba(255, 255, 255, 0.42);
  border: 1px solid var(--pg-line);
  border-radius: 2px;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}
.pg-choice:hover { background: rgba(255, 255, 255, 0.75); border-color: rgba(23, 25, 25, 0.3); }
.pg-choice:active { transform: translateY(1px); }
.pg-choice.is-chosen {
  background: rgba(255, 255, 255, 0.9);
  border-color: var(--pg-dark);
}
.pg-choice:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 3px; }

.pg-choice__body { display: flex; flex-direction: column; gap: 0.45rem; }

.pg-choice__label {
  font-family: var(--pg-font-title);
  font-weight: 500;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  text-transform: lowercase;
  letter-spacing: 0.01em;
}
.pg-choice__badge {
  align-self: flex-start;
  font-family: var(--pg-font-title);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pg-muted);
  border: 1px solid var(--pg-line);
  border-radius: 999px;
  padding: 0.18em 0.7em;
}
.pg-choice__note {
  font-size: 1rem;
  line-height: 1.45;
  color: var(--pg-muted);
  max-width: 34em;
}
.pg-choice__count {
  font-family: var(--pg-font-title);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--pg-faint);
  text-transform: lowercase;
  margin-top: 0.2rem;
  min-height: 1em;
}
.pg-choice--focus { gap: 0.6rem; }

/* The little sheets that show what a format does. */
.pg-diagram { width: 100%; height: auto; display: block; }
.pg-diagram__sheet { fill: #f4f4f4; stroke: rgba(23, 25, 25, 0.18); stroke-width: 0.25; }
.pg-diagram__img   { fill: rgba(23, 25, 25, 0.30); }
.pg-diagram__bar   { fill: rgba(23, 25, 25, 0.78); }
.pg-diagram__ttl   { fill: none; stroke: rgba(23, 25, 25, 0.45); stroke-width: 0.3; }
.pg-diagram__txt   { fill: rgba(23, 25, 25, 0.16); }
.pg-diagram__barO  { fill: none; stroke: rgba(23, 25, 25, 0.78); stroke-width: 0.3; }
.pg-choice.is-chosen .pg-diagram__img { fill: rgba(23, 25, 25, 0.42); }

/* The always-available shortcut: the artist's own PDF. */
.pg-official {
  margin-top: clamp(1.8rem, 5vh, 3rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--pg-hair);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1.2rem;
}
.pg-official__head {
  margin: 0;
  font-family: var(--pg-font-title);
  font-size: 0.95rem;
  text-transform: lowercase;
  letter-spacing: 0.02em;
}
.pg-official__note { margin: 0; color: var(--pg-muted); flex: 1 1 14rem; }
.pg-official__link {
  font-family: var(--pg-font-title);
  font-size: 0.86rem;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--pg-fg);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}
.pg-official__link span { color: var(--pg-faint); }
.pg-official__link:hover { opacity: 0.6; }

/* ── The composer ───────────────────────────────────────────────────────── */

.pg-compose__head { margin-bottom: clamp(1rem, 3vh, 1.8rem); }
.pg-compose__head .pg-q { margin-bottom: 0.3rem; }
.pg-compose__head .pg-hint { margin-top: 0; }

.pg-list {
  --pg-tile: clamp(6.5rem, 11vw, 10.5rem);
  --pg-gap: 0.55rem;
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pg-gap);
  position: relative;
}

/* Every row is exactly as tall as its square panel plus its padding, and that
   is not a cosmetic decision: a drag that reorders a list of unequal rows has
   to solve for where each one would land, while a list of equal rows only has
   to count. The blurb is clamped to fit rather than the row grown to hold it. */
.pg-row {
  display: grid;
  /* Griff · laufende Nummer · Karte · Text · Zählknopf. Der Griff steht
     links, weil dort angefasst wird, und der Zählknopf rechts, weil dort
     entschieden wird — zwei Werkzeuge an zwei Rändern statt beide am selben. */
  grid-template-columns:
    1.3rem 2.2rem minmax(0, var(--pg-tile, 11rem)) minmax(0, 1fr) 2.9rem;
  align-items: stretch;
  height: calc(var(--pg-tile, 11rem) + 1.1rem);
  gap: clamp(0.8rem, 2vw, 1.6rem);
  padding: 0.55rem 0.6rem 0.55rem 0.35rem;
  border: 1px solid transparent;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0);
  cursor: pointer;
  transition: background 180ms ease, border-color 180ms ease, opacity 220ms ease;
  touch-action: pan-y;
}
.pg-row:hover { background: rgba(255, 255, 255, 0.45); border-color: var(--pg-hair); }
.pg-row:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 2px; }

/* Not greyed out — thinner. The picture keeps its colour, it just steps back. */
.pg-row.is-out { opacity: 0.34; }
.pg-row.is-out:hover { opacity: 0.55; }

.pg-row__index {
  align-self: center;
  justify-self: end;
  font-family: var(--pg-font-title);
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  color: var(--pg-faint);
}
.pg-row.is-in .pg-row__index { color: var(--pg-fg); }

/* The square panel: the picture, the title on it, the year under the title. */
.pg-tile {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--pg-tile-color, #d8d8d8);
  border-radius: 1px;
}
.pg-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pg-focus, 50% 50%);
  display: block;
}
.pg-tile::after {
  content: "";
  position: absolute;
  inset: 40% 0 0 0;
  background: linear-gradient(to bottom, rgba(12, 13, 13, 0), rgba(12, 13, 13, 0.62));
  pointer-events: none;
}
.pg-tile__text {
  position: absolute;
  left: 0.7rem;
  right: 0.7rem;
  bottom: 0.6rem;
  z-index: 1;
  color: #fff;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.pg-tile__title {
  font-family: var(--pg-font-title);
  font-weight: 500;
  font-size: clamp(0.85rem, 1.5vw, 1.02rem);
  line-height: 1.08;
  letter-spacing: 0.005em;
  text-transform: lowercase;
  text-wrap: balance;
}
.pg-tile__year {
  font-family: var(--pg-font-title);
  font-size: 0.64rem;
  letter-spacing: 0.2em;
  opacity: 0.85;
}
.pg-tile__empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: rgba(23, 25, 25, 0.35);
  font-family: var(--pg-font-title);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: lowercase;
}

/* The tick. A box, because that is what it is. */
.pg-tick {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  width: 1.35rem;
  height: 1.35rem;
  display: grid;
  place-items: center;
  border: 1.2px solid rgba(255, 255, 255, 0.85);
  border-radius: 2px;
  background: rgba(12, 13, 13, 0.28);
  backdrop-filter: blur(2px);
  transition: background 160ms ease, border-color 160ms ease;
}
.pg-tick svg { width: 0.85rem; height: 0.85rem; fill: none; stroke: #fff; stroke-width: 2; opacity: 0; transition: opacity 160ms ease; }
.pg-row.is-in .pg-tick { background: rgba(255, 255, 255, 0.92); border-color: #fff; }
.pg-row.is-in .pg-tick svg { stroke: var(--pg-dark); opacity: 1; }

.pg-row__body {
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
  padding-right: 0.5rem;
}
.pg-row__blurb {
  margin: 0;
  font-size: clamp(0.98rem, 1.5vw, 1.1rem);
  line-height: 1.42;
  color: var(--pg-fg);
  max-width: 44em;
  min-width: 0;
  /* A German compound long enough to be a line of its own would otherwise
     widen the row rather than break. */
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}
.pg-row__meta {
  margin: 0;
  font-family: var(--pg-font-title);
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: lowercase;
  color: var(--pg-faint);
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.75rem;
}

.pg-grip {
  align-self: center;
  justify-self: center;
  width: 1.6rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  color: var(--pg-faint);
  cursor: grab;
  touch-action: none;
}
.pg-grip:hover { color: var(--pg-fg); }
.pg-grip svg { width: 0.85rem; height: 1.2rem; fill: currentColor; }

/* ── Der Zählknopf ────────────────────────────────────────────────────────
   Zeigt die Zahl, die als Nächstes vergeben wird, und nach dem Klick
   dauerhaft die eigene. Er erscheint erst, wenn der Zeiger auf der Karte
   liegt — solange man liest, soll die Liste ruhig sein.

   Deshalb `@media (hover: hover)` und nicht einfach `.pg-row:hover`: auf
   einem Telefon gibt es keinen ruhenden Zeiger, dort wäre der Knopf nie zu
   sehen — und gerade dort ist er nützlicher als das Ziehen. Also ist
   „immer sichtbar" der Grundfall und das Verstecken die Ausnahme. */
.pg-pick {
  align-self: center;
  justify-self: center;
  display: inline-flex;
  align-items: center;
  gap: 0.18rem;
  min-width: 2.6rem;
  height: 1.65rem;
  padding: 0 0.4rem;
  border: 1px solid var(--pg-line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  color: var(--pg-fg);
  font-family: var(--pg-font-title);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  cursor: pointer;
  transition: opacity 160ms ease, background 160ms ease,
              border-color 160ms ease, color 160ms ease;
}
.pg-pick__arrow { width: 0.62rem; height: 0.62rem; stroke: currentColor; stroke-width: 1.6; }
.pg-pick__n { display: inline-block; min-width: 0.62rem; text-align: center; }
.pg-pick:hover:not(:disabled) { background: var(--pg-dark); border-color: var(--pg-dark); color: #fff; }
.pg-pick:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 2px; }

/* Gesetzt: kein Pfeil mehr, weil es nichts mehr zu tun gibt — nur noch die
   Zahl, und die bleibt stehen. */
.pg-pick.is-placed {
  cursor: default;
  background: var(--pg-dark);
  border-color: var(--pg-dark);
  color: #fff;
  min-width: 1.65rem;
  padding: 0;
  justify-content: center;
}
.pg-pick.is-placed .pg-pick__arrow { display: none; }

@media (hover: hover) {
  .pg-pick { opacity: 0; }
  .pg-row:hover .pg-pick,
  .pg-row:focus-within .pg-pick,
  .pg-row.is-picked .pg-pick { opacity: 1; }
}

/* Dragging: the row lifts out, the gap follows it. */
.pg-row.is-dragging {
  position: relative;
  z-index: 5;
  cursor: grabbing;
  background: rgba(255, 255, 255, 0.94);
  border-color: var(--pg-line);
  box-shadow: 0 10px 30px rgba(23, 25, 25, 0.14);
  opacity: 1 !important;
}
.pg-list.is-sorting .pg-row:not(.is-dragging) { transition: transform 220ms cubic-bezier(0.22, 0.7, 0.3, 1); }
.pg-list.is-sorting { cursor: grabbing; }

/* ── Das Zwischenfach ─────────────────────────────────────────────────────
   Ein Klappmenü in der Fußleiste. Es öffnet nach OBEN, weil es unten steht —
   nach unten läge es außerhalb des Fensters. */
/* ── `[hidden]` heißt weg. Auch hier. ────────────────────────────────────
   Die Browserregel dafür ist `[hidden] { display: none }` — und die steht im
   UA-Stylesheet, also VERLIERT sie gegen jedes `display` aus dieser Datei.
   Wer einem Element hier `display: grid` gibt, schaltet damit stillschweigend
   sein `hidden` ab; im JavaScript steht dann `el.hidden = true`, die Eigenschaft
   meldet brav `true`, und das Ding steht trotzdem auf dem Schirm.

   Gemessen betraf das drei Dinge auf einmal: dieses Menü, die ganze SUCHZEILE
   (in Schritt 1, 2 und im Dokument sichtbar, obwohl sie nur in die Auswahl
   gehört) und ihre Löschtaste, die deshalb auch bei leerem Feld dastand — dazu
   `#pg-link-pdf`, das es schon länger gab. Und es ist nicht zu sehen, wenn man
   den Zustand im JS abfragt: `n.hidden` sagt die Wahrheit über das Attribut und
   nichts über das Bild.

   `!important` ist hier nicht die Faust, sondern die einzige Sprache, die die
   UA-Regel wiederherstellt: es soll nie ein Element geben, das `hidden` ist und
   trotzdem gezeigt werden will. */
.pg [hidden] { display: none !important; }

.pg-slot { position: relative; display: inline-flex; align-self: end; }
/* Die Diskette. Gleiche Größe und gleiche Ruhe wie das Kreuz daneben — sie
   sind Nachbarn und sollen nicht gegeneinander anschreien. */
.pg-slot__toggle {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 0;
  border-radius: 2px;
  background: none;
  color: var(--pg-faint);
  cursor: pointer;
  transition: color 160ms ease, background 160ms ease;
}
.pg-slot__toggle svg { width: 1rem; height: 1rem; fill: currentColor; }
/* Der Schieber ist das Loch in der Diskette: er trägt die Farbe des Grundes,
   nicht seine eigene. `--pg-light` und nicht ein erfundenes `--pg-bg` — den
   Grundton gibt es hier schon, und ein zweiter Name für dieselbe Farbe ist
   eine Farbe, die irgendwann auseinanderläuft. */
.pg-slot__shutter { fill: var(--pg-light); }
.pg-slot__toggle:hover,
.pg-slot__toggle[aria-expanded="true"] { color: var(--pg-fg); background: rgba(23, 25, 25, 0.06); }
.pg-slot__toggle:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 2px; }

.pg-slot__menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  left: auto;
  z-index: 40;
  display: grid;
  min-width: 15rem;
  padding: 0.3rem;
  background: linear-gradient(to bottom, #f6f6f6, #ececec);
  border: 1px solid var(--pg-line);
  border-radius: 3px;
  box-shadow: 0 12px 34px rgba(23, 25, 25, 0.18);
}
.pg-slot__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 0.42rem 0.55rem;
  border: 0;
  border-radius: 2px;
  background: none;
  font-family: var(--pg-font-title);
  font-size: 0.76rem;
  color: var(--pg-fg);
  text-align: left;
  cursor: pointer;
}
.pg-slot__item:hover:not(:disabled) { background: rgba(23, 25, 25, 0.07); }
.pg-slot__item:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: -2px; }
/* Leeres Fach: „laden" und „löschen" sind da, aber stumm — ein Menüpunkt, der
   verschwindet, lässt den Benutzer suchen, wo er eben noch war. */
.pg-slot__item:disabled { color: var(--pg-faint); cursor: default; }
.pg-slot__hint {
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  color: var(--pg-faint);
  white-space: nowrap;
}

/* ── The bar ────────────────────────────────────────────────────────────── */

.pg-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem var(--pg-pad) max(0.9rem, env(safe-area-inset-bottom));
  border-top: 1px solid var(--pg-hair);
  background: rgba(242, 242, 242, 0.86);
  backdrop-filter: blur(8px);
}
/* Impressum + Datenschutz, die vierte Rasterzeile unter der Leiste.
   Leiser als alles darüber und trotzdem lesbar: die Pflicht ist „leicht
   erkennbar", nicht „vorhanden". Siehe den Kommentar im View. */
.pg > .lz-legal-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  padding: 0.5rem var(--pg-pad) max(0.55rem, env(safe-area-inset-bottom));
  border-top: 1px solid var(--pg-hair);
  background: rgba(242, 242, 242, 0.86);
  font-family: var(--pg-font-title);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  text-transform: lowercase;
}
.pg > .lz-legal-links a { color: var(--pg-muted, #6b6b66); text-decoration: none; }
.pg > .lz-legal-links a:hover,
.pg > .lz-legal-links a:focus-visible { color: var(--pg-fg); text-decoration: underline; }

.pg-bar__left  { justify-self: start; }
.pg-bar__mid   { justify-self: center; text-align: center; display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 0.35rem 0.9rem; }
.pg-bar__right { justify-self: end; }

.pg-count {
  font-family: var(--pg-font-title);
  font-size: 0.82rem;
  letter-spacing: 0.05em;
  text-transform: lowercase;
  color: var(--pg-muted);
  font-variant-numeric: tabular-nums;
}
.pg-count.is-warning { color: var(--pg-fg); }
.pg-bulk { display: flex; align-items: baseline; gap: 0.5rem; }
.pg-bulk__sep { color: var(--pg-faint); }

.pg-btn {
  font-family: var(--pg-font-title);
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  text-transform: lowercase;
  padding: 0.62em 1.5em;
  border: 1px solid var(--pg-dark);
  border-radius: 999px;
  background: var(--pg-dark);
  color: #f2f2f2;
  cursor: pointer;
  transition: opacity 150ms ease, background 150ms ease, color 150ms ease;
}
.pg-btn:hover { opacity: 0.8; }
.pg-btn:disabled { opacity: 0.3; cursor: default; }
.pg-btn--ghost { background: transparent; color: var(--pg-fg); border-color: var(--pg-line); }
.pg-btn--ghost:hover { border-color: var(--pg-dark); opacity: 1; }
.pg-btn[hidden] { display: none; }
.pg-btn:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 3px; }

.pg-link {
  font-family: var(--pg-font-title);
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: lowercase;
  background: none;
  border: 0;
  padding: 0;
  color: var(--pg-muted);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--pg-line);
}
.pg-link:hover { color: var(--pg-fg); text-decoration-color: currentColor; }
.pg-link:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 2px; }
.pg-bulk[hidden] { display: none; }

/* ── Narrow screens ─────────────────────────────────────────────────────── */

@media (max-width: 860px) {
  .pg-head {
    grid-template-columns: auto 1fr auto;
    row-gap: 0.7rem;
  }
  .pg-progress { grid-column: 1 / -1; order: 3; }
  .pg-progress ol { justify-content: space-between; }
  .pg-progress__l { display: none; }
  .pg-progress li.is-current .pg-progress__l { display: inline; }

  /* Auf dem Telefon wandert die Schrittanzeige selbst in eine eigene Zeile
     (`order: 3`). Ohne eine eigene Ordnungszahl stünde die Suche davor — sie
     soll aber unter allem stehen, hier wie auf dem Schreibtisch. */
  .pg-search { margin-top: 0.7rem; order: 4; }
  .pg-row {
    /* Der Griff ist hier ausgeblendet (siehe unten) und belegt deshalb auch
       keine Spalte — es bleiben Nummer, Karte, Text und der Zählknopf. */
    grid-template-columns: 1.8rem minmax(0, 7.5rem) minmax(0, 1fr) 2.6rem;
    gap: 0.8rem;
    padding-left: 0;
  }
  /* The bar's three groups do not fit on one phone line: „vorschlag
     zurücksetzen" alone is wider than a third of the screen. */
  .pg-bar {
    grid-template-columns: auto auto;
    grid-template-areas: "count count" "back next";
    row-gap: 0.7rem;
  }
  .pg-bar__left  { grid-area: back; }
  .pg-bar__right { grid-area: next; }
  .pg-bar__mid   { grid-area: count; justify-self: center;
                   display: flex; flex-wrap: wrap; justify-content: center;
                   align-items: baseline; gap: 0.3rem 0.8rem; }
  /* Auf dem Telefon bleibt das Menü am rechten Rand hängen, statt über ihn
     hinauszulaufen — der Knopf steht dort ohnehin ganz außen. */
  .pg-slot__menu { right: 0; left: auto; min-width: 12rem; }
  .pg-grip { display: none; }
  .pg-row__meta { font-size: 0.64rem; }
}

@media (max-width: 520px) {
  .pg-head__title { display: none; }
  .pg-row__blurb { font-size: 0.95rem; -webkit-line-clamp: 4; }
  .pg-row__meta { font-size: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .pg-step { animation: none; }
  .pg-list.is-sorting .pg-row:not(.is-dragging) { transition: none; }
  .pg-choice, .pg-row, .pg-btn { transition: none; }
}

/* ==========================================================================
   THE DOCUMENT — `pd-`
   --------------------------------------------------------------------------
   One A4 landscape sheet, 297 × 210 mm, drawn once and shown twice: on screen
   scaled down inside `.pd-sheet`, in print at 1:1 on the paper. Everything
   inside is in millimetres, so the two cannot drift apart.

   The numbers are not invented and they are not estimates either. The
   hand-made portfolio (content/3_info/lukaszerbst_portfolio-2026_en.pdf) is
   A4 landscape, 841.89 × 595.276 pt, and its content streams are plain once
   inflated — so these are the literal operands out of the file, confirmed
   against the rendered pixels:

     margin             36 pt on all four sides   → 12.7 mm
     dark bar           y 221.10, height 23.81    → 78.0 mm, 8.4 mm
     dark bar, right    x 691.89                  → 52.9 mm from the right
     title / video      28.2 pt, right at 805.89  → 12.7 mm from the right
     title              STROKE ONLY, 0.15 pt, in the ink — not a grey fill
     title baseline     y 270.03                  → 95.3 mm from the top
     body               8 pt on 13, tracking 0.107 em
     venue / year       10 pt on 15, tracking 0.2 em, right at 805.89
     caption            6 pt on 6.675
     text grid          4 columns of 178.29 pt, gutter 14.18, first x 50.17
     ink                #282d2e
     ground             #f2f2f2 (top) → #e5e5e5 (bottom)

   Two of these were wrong when guessed off the render and both matter: the
   title is a HAIRLINE STROKE IN THE INK COLOUR and only reads as light grey
   because it is 0.15 pt wide — set as a grey fill it goes muddy; and the
   venue/year line is 10 pt, not the 6 it looks like, carried by 0.2 em of
   tracking.
   ========================================================================== */

.pg-doc {
  position: fixed;
  inset: 0;
  z-index: 40;
  overflow-y: auto;
  background: #dcdcdc;
}
.pg-doc[hidden] { display: none; }
body.pg-printing { overflow: hidden; }

.pg-doc__bar {
  position: sticky;
  top: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem var(--pg-pad);
  background: rgba(236, 236, 236, 0.94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--pg-hair);
}
.pg-doc__note {
  margin: 0;
  text-align: center;
  font-size: 0.88rem;
  color: var(--pg-muted);
}

.pg-doc__pages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.8rem, 2vw, 1.6rem);
  padding: clamp(1rem, 3vw, 2.4rem) 1rem 4rem;
}

/* The screen wrapper: reserves the scaled size, the sheet inside is 1:1. */
.pd-sheet {
  --pd-scale: 1;
  width: calc(297mm * var(--pd-scale));
  height: calc(210mm * var(--pd-scale));
  flex: none;
  box-shadow: 0 6px 26px rgba(23, 25, 25, 0.16);
}
.pd-sheet > .pd-page {
  transform: scale(var(--pd-scale));
  transform-origin: top left;
}

.pd-page {
  --pd-margin: 12.7mm;            /* 36 pt */
  --pd-title-right: 12.7mm;       /* right edge 805.89 pt */
  --pd-ink: #282d2e;

  /* ── Die Brotschrift des Dokuments ─────────────────────────────────────
     Eine Zeile, und sie ist eine Entscheidung, keine Kleinigkeit.

     Das handgesetzte Portfolio ist in **Rooney Sans** gesetzt. Die hat diese
     Website nicht: `main.css` nennt sie zwar (`'RooneySans', 'Forum', serif`),
     aber es gibt nirgends ein `@font-face` dafür — sie steht nur auf dem
     Rechner, auf dem sie installiert ist, und jeder Besucher der Seite sieht
     seit jeher Forum. Von den vier Schriften, die die Seite wirklich lädt,
     gemessen an Rooneys eigenen Metriken (Alphabetbreite / x-Höhe):

       Rooney Sans   12,996 em / 0,497     ← das Original
       Roboto        12,968 em / 0,528     −0,2 %  praktisch deckungsgleich
       Forum         11,786 em / 0,420     −9,3 %  und 15 % kleinere x-Höhe
       Yrsa          11,628 em / 0,416     −10,5 %

     **Forum ist die Voreinstellung**, weil es die Schrift ist, in der die
     Website ihre Texte setzt, und dieses Portfolio soll aussehen wie die
     Seite, aus der es entsteht. Der Preis steht daneben: bei 6 pt
     Bildunterschrift sind 0,420 x-Höhe 2,52 pt, und das ist auf Papier
     grenzwertig.

     Wer die Proportionen des alten Portfolios genauer will als seine Stimme,
     setzt hier Roboto ein — dann trägt der ganze Maßstab oben (8/13, 6/6,675,
     10/15) unverändert, weil er für eine Schrift dieser Breite gemacht wurde.
     Roboto lädt die Seite ohnehin schon.

     Und wer Rooney will: eine lizenzierte Webschrift nach `assets/fonts/`
     legen und hier eintragen. `font-src 'self'` erlaubt das bereits, und das
     Muster steht in hoeren-sagen-wissen.php (National Park). */
  --pd-font-body: var(--pg-font-body);
  /* --pd-font-body: "Roboto", system-ui, sans-serif;   ← metrisch wie das Original */

  position: relative;
  width: 297mm;
  height: 210mm;
  overflow: hidden;
  background: linear-gradient(to bottom, #f2f2f2, #e5e5e5);
  color: var(--pd-ink);
  font-family: var(--pd-font-body);
  /* Without this the ground, the dark bar and every full-bleed photograph
     come out of the printer as white paper: browsers drop backgrounds by
     default and only this property asks for them back. */
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

/* ── The furniture every page shares ────────────────────────────────────── */

.pd-folio {
  position: absolute;
  left: var(--pd-margin);
  /* Baseline 55.50 pt from the top on every one of the 66 pages, which puts
     the figures' cap line flush with the 36 pt margin. The value here is where
     the BOX goes, not the baseline, so it was set by rendering and measuring
     against the original rather than by arithmetic on the font's metrics. */
  top: 11.1mm;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: 28.2pt;
  line-height: 1;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* ── The bar ─────────────────────────────────────────────────────────────
   Not furniture: the one element that lives through the document. Its
   geometry is written inline per segment by the reducer in the JS (see the
   THE BAR header there for the five rules); this file only knows its three
   states of matter. Born as an outline, it solidifies to ink, photographs
   cut it, and on the last dark page it resolves in paper white. Flipping
   through the pages full-screen plays that life back as a stop-motion film —
   which is why its vertical position never moves within a document. */
.pd-bar {
  position: absolute;
  background: var(--pd-ink);
}
.pd-bar--stroked {
  background: transparent;
  /* The bar's outline is the TITLE's outline — the same 0.15 pt, nothing
     heavier: one contour weight on the whole sheet. `box-sizing:
     border-box` is set globally, so the stroke lies INSIDE the shape and
     the outlined bar occupies exactly the rectangle the state names. */
  border: 0.15pt solid var(--pd-ink);
}
.pd-bar--paper { background: #f2f2f2; border: 0; }
/* An outlined bar on a full-page picture — the flip's canvas. Doubled class
   because the z-order block below sets .pd-bar under the photographs; on the
   picture it must lie on top. Same 0.15 pt as everywhere; on a dark picture
   the stroke turns paper, the switch everything makes on dark ground here. */
.pd-bar.pd-bar--over { z-index: 2; }
/* Rule 9: an outlined piece licensed to overlap a photograph rises above
   it — drawn under, the overlap would just look trimmed. */
.pd-bar.pd-bar--onimg { z-index: 2; }
.pd-bar--overpaper { border-color: #f2f2f2; }

/* The work's name: Montserrat Alternates, outline only, right aligned, sitting
   under the bar's line. `-webkit-text-stroke` is the same mechanism the site
   menu's wordmark uses; the @supports fallback matters more here than on
   screen, because a filled title where an outlined one was meant would be the
   loudest thing on the page. */
.pd-title {
  position: absolute;
  right: var(--pd-title-right);
  /* First baseline 270.03 pt = 95.26 mm from the top, on 20 of 24 title
     instances of the original. The value here is the BOX top: measured on
     the render, 87.6 puts the baseline at 95.3 — and, just as material, the
     lowercase ascenders at 87.8, clear of the band that ends at 86.4. At
     85.2 the ascender tips stood 0.9 mm deep in the solid band. */
  top: 87.6mm;
  margin: 0;
  max-width: calc(297mm - var(--pd-title-right) - 30mm);
  text-align: right;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: 28.2pt;
  line-height: 0.851;             /* 24 pt of leading on 28.2 */
  letter-spacing: 0;
  text-transform: lowercase;
  color: transparent;
  -webkit-text-stroke: 0.15pt var(--pd-ink);
}
/* Without the fallback a browser that cannot stroke text prints nothing where
   the work's name should be. It falls back to a light grey fill rather than
   the ink, because a 28 pt name in solid black would be the loudest thing that
   has ever stood on one of these pages. */
@supports not ((-webkit-text-stroke: 1px #000) or (text-stroke: 1px #000)) {
  .pd-title { color: #c9caca; }
}
.pd-title span { display: block; }

/* Where it happened, and when. Bottom right, letter-spaced, lower case. */
.pd-venue,
.pd-year {
  position: absolute;
  right: var(--pd-title-right);
  margin: 0;
  text-align: right;
  white-space: pre-line;          /* the comma-split venue stacks its lines */
  font-family: var(--pd-font-body);
  font-weight: 400;
  font-size: 10pt;                /* looks like 6 — that is the tracking */
  line-height: 1.5;               /* 15 pt on 10 */
  letter-spacing: 0.2em;
  text-transform: lowercase;
}
/* Held to the identity column, 178.29 pt. Without it „Niedersächsische
   Landesvertretung in Berlin" sets as one 294 pt line — it has no comma to
   break on, so the comma-splitting above never touches it — and reaches a
   third of the way across the sheet where the original wraps to three lines. */
.pd-venue { bottom: 25.7mm; max-width: 62.9mm; }
.pd-year  { bottom: 11.2mm; }     /* baseline 559.28 pt = 36 pt off the foot */
/* The letter-spacing hangs off the last glyph and pushes the line left of the
   margin it is supposed to sit on; this pulls it back. */
.pd-venue, .pd-year { margin-right: -0.2em; }

/* The compact sheet keeps venue and year at the same baselines but stands
   them under the image, on the folio's own left axis — a museum label. */
.pd-venue--left, .pd-year--left {
  right: auto;
  left: var(--pd-margin);
  text-align: left;
  margin-right: 0;
  white-space: pre-line;
}

/* Auf dem kompakten Bogen steht es links unter den Bildern und über der
   Ortsangabe — und in 18 pt, der Größe des kompakten Titels, nicht in den
   28,2 pt des losen. Dort ist das Wort so groß wie der Titel daneben und
   gehört damit zu ihm; hier wäre es größer als er. Gemessene Nachbarn:
   zweites Bild bis 77 mm über dem Fuß, Ortsangabe ab 36,3 mm. */
.pd-page--compact .pd-media {
  right: auto;
  left: var(--pd-margin);
  bottom: 40mm;
  font-size: 18pt;
}

.pd-media {
  position: absolute;
  right: var(--pd-title-right);
  bottom: 12mm;
  margin: 0;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: 28.2pt;
  letter-spacing: 0;
  text-transform: lowercase;
}

/* A caption belongs to a photograph and is set small, flush right, three lines
   at most: the work, the place, who took it. */
.pd-caption {
  position: absolute;
  margin: 0;
  font-family: var(--pd-font-body);
  font-weight: 400;
  font-size: 6pt;
  line-height: 1.11;              /* 6.675 pt on 6 — the lines nearly touch */
  letter-spacing: 0.11em;
  text-align: right;
  white-space: pre-line;
}

/* ── Pictures ───────────────────────────────────────────────────────────── */

/* Every frame is an exact rectangle computed in the plan from the image's
   own aspect ratio — which is why there are no frame classes here: a frame
   that already has the picture's proportions crops nothing even though the
   CSS below says `cover`, and the frames that DO crop (the edge bleeds, a
   diptych partner) crop under the Panel's focus point. The z-order is the
   page's one law of physics: ground, then the bar, then photographs, then
   type — so a photograph covers the bar (that is how it cuts it) and the
   page number is never lost under a picture. */
.pd-figure { position: absolute; margin: 0; overflow: hidden; z-index: 1; }
.pd-bar { z-index: 0; }
.pd-folio, .pd-title, .pd-venue, .pd-year,
.pd-caption, .pd-media, .pd-columns { z-index: 2; }
.pd-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pd-focus, 50% 50%);
  display: block;
}

/* ── Text ───────────────────────────────────────────────────────────────── */

/* The text block sits on the master grid — first column at 50.17 pt, column
   width 178.29, gutter 14.18 — and holds the WHOLE text of a work on one
   sheet: the engine widens it from one column to at most three (the fourth
   is the identity column and never carries body text), and only a text that
   overflows even three, which no work in the content does, runs on. Left
   position, width and column count are written inline by the engine. */
.pd-columns {
  position: absolute;
  top: 51.8mm;                    /* 146.79 pt */
  height: 145.5mm;                /* down to 559.276 pt */
  /* SPALTE FÜR SPALTE, nicht ausgewogen. Der Vorgabewert `balance` verteilt
     den Satz gleichmäßig auf alle Spalten — bei einem kurzen Text auf dem
     kompakten Bogen, dessen Spaltenzahl fest bei drei liegt, ergibt das drei
     angefangene Stummel nebeneinander und darunter zwei Drittel Leere. Man
     liest aber nicht drei Anfänge, man liest einen Text: erste Spalte voll,
     dann die zweite, dann die dritte. */
  column-fill: auto;
  column-gap: 5mm;                /* 14.18 pt */
  font-size: 8pt;
  line-height: 1.625;             /* 13 pt on 8 */
  letter-spacing: 0.107em;
  text-align: left;
  hyphens: auto;
  /* German compounds break badly without a floor — Chrome will otherwise set
     „Informati-onsaustauschs". Six characters before a break, three on each
     side of it. */
  -webkit-hyphenate-limit-before: 4;
  -webkit-hyphenate-limit-after: 4;
  hyphenate-limit-chars: 7 4 4;
  orphans: 2;
  widows: 2;
}
/* A paragraph may continue across a column — with whole texts on one sheet,
   forbidding the break costs a third of the capacity in stranded lines. */
.pd-columns p { margin: 0 0 2.5mm; }   /* +7.09 pt */
.pd-columns p:last-child { margin-bottom: 0; }
/* Die Marken des Autors sind ein gewöhnlicher Absatzwechsel — nicht mehr.
   Sie waren einmal ein Seitenumbruch, dann ein tieferer Atemzug (4,6 mm
   zusätzlich); beides sagt mehr, als der Autor damit gemeint hat. Im Text
   steht an dieser Stelle nichts weiter als „hier fängt etwas Neues an", und
   genau das sagt ein Absatz schon. Die Klasse bleibt, weil der Satzspiegel
   sie kennt und der Umbruchschutz weiter an ihr hängt. */
.pd-columns .pd-sec { margin-top: 0; }

/* The compact title: the same outline hairline, held to 18 pt so that no
   title in the content needs more than two lines above the text block. Its
   width is capped clear of the image panel (inline). The display-title's
   hand-set line breaks belong to the tape and the loose format; compact
   wraps naturally — one strict template, sixteen times. */
.pd-title--compact {
  top: 20.4mm;                    /* first baseline 76 pt */
  font-size: 18pt;
}

/* ── Cover and colophon ─────────────────────────────────────────────────── */

/* The wordmark on the cover sits at the title's own baseline — under the
   newborn bar, exactly where the hand-made cover puts it. */

.pd-page--end {
  background: #171919;
  color: #e6e6e6;
  --pd-ink: #e6e6e6;
}
.pd-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  text-align: center;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: 28.2pt;
  line-height: 0.862;             /* 24.31 pt of leading on 28.2 */
  letter-spacing: 0;
  text-transform: lowercase;
}
.pd-colophon {
  position: absolute;
  right: var(--pd-title-right);
  bottom: 12.4mm;
  margin: 0;
  text-align: right;
  font-family: var(--pd-font-body);
  font-size: 8pt;
  line-height: 1.375;             /* 11 pt on 8 */
  letter-spacing: 0.107em;
    white-space: pre-line;
}

/* ── Print ──────────────────────────────────────────────────────────────── */

@page {
  /* Named explicitly rather than as `A4 landscape`: the two are the same box,
     but a browser that does not recognise the keyword pair silently keeps
     portrait, and then every page is cropped down its middle. */
  size: 297mm 210mm;
  margin: 0;
}

/* Every rule here is scoped to `body.pg-printing`, which is set exactly while
   the document is on screen. Unscoped, a ⌘P pressed back on the composer would
   hide the whole tool and print one blank sheet — the browser's print command
   belongs to the browser, and it must not be able to produce nothing. */
@media print {
  body.pg-printing { background: #fff; height: auto; overflow: visible; }
  body.pg-printing .pg { display: block; height: auto; overflow: visible; }

  /* Everything that is not the document leaves the paper. */
  body.pg-printing .pg-head,
  body.pg-printing .pg-main,
  body.pg-printing .pg-bar,
  body.pg-printing .pg-noscript,
  body.pg-printing .pg-doc__bar { display: none !important; }

  .pg-doc { position: static; overflow: visible; background: none; }
  .pg-doc[hidden] { display: none !important; }
  .pg-doc__pages { display: block; padding: 0; gap: 0; }

  .pd-sheet {
    width: auto; height: auto;
    box-shadow: none;
    break-after: page;
    page-break-after: always;
  }
  .pd-sheet:last-child { break-after: auto; page-break-after: auto; }
  .pd-sheet > .pd-page { transform: none; }
  .pd-page { break-inside: avoid; page-break-inside: avoid; }
}

/* ── The extras (CV, statement, portrait) ──────────────────────────────── */

.pg-extras {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.4rem;
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--pg-hair);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.35);
}
.pg-extras__head {
  font-family: var(--pg-font-title);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: lowercase;
  color: var(--pg-faint);
}
.pg-extras__item {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  cursor: pointer;
  font-family: var(--pg-font-title);
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  text-transform: lowercase;
}
.pg-extras__item input {
  width: 0.95rem; height: 0.95rem;
  accent-color: var(--pg-dark);
  cursor: pointer;
}
.pg-extras__select {
  font-family: var(--pg-font-title);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  padding: 0.25em 0.5em;
  border: 1px solid var(--pg-line);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.8);
  color: var(--pg-fg);
  margin-left: -0.8rem;
}
.pg-extras__select:disabled { opacity: 0.4; }

/* The CV and statement cards: typographic tiles — no photograph, the word
   itself in the outlined face on the site's own ground. */
.pg-tile--word {
  display: grid;
  place-items: center;
  background: linear-gradient(to bottom, #f2f2f2, #e5e5e5);
  border: 1px solid var(--pg-hair);
}
.pg-tile--word .pg-tile__word {
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: clamp(1.2rem, 2.4vw, 1.7rem);
  text-transform: lowercase;
  letter-spacing: 0.01em;
  color: transparent;
  -webkit-text-stroke: 0.5pt var(--pg-dark);
}
@supports not ((-webkit-text-stroke: 1px #000)) {
  .pg-tile--word .pg-tile__word { color: var(--pg-dark); }
}
.pg-tile--word::after { display: none; }

.pg-doc__actions { display: inline-flex; gap: 0.6rem; }

/* ── The seven-day-link modal ──────────────────────────────────────────── */

.pg-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  background: rgba(23, 25, 25, 0.35);
  backdrop-filter: blur(3px);
}
.pg-modal[hidden] { display: none; }
/* ── Die Videowahl ────────────────────────────────────────────────────────
   Breiter als die übrigen Dialoge, weil hier Bilder verglichen werden und
   nicht Sätze gelesen. Die Kacheln stehen nebeneinander, solange sie das
   können, und untereinander, sobald es eng wird — bei drei oder vier Filmen
   auf einem Laptop ist das der Normalfall. */
.pg-vid__panel { width: min(52rem, calc(100vw - 2rem)); }
.pg-vid__work {
  margin: 0.1rem 0 0;
  font-family: var(--pg-font-title);
  font-size: 0.92rem;
  color: var(--pg-fg);
}
.pg-vid__list {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.9rem;
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.pg-vid__opt {
  display: grid;
  gap: 0.5rem;
  width: 100%;
  padding: 0.55rem;
  border: 1px solid var(--pg-line);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.6);
  text-align: left;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease;
}
.pg-vid__opt:hover { background: #fff; border-color: var(--pg-dark); }
.pg-vid__opt:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 2px; }
.pg-vid__thumb {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #d8d8d8;
  border-radius: 1px;
}
.pg-vid__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pg-vid__noimg {
  font-family: var(--pg-font-title);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  color: var(--pg-faint);
}
.pg-vid__words { display: grid; gap: 0.15rem; min-width: 0; }
.pg-vid__title {
  font-family: var(--pg-font-title);
  font-size: 0.78rem;
  line-height: 1.3;
  color: var(--pg-fg);
  /* Vimeo-Titel sind oft ein ganzer Satz — zwei Zeilen, dann Schluss, sonst
     bestimmt der längste Titel die Höhe aller Kacheln. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pg-vid__url {
  font-family: var(--pg-font-title);
  font-size: 0.66rem;
  color: var(--pg-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pg-vid__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 1rem 0 0;
}
.pg-vid__count {
  font-family: var(--pg-font-title);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  color: var(--pg-faint);
}

.pg-modal__panel {
  position: relative;
  width: min(34rem, calc(100vw - 2rem));
  background: linear-gradient(to bottom, #f2f2f2, #e5e5e5);
  border: 1px solid var(--pg-line);
  border-radius: 2px;
  padding: 1.6rem 1.8rem 1.7rem;
  box-shadow: 0 18px 60px rgba(23, 25, 25, 0.25);
}
.pg-modal__close {
  position: absolute;
  top: 0.7rem; right: 0.7rem;
  width: 2rem; height: 2rem;
  display: grid; place-items: center;
  background: none; border: 0; cursor: pointer;
  color: var(--pg-muted);
}
.pg-modal__close svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.3; }
.pg-modal__close:hover { color: var(--pg-fg); }
.pg-modal__head {
  margin: 0 0 0.8rem;
  font-family: var(--pg-font-title);
  font-weight: 500;
  font-size: 1.1rem;
  text-transform: lowercase;
}
.pg-modal__status { margin: 0; color: var(--pg-muted); font-size: 0.98rem; }
.pg-modal__status.is-error { color: var(--pg-fg); }
.pg-modal__result[hidden] { display: none; }
.pg-modal__ready { margin: 0 0 0.5rem; font-size: 0.98rem; }
.pg-modal__url {
  margin: 0 0 0.8rem;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.6rem;
}
.pg-modal__url a {
  font-family: var(--pg-font-title);
  font-size: 0.92rem;
  color: var(--pg-fg);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  word-break: break-all;
}
.pg-modal__validity { margin: 0 0 1.1rem; color: var(--pg-muted); font-size: 0.92rem; }
.pg-modal__mail { border-top: 1px solid var(--pg-hair); padding-top: 1rem; }
.pg-modal__mailhead {
  margin: 0 0 0.5rem;
  font-family: var(--pg-font-title);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  color: var(--pg-muted);
}
.pg-modal__mail form { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.pg-modal__input {
  flex: 1 1 14rem;
  font-family: var(--pg-font-body);
  font-size: 1rem;
  padding: 0.5em 0.7em;
  border: 1px solid var(--pg-line);
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.85);
  color: var(--pg-fg);
}
.pg-modal__input:focus-visible { outline: 2px solid var(--pg-dark); outline-offset: 1px; }
.pg-modal__mailstatus { margin: 0.5rem 0 0; font-size: 0.9rem; color: var(--pg-muted); min-height: 1.2em; }
/* The honeypot: visually gone, present for whatever fills every field. */
.pg-modal__hp {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
@media print {
  body.pg-printing .pg-modal { display: none !important; }
}

/* ── The CV pages — the official CV's own design, measured off it ───────── */
/* Two halves of sections per sheet: headings in the title face at ~17 pt,
   entries as a 25.5 mm year column beside letterspaced 8 pt lines on 11 pt,
   the outlined wordmark bottom right as a watermark. No bar runs here: the
   CV is an appendix in a set design; the story passes through untouched. */

.pd-cvflow {
  position: absolute;
  left: var(--pd-margin);
  right: var(--pd-margin);
  top: 10mm;
  /* 184 statt 187: die letzten 3 mm gehören dem Stempel, der auf dieser einen
     Seite unten links steht (die CV-Seite hat oben keinen Rand). Gemessen
     ragte die erste Spalte sonst 1,6 mm in ihn hinein — und `column-fill: auto`
     füllt sie bis zur Unterkante, das ist also kein seltener Fall. Bezahlt
     wird es aus der Reserve der Zeilenschätzung (76 geschätzt gegen ~79
     gemessen): 1,6 % Höhe, damit der regelkundige Beschnitt im Plan weiter
     führt und der Reflow Krümelfänger bleibt. */
  height: 184mm;
  column-count: 2;
  column-gap: 12mm;
  column-fill: auto;
}
/* Sections FLOW across columns — the official CV stacks two sections in a
   column and lets a long one continue; keeping sections whole doubled the
   page count with half-empty columns. Only the heading may not strand. */
.pd-cvsec {
  margin: 0 0 7.5mm;
}
.pd-cvhead {
  break-inside: avoid;
  break-after: avoid;
  margin: 0 0 4.2mm;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: 17pt;
  line-height: 1.05;
  letter-spacing: 0.005em;
  text-transform: lowercase;
  color: var(--pd-ink);
}
.pd-cventry {
  display: grid;
  grid-template-columns: 25.5mm 1fr;
  gap: 0 2mm;
  break-inside: avoid;
  font-family: var(--pd-font-body);
  font-size: 8pt;
  line-height: 1.375;             /* 11 pt on 8 — the CV's own rhythm */
  letter-spacing: 0.08em;
  margin: 0 0 0.4mm;
}
.pd-cvyear { white-space: nowrap; }
.pd-cvtext { white-space: pre-line; }

/* Die Wortmarke, wie sie im handgesetzten Lebenslauf steht — die Werte sind
   aus dessen Inhaltsstrom gelesen, nicht geschätzt:

       0.15 w              Konturstärke 0,15 pt
       1 Tr                Textmodus „nur Kontur"
       28.2 0 0 28.2 …Tm   28,2 pt
       0.157 0.176 0.18    Strichfarbe = #282d2e, die Druckfarbe
       … 636.52 35.90 Tm   Grundlinie 35,90 pt = 12,7 mm über der Unterkante

   Das ist exakt die Behandlung der großen Werktitel im Portfolio (28,2 pt,
   0,15 pt Kontur in der Druckfarbe) — kein eigener Stil, sondern derselbe.
   Die erste Fassung malte sie flächig in #d9d9d9 bei 30 pt: ein grauer
   Klecks statt einer Kontur. */
.pd-cvmark {
  position: absolute;
  right: var(--pd-title-right);
  /* Kastenkante, nicht Grundlinie: der Wert ist am Rendern gemessen, damit
     die Grundlinie auf 12,7 mm liegt — dieselbe Linie, auf der im Portfolio
     das Jahr sitzt. Gemessen: bei 6,4 mm lag sie auf 7,88 — also 4,82 höher. */
  bottom: 11.2mm;
  font-family: var(--pg-font-title);
  font-weight: 600;
  font-size: 28.2pt;
  line-height: 1;
  letter-spacing: 0;
  text-transform: lowercase;
  color: transparent;
  -webkit-text-stroke: 0.15pt var(--pd-ink);
  z-index: 0;
}
/* Ohne Konturschrift bliebe sonst nichts stehen — dann dasselbe helle Grau,
   das auch der Titel als Ersatz nimmt. */
@supports not ((-webkit-text-stroke: 1px #000) or (text-stroke: 1px #000)) {
  .pd-cvmark { color: #c9caca; }
}

/* ── The statement page ─────────────────────────────────────────────────── */
/* The artist's own page: no title, no venue — the text at reading size,
   larger than a work's, in the band's company. */
.pd-columns--statement {
  font-size: 10pt;
  line-height: 1.6;               /* 16 pt on 10 */
  letter-spacing: 0.06em;
}
.pd-columns--statement p { margin: 0 0 4mm; }

/* ── The portrait on the last page ──────────────────────────────────────── */
.pd-portrait {
  position: absolute;
  left: var(--pd-margin);
  bottom: 12.4mm;
  margin: 0;
  overflow: hidden;
  z-index: 1;
}
.pd-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The end page's contact block holds the CV's grouped rhythm. */
.pd-page--end .pd-colophon { white-space: pre-line; max-width: 90mm; }

/* The linked word „video" keeps the ink — a printed link is still print. */
a.pd-media { color: var(--pd-ink); text-decoration: none; }


/* ── Der Spinner am Sieben-Tage-Link ──────────────────────────────────────
   Das Dokument wird auf dem Server gedruckt, und das dauert (gemessen 4,4 s
   für sechzig Seiten auf einer schnellen Maschine, entsprechend mehr auf einer
   kleinen). Ein Ring, der sich dreht, ist hier keine Dekoration, sondern die
   einzige ehrliche Antwort auf „passiert gerade etwas?". Er steht still, wenn
   der Leser das so eingestellt hat. */
.pg-modal__pdf {
  display: flex;
  align-items: center;
  gap: 0.6em;
  margin: 0.9rem 0 0;
  font-size: 0.92rem;
  color: var(--pg-muted, #6b6b66);
  min-height: 2em;
}
.pg-spinner {
  width: 1em;
  height: 1em;
  flex: none;
  border: 1px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: pg-spin 900ms linear infinite;
  opacity: 0.7;
}
@keyframes pg-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .pg-spinner { animation: none; border-right-color: currentColor; opacity: 0.35; }
}

/* Das Tageskontingent, gleich unter der Gültigkeit: eine Angabe, keine
   Warnung — deshalb dieselbe stille Farbe wie die Zeile darüber. */
.pg-modal__quota {
  margin: 0.35rem 0 0;
  font-size: 0.86rem;
  color: var(--pg-muted, #6b6b66);
}

/* ── Der Stempel auf jedem Blatt ──────────────────────────────────────────
   Drei Zeilen im OBEREN RAND, rechtsbündig auf der Kante, an der auch Titel,
   Jahr und Impressum hängen (`--pd-title-right`, die im handgesetzten PDF
   angegebene: x 805,89 von 841,89 pt). Der Rand ist der einzige Streifen, den
   fast jede Seitenart frei hat — oben rechts IM Satz sitzt auf dem kompakten
   Blatt der Titel (ab 20,4 mm), unten rechts auf dem losen das Jahr.

   **6 mm, nicht 4.** `@page { margin: 0 }` gibt uns das Blatt bis an die
   Kante, also ist unser Abstand der wirkliche — und ein Drucker kann die
   ersten 4,2 bis 6,35 mm gar nicht bedrucken. Bei 4 mm läge die erste Zeile
   auf den meisten Geräten in dieser Zone: im PDF da, auf Papier weg. Mit 6 mm
   ist die verbreitete 5-mm-Klasse ganz frei; drei Zeilen enden bei 12,6 mm,
   also genau an der Oberkante des Satzspiegels.

   **5 pt, nicht 4.** Forums x-Höhe ist 0,42 em: 4 pt sind 0,59 mm, 5 pt
   0,74 mm, die kleinste Schrift des Dokuments (6 pt Bildunterschrift) 0,89 mm
   — die dieses Stylesheet selbst schon „grenzwertig" nennt. Die dritte Zeile
   ist keine Zierde, sondern ein Ausweis, den jemand mit einer Zeile im Panel
   vergleichen muss; sie bekommt zusätzlich die Sperrung, mit der dieses
   Dokument ohnehin kleine Zeilen lesbar hält. */
.pd-stamp {
  position: absolute;
  top: 6mm;
  right: var(--pd-title-right);
  z-index: 3;
  display: flex;
  flex-direction: column;
  text-align: right;
  font-family: var(--pd-font-body);
  font-size: 5pt;
  line-height: 1.25;
  letter-spacing: 0.02em;
  color: var(--pd-stamp-ink);
  pointer-events: none;
}
.pd-stamp > span:last-child { letter-spacing: 0.08em; }

/* Die Farbe ist gerechnet, nicht gewählt: #656869 ist die Druckfarbe zu 70 %
   über dem hellen Grund und ergibt 5,0 : 1, #898989 die helle Farbe zu 55 %
   über dem dunklen Grund und ebenfalls 5,0 : 1. Fünf zu eins ist die eigene
   Vorgabe dieser Seite für kleine Schrift — und immer noch deutlich leiser
   als die Bildunterschrift bei 7,5 : 1. Die erste Fassung schrieb
   rgba(40,45,46,0.55) und maß 3,3 : 1.
   Ein Klassenwechsel für die dunkle Seite braucht es nicht: sie definiert
   ihre Tinte ohnehin neu, und ein Seitentyp-Test im JS wäre eine zweite
   Stelle, an die man denken muss. */
.pd-page      { --pd-stamp-ink: #656869; }
.pd-page--end { --pd-stamp-ink: #898989; }

/* Die CV-Seite hat keinen oberen Rand: ihr Textfluss beginnt bei 10 mm, also
   ÜBER dem Satzspiegel — sie ist die einzige Seite, die das tut, und sie tut
   es, weil der ausführliche Lebenslauf auf zwei Blätter gedeckelt ist. Dort
   weicht der Stempel nach unten aus, auf dieselbe Grundlinie wie das
   Wasserzeichen der Wortmarke (8 mm) und an dessen andere Seite, damit die
   beiden als Paar lesen und nicht als Versehen. Das ist die Regel des
   Dokuments, angewandt auf sein jüngstes Zeichen: die leiseste Marke weicht. */
.pd-page--cv .pd-stamp {
  top: auto;
  /* 8 mm, und NICHT auf der Grundlinie der Wortmarke (12,7 mm), obwohl das
     hübscher wäre: dorthin gehoben ragt der Stempel 2,2 mm in die erste
     Spalte des Lebenslaufs, und die weiter zu kürzen hieße, Platz für
     Einträge gegen eine Feinheit zu tauschen. Die Wortmarke steht, wo das
     handgesetzte CV sie hat; der Stempel steht, wo er niemanden stört. */
  bottom: 8mm;
  right: auto;
  left: var(--pd-title-right);
  text-align: left;
}

/* ── Ziehen ist kein Markieren ────────────────────────────────────────────
   Auf dieser Seite wird nichts ausgewählt: das Werkzeug besteht aus Klicken
   und Ziehen, und eine blaue Markierung, die beim Sortieren mitläuft, ist
   nichts als Lärm. Ausgenommen bleibt, was man wirklich herauskopieren will
   — die Adresse im Link-Dialog und der Text im fertigen Dokument. */
body.pg {
  -webkit-user-select: none;
  user-select: none;
}
.pg-modal__url,
.pg-modal__url a,
.pg-modal__input,
#pg-doc-pages {
  -webkit-user-select: text;
  user-select: text;
}
