/* ===========================================================================
   Galerie – Stylesheet der öffentlichen Seiten
   ---------------------------------------------------------------------------
   Aufbau:
     1. Schriften
     2. Farben & Grundwerte (CSS-Variablen)
     3. Grundgerüst (Reset, Typografie, Hilfsklassen)
     4. Kopfbereich & Navigation
     5. Startseite: Titelblock, Filter, Raster
     6. Detailseite
     7. Textseiten (Über mich)
     8. Kontaktblock & Formular
     9. Fußbereich
    10. Reaktionsfähigkeit / kleine Bildschirme
   ========================================================================= */

/* --- 1. Schriften -------------------------------------------------------- */

/* Aveline liegt als Datei bei – keine externe Schriftquelle, die Seite
   funktioniert also auch offline und ohne Verbindung zu Dritten. */
@font-face {
  font-family: 'Aveline';
  src: url('../fonts/Aveline.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Roboto: Wird die Schrift lokal gefunden (Android, ChromeOS, installiert),
   nutzt der Browser sie. Sonst greift eine metrisch sehr ähnliche Systemschrift.
   Wer Roboto mitliefern möchte, legt Roboto-Regular.woff2 und Roboto-Medium.woff2
   in assets/fonts/ ab und entfernt die Kommentarzeichen unten. */
/*
@font-face {
  font-family: 'Roboto';
  src: url('../fonts/Roboto-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Roboto';
  src: url('../fonts/Roboto-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
*/

/* --- 2. Farben & Grundwerte ---------------------------------------------- */

:root {
  --sand:        #e7e1d7;   /* Seitenhintergrund */
  --sand-deep:   #ddd5c8;   /* leichte Abhebung, Hover */
  --paper:       #fdfcfa;   /* Passepartout um die Bilder */
  --ink:         #26333a;   /* Schrift & dunkle Flächen */
  --ink-soft:    #495962;
  /* Nebenangaben (Technik, Maße, Jahr, Leerzustände).
     Der frühere Wert #8b8377 kam auf dem Sandton nur auf 2,88:1 und lag damit
     unter der Anforderung von 4,5:1 für normalen Text (WCAG AA). Dieser Ton
     hält denselben Charakter und erreicht 4,51:1. */
  --muted:       #6a645a;
  --muted-dark:  #9aa3a6;   /* Nebenangaben auf dunklem Grund */
  --line:        rgba(38, 51, 58, 0.18);

  --font-display: 'Aveline', 'Iowan Old Style', Georgia, serif;
  --font-body:    'Roboto', 'Helvetica Neue', Arial, 'Segoe UI', sans-serif;

  --page-max:    1240px;
  --page-pad:    clamp(1.25rem, 4vw, 3rem);
  --radius-pill: 999px;

  --shadow-card:  0 1px 2px rgba(38, 51, 58, 0.08), 0 12px 28px -18px rgba(38, 51, 58, 0.45);
  --shadow-hover: 0 2px 4px rgba(38, 51, 58, 0.10), 0 22px 40px -22px rgba(38, 51, 58, 0.55);
}

/* --- 3. Grundgerüst ------------------------------------------------------ */

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

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

body {
  margin: 0;
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; }

a { color: inherit; }

h1, h2, h3 { font-family: var(--font-display); font-weight: 400; letter-spacing: -0.005em; }

/* Sichtbarer Fokusrahmen für Tastaturbedienung (WCAG 2.4.7) */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}
.contact-block :focus-visible { outline-color: var(--sand); }

/* Nur für Screenreader */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--sand);
  padding: 0.75rem 1.25rem;
  z-index: 20;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

.flash {
  max-width: var(--page-max);
  margin: 1rem auto 0;
  padding: 0.85rem 1.25rem;
  border-radius: 4px;
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: 0.95rem;
}
.flash--error { border-color: #b8683f; color: #8a4526; }

.button {
  display: inline-block;
  font: inherit;
  padding: 0.85rem 2.1rem;
  border-radius: var(--radius-pill);
  border: 1px solid currentColor;
  background: none;
  color: inherit;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.button--ghost:hover { background: rgba(231, 225, 215, 0.12); }
.contact-block .button--ghost:hover { background: rgba(231, 225, 215, 0.14); }

.link-back {
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 0.98rem;
}
.link-back:hover { color: var(--ink); }

.empty-state {
  max-width: 40rem;
  margin: clamp(3rem, 10vw, 6rem) auto;
  padding: 0 var(--page-pad);
  text-align: center;
  color: var(--muted);
}
.empty-state a { color: var(--ink); }

/* --- 4. Kopfbereich & Navigation ----------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--sand);
}
/* Beim Scrollen (per JS gesetzt) hebt sich die Leiste dezent ab.
   Bewusst als Schatten und nicht als Rahmen: Ein Rahmen würde die Leiste um
   1 px höher machen und damit auf dem Telefon die 48-px-Grenze sprengen. */
.site-header.is-stuck { box-shadow: 0 1px 0 var(--line); }

.site-header__inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0.9rem var(--page-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.wordmark {
  font-family: var(--font-display);
  font-size: 1.4rem;
  text-decoration: none;
  color: var(--ink);
  line-height: 1.2;
}
/* Startseite: Der Name blendet sich in der Kopfleiste ein, sobald die große
   Überschrift nach oben aus dem Bild gescrollt ist.
   Bewusst "visibility" statt "display": Der Platz bleibt reserviert, die
   Navigation springt beim Einblenden also nicht. Gleichzeitig ist der Link im
   unsichtbaren Zustand weder mit der Tabulatortaste erreichbar noch für
   Screenreader vorhanden. Ohne JavaScript bleibt er unsichtbar – es geht nichts
   verloren, denn er verweist nur auf die bereits geöffnete Seite. */
.wordmark--reveal {
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}
.wordmark--reveal.is-visible { visibility: visible; opacity: 1; }

.site-nav { display: flex; align-items: center; gap: clamp(0.75rem, 2vw, 2rem); }

.site-nav ul {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 2rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Der Menüknopf ist auf dem Bildschirm nicht vorhanden - dort steht ohnehin
   alles in einer Reihe. Er taucht erst in der Telefonansicht auf, und auch
   dort nur, wenn JavaScript läuft (siehe unten). */
.nav-toggle { display: none; }
.social-icon__label { display: none; }
.site-nav a {
  display: inline-block;
  padding: 0.55rem 0.25rem;      /* großzügige Trefferfläche auf Touchgeräten */
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 1rem;
  transition: color 0.2s ease;
}
.site-nav a:hover,
.site-nav a[aria-current] { color: var(--ink); }

.site-nav .nav-pill {
  padding: 0.5rem 1.5rem;
  border: 1px solid var(--ink);
  border-radius: var(--radius-pill);
  color: var(--ink);
}
.site-nav .nav-pill:hover { background: var(--ink); color: var(--sand); }

/* --- Verweis auf Instagram -----------------------------------------------
   Das erste und einzige Bildzeichen der öffentlichen Seite. Bewusst als
   Umrisszeichnung in der Farbe der übrigen Navigationslinks und nicht als
   buntes Verlaufslogo: Das wäre der einzige Farbfleck der Seite und zöge die
   Aufmerksamkeit von den Werken weg. */
.social-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: var(--radius-pill);
  color: var(--ink-soft);
  transition: color 0.2s ease, background-color 0.2s ease;
}
/* Bewusst gerade Maße: 20 px in 40 px ergibt genau 10 px Luft auf jeder Seite.
   Bei einer ungeraden Größe blieben 9,5 px, und auf Bildschirmen ohne doppelte
   Pixeldichte rundet der Browser das zu 9 und 10 - das Zeichen sitzt dann um
   ein Pixel daneben. */
.social-icon svg { width: 20px; height: 20px; display: block; }

/* WICHTIG: ".site-nav a" ist spezifischer als ".social-icon" und setzt
   display:inline-block sowie einen Innenabstand. Ohne diese Zeile ist das
   Element in der Kopfleiste gar kein Flex-Kasten - align-items und
   justify-content bleiben wirkungslos und das Zeichen klebt in der linken
   oberen Ecke, rund 5 px aus der Mitte. */
.site-nav .social-icon {
  display: inline-flex;
  padding: 0;
}
.site-nav .social-icon:hover { background: var(--sand-deep); color: var(--ink); }

/* Der Listenpunkt wird selbst zum Flex-Kasten. Sonst stünde das Zeichen auf der
   Textgrundlinie des Punktes, unter sich der Platz für Unterlängen - es säße
   dann rund 5 px höher als der Kontakt-Knopf daneben. */
.site-nav__social { display: flex; }

/* --- 5. Startseite -------------------------------------------------------- */

.hero {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 3rem) var(--page-pad) 0;
  text-align: center;
}
/* Name, Berufsbezeichnung und Ort stehen linksbündig untereinander.
   Der Kniff: Der umschließende Block ist "inline-block" und damit genau so
   breit wie sein breitester Inhalt – also wie der Name. Dadurch beginnen alle
   drei Zeilen an derselben Kante, während der Block selbst durch das
   text-align:center der Sektion mittig auf der Seite sitzt. */
.hero__intro {
  display: inline-block;
  max-width: 100%;
  text-align: left;
}
.hero__name {
  margin: 0;
  font-size: clamp(2.75rem, 8vw, 4.6rem);
  line-height: 1.05;
}
.hero__role {
  margin: 1.75rem 0 0;
  color: var(--ink-soft);
}
.hero__role span { display: block; }

.hero__statement {
  margin: clamp(2.5rem, 7vw, 4.5rem) auto 0;
  max-width: 52rem;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  color: var(--ink);
}

.filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  max-width: var(--page-max);
  margin: clamp(2.5rem, 6vw, 4rem) auto clamp(2rem, 4vw, 3rem);
  padding: 0 var(--page-pad);
}
.filter {
  --filter-color: var(--ink);
  padding: 0.55rem 1.5rem;
  border: 1px solid var(--filter-color);
  border-radius: var(--radius-pill);
  color: var(--filter-color);
  background: none;
  font: inherit;
  font-size: 0.98rem;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.filter:hover { background: color-mix(in srgb, var(--filter-color) 12%, transparent); }
.filter.is-active {
  background: var(--filter-color);
  color: var(--sand);
}

/* Raster der Werke.
   ---------------------------------------------------------------------------
   Grundlage ist ein echtes CSS-Grid, das ZEILENWEISE füllt: Das erste Werk
   steht oben links, das zweite daneben, das dritte rechts davon. Die
   Reihenfolge aus der Verwaltung ist damit auch von links nach rechts lesbar.

   (Ein mehrspaltiger Textfluss – "column-count" – wäre einfacher, füllt aber
   zwangsläufig erst die linke Spalte von oben bis unten. Die zuerst
   einsortierten Werke landen dann untereinander statt nebeneinander.)

   In dieser Grundform ist jede Zeile so hoch wie ihr höchstes Bild; unter
   flacheren Werken bleibt also Luft. Den Feinschliff macht assets/js/gallery.js:
   Es setzt für jede Kachel, über wie viele der 1 px hohen Rasterzeilen sie
   reicht – dadurch rücken die Kacheln dicht zusammen, ohne dass ein Bild
   beschnitten oder auf eine einheitliche Höhe gezwungen wird. Ohne JavaScript
   bleibt das gewöhnliche Raster: etwas luftiger, aber vollständig und in der
   richtigen Reihenfolge. */
.grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 3vw, 2.75rem);
  /* Senkrecht bewusst enger als waagerecht: Unter jedem Bild stehen bereits
     Titel und Angaben, die optisch mitzählen. Ein gleich großer Zeilenabstand
     ließe die Kacheln untereinander auseinanderfallen. */
  row-gap: clamp(1rem, 2vw, 1.75rem);
  align-items: start;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--page-pad) clamp(4rem, 9vw, 7rem);
  list-style: none;
}
.grid__item[hidden] { display: none; }

/* Wird nur gesetzt, wenn JavaScript die Zeilenspannen berechnet hat.
   Der Zeilenabstand wird dabei auf 0 gesetzt und stattdessen in die berechnete
   Spanne eingerechnet. Grund: Eine Rasterstufe ist sonst 1 px + Zeilenabstand
   groß, und der Rest beim Aufrunden landet als zusätzliche Lücke unter der
   Kachel – die Abstände schwankten dadurch um bis zu 26 px. So beträgt eine
   Stufe genau 1 px und alle Abstände sind auf 1 px genau gleich. */
.grid--masonry {
  grid-auto-rows: 1px;
  row-gap: 0;
}

/* Randfälle: Bei ein oder zwei sichtbaren Werken würden drei Spalten eine
   große leere Fläche hinterlassen. Die Spaltenzahl richtet sich deshalb nach
   der Anzahl der sichtbaren Werke (serverseitig gesetzt, beim Filtern von
   assets/js/gallery.js aktualisiert). Die Breite wird zusätzlich begrenzt,
   damit ein einzelnes Werk nicht bildschirmfüllend wirkt. */
.grid--cols-1 { grid-template-columns: minmax(0, 1fr); max-width: 32rem; }
.grid--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 64rem; }
.grid--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.card {
  display: block;
  text-decoration: none;
  color: inherit;
}
.card__mat {
  display: block;
  background: var(--paper);
  padding: clamp(0.5rem, 1.1vw, 0.8rem);
  box-shadow: var(--shadow-card);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.card__mat img { display: block; width: 100%; }
.card:hover .card__mat {
  transform: translateY(-3px);
  box-shadow: var(--shadow-hover);
}
.card__placeholder {
  display: block;
  aspect-ratio: 3 / 4;
  background: repeating-linear-gradient(45deg, var(--sand-deep) 0 12px, var(--paper) 12px 24px);
}
.card__title {
  display: block;
  margin-top: 0.475rem;   /* halber Abstand zum Bild – rückt die Beschriftung näher heran */
  font-size: 1.05rem;
  color: var(--ink-soft);
}
.card:hover .card__title { color: var(--ink); }
.card__meta {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.86rem;
  color: var(--muted);
}

/* --- 6. Detailseite ------------------------------------------------------- */

.detail,
.detail-missing {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.5rem) var(--page-pad) clamp(4rem, 8vw, 6rem);
}
.detail-missing { text-align: center; padding-top: clamp(4rem, 12vw, 8rem); }
.detail-missing__text { max-width: 34rem; margin: 1rem auto 2rem; color: var(--muted); }

/* Hinweisbalken über einem Entwurf – sieht nur der angemeldete Inhaber.
   Ein eigener, warmer Ton: deutlich genug, um nicht übersehen zu werden,
   aber kein Alarmrot. */
.draft-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.25rem;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0.75rem var(--page-pad);
  background: #8a6220;
  color: #f6efe2;
  font-size: 0.92rem;
}
.draft-banner__text { margin: 0; }
.draft-banner__text strong { font-weight: 500; }
.draft-banner__action { margin: 0 0 0 auto; }
.draft-banner__button {
  font: inherit;
  padding: 0.35rem 1rem;
  border: 1px solid rgba(246, 239, 226, 0.6);
  border-radius: 4px;
  background: none;
  color: inherit;
  cursor: pointer;
}
.draft-banner__button:hover { background: rgba(246, 239, 226, 0.15); }
.draft-banner__link { color: inherit; }
.draft-banner :focus-visible { outline: 2px solid #f6efe2; outline-offset: 2px; }
@media (max-width: 640px) {
  .draft-banner__action { margin-left: 0; }
}

.detail__back { margin: 0 0 clamp(1.5rem, 3vw, 2.5rem); }

.detail__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

.detail__figure {
  margin: 0;
  background: var(--paper);
  padding: clamp(0.5rem, 1.2vw, 0.9rem);
  box-shadow: var(--shadow-card);
  justify-self: start;
  max-width: 640px;
}
.detail__figure img { display: block; width: 100%; }

/* Bild anklickbar: Verweis auf die große Datei, mit dezentem Lupenzeichen. */
.detail__zoom {
  display: block;
  position: relative;
  cursor: zoom-in;
}
.detail__zoom-badge {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: rgba(38, 51, 58, 0.75);
  color: var(--sand);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.detail__zoom:hover .detail__zoom-badge,
.detail__zoom:focus-visible .detail__zoom-badge { opacity: 1; }
/* Auf Touchgeräten gibt es kein Überfahren – dort immer sichtbar. */
@media (hover: none) {
  .detail__zoom-badge { opacity: 1; }
}

/* --- Bildreihe unter dem Werk -------------------------------------------- */

/* Erscheint nur bei mehr als einem Bild. Bei einem einzelnen Bild sieht die
   Werkseite unverändert aus wie zuvor. */
.detail__strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.7rem 0 0;
  padding: 0;
  list-style: none;
}
.detail__strip-item {
  display: block;
  padding: 3px;
  background: var(--paper);
  border: 1px solid transparent;
  box-shadow: 0 1px 2px rgba(38, 51, 58, 0.08);
  transition: border-color 0.15s ease;
}
.detail__strip-item img {
  display: block;
  width: 72px;
  height: 56px;
  object-fit: cover;         /* gleich große Felder, ohne zu verzerren */
}
.detail__strip-item:hover { border-color: var(--muted); }
.detail__strip-item.is-active { border-color: var(--ink); }

.detail__caption {
  margin: 0.7rem 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}

/* --- Vergrößerte Ansicht ------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: none;
  background: rgba(23, 32, 37, 0.96);
  overscroll-behavior: contain;
}
.lightbox.is-open { display: block; }
body.has-lightbox { overflow: hidden; }

.lightbox__image {
  position: absolute;
  left: 50%;
  top: 50%;
  transform-origin: center center;
  cursor: zoom-in;
  touch-action: none;          /* Ziehen und Zwei-Finger-Geste selbst behandeln */
  user-select: none;
  max-width: none;             /* die Größe setzt das Skript */
}
.lightbox.is-zoomed .lightbox__image { cursor: grab; }

.lightbox__close {
  position: absolute;
  top: clamp(0.75rem, 2vw, 1.5rem);
  right: clamp(0.75rem, 2vw, 1.5rem);
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(231, 225, 215, 0.5);
  border-radius: 50%;
  background: none;
  color: var(--sand);
  font: inherit;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.lightbox__close:hover { background: var(--sand); color: var(--ink); }
.lightbox__close:focus-visible { outline: 2px solid var(--sand); outline-offset: 2px; }

.lightbox__hint {
  position: absolute;
  left: 50%;
  bottom: clamp(0.5rem, 2vw, 1.25rem);
  transform: translateX(-50%);
  margin: 0;
  font-size: 0.82rem;
  color: rgba(231, 225, 215, 0.55);
  text-align: center;
  pointer-events: none;
  max-width: min(90vw, 40rem);
}
/* Zähler und Beschriftung des gerade gezeigten Bildes */
.lightbox__hint b { font-weight: 400; color: rgba(231, 225, 215, 0.8); }

/* Blättern zwischen den Bildern eines Werks – nur bei mehreren vorhanden. */
.lightbox__step {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(231, 225, 215, 0.5);
  border-radius: 50%;
  background: rgba(23, 32, 37, 0.55);
  color: var(--sand);
  font: inherit;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.lightbox__step:hover { background: var(--sand); color: var(--ink); }
.lightbox__step:focus-visible { outline: 2px solid var(--sand); outline-offset: 2px; }
.lightbox__step--prev { left: clamp(0.5rem, 2vw, 1.5rem); }
.lightbox__step--next { right: clamp(0.5rem, 2vw, 1.5rem); }
/* Beim Hineinzoomen stören die Pfeile – dann verschwinden sie. */
.lightbox.is-zoomed .lightbox__step { display: none; }
@media (max-width: 640px) {
  .lightbox__hint { display: none; }   /* auf dem Telefon selbsterklärend */
}

.detail__title {
  margin: 0 0 1.25rem;
  font-size: clamp(2.2rem, 5vw, 3.3rem);
  line-height: 1.05;
}
.detail__description { color: var(--ink-soft); max-width: 40rem; }
.detail__description p { margin: 0 0 1rem; }

.detail__meta { margin: 2.25rem 0 0; }
.detail__row { margin-bottom: 0.85rem; }
/* Die Bezeichnungen (Technik, Maße, …) sind für Screenreader vorhanden,
   optisch zeigt das Layout – wie im Entwurf – nur die Werte. */
.detail__row dt {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}
.detail__row dd {
  margin: 0;
  color: var(--muted);
  font-size: 1.02rem;
}
.detail__row dd a { color: var(--muted); text-underline-offset: 3px; }
.detail__row dd a:hover { color: var(--ink); }

/* Kategorie als gefüllte Pille – gleiche Form wie die Filterknöpfe auf der
   Startseite, gefüllt mit der Farbe der jeweiligen Kategorie. Füllung und
   Schriftfarbe kommen aus dem HTML (dort berechnet), damit jede im
   Admin-Bereich gewählte Farbe lesbar bleibt. */
.detail__row--tag { margin-top: 1.25rem; }
.tag-pill {
  display: inline-block;
  padding: 0.35rem 1.1rem;
  border-radius: var(--radius-pill);
  background: var(--tag-bg, var(--ink));
  color: var(--tag-fg, var(--sand));
  font-size: 0.95rem;
  line-height: 1.5;
  text-decoration: none;
  transition: filter 0.2s ease;
}
.detail__row dd a.tag-pill { color: var(--tag-fg, var(--sand)); }
.tag-pill:hover { filter: brightness(0.92); }
.tag-pill:focus-visible { outline-offset: 2px; }

/* Blättern zwischen den Werken: nur zwei Kreise mit Pfeil.
   Umrandung, Rundung und das Füllen beim Überfahren entsprechen dem
   Kontakt-Knopf in der Kopfleiste (.nav-pill) – nur eben rund statt länglich. */
.detail__nav {
  display: flex;
  gap: 0.75rem;
  margin-top: clamp(3rem, 7vw, 5rem);
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}
/* Zurück-Pfeil an die linke, Weiter-Pfeil an die rechte Kante.
   Der automatische Außenabstand erledigt zugleich die Randfälle: Beim ersten
   Werk gibt es nur den Weiter-Pfeil - er wird trotzdem nach rechts geschoben.
   Beim letzten Werk bleibt der Zurück-Pfeil von selbst links stehen. */
.detail__nav-link[rel="next"] { margin-left: auto; }
.detail__nav-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--ink);
  border-radius: 50%;
  color: var(--ink);
  font-size: 1.15rem;
  line-height: 1;
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.detail__nav-link:hover { background: var(--ink); color: var(--sand); }

/* --- 7. Textseiten -------------------------------------------------------- */

.prose {
  max-width: 62rem;
  margin: 0 auto;
  padding: clamp(2rem, 6vw, 4rem) var(--page-pad) clamp(4rem, 8vw, 6rem);
}
.prose__title {
  margin: 0 0 clamp(2rem, 4vw, 3rem);
  font-size: clamp(2.4rem, 6vw, 3.6rem);
  line-height: 1.05;
}
.prose__layout--with-portrait {
  display: grid;
  grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
.prose__portrait {
  margin: 0;
  background: var(--paper);
  padding: 0.6rem;
  box-shadow: var(--shadow-card);
}
.prose__portrait img { display: block; width: 100%; }
.prose__intro { font-size: 1.2rem; color: var(--ink); margin-top: 0; }
.prose__text { color: var(--ink-soft); max-width: 40rem; }
.prose__text p { margin: 0 0 1.15rem; }

/* --- 8. Kontaktblock & Formular ------------------------------------------- */

.contact-block {
  background: var(--ink);
  color: var(--sand);
  padding: clamp(3.5rem, 10vw, 7rem) var(--page-pad) clamp(3rem, 8vw, 5rem);
  text-align: center;
}
.contact-block__inner { max-width: 56rem; margin: 0 auto; }

.contact-block__label {
  margin: 0 0 clamp(1.5rem, 4vw, 2.5rem);
  font-size: 0.95rem;
  color: var(--muted-dark);
}
.contact-block__heading {
  margin: 0;
  font-size: clamp(2.4rem, 7vw, 4rem);
  line-height: 1.05;
  max-width: 14ch;
  margin-inline: auto;
}
.contact-block__text {
  margin: clamp(1.75rem, 4vw, 2.75rem) auto 0;
  max-width: 44rem;
  color: rgba(231, 225, 215, 0.85);
}
.contact-block__text--small { font-size: 0.98rem; }
.contact-block__action { margin: clamp(2rem, 5vw, 3rem) 0 0; }
.contact-block__success {
  margin: 2.5rem auto 0;
  max-width: 40rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid rgba(231, 225, 215, 0.4);
  border-radius: 4px;
}
.contact-block__imprint {
  margin: clamp(2.5rem, 6vw, 4rem) 0 0;
  font-size: 0.9rem;
  color: var(--muted-dark);
}

.contact-form {
  max-width: 34rem;
  margin: clamp(2.5rem, 6vw, 3.5rem) auto 0;
  text-align: left;
}
.field { margin-bottom: 1.5rem; }
.field label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.92rem;
  color: rgba(231, 225, 215, 0.75);
}
.field__hint { color: var(--muted-dark); }
.contact-form input,
.contact-form textarea {
  width: 100%;
  font: inherit;
  color: var(--sand);
  background: transparent;
  border: 1px solid rgba(231, 225, 215, 0.35);
  border-radius: 3px;
  padding: 0.75rem 0.9rem;
}
.contact-form textarea { resize: vertical; min-height: 8rem; }
.contact-form input:focus,
.contact-form textarea:focus { border-color: var(--sand); outline-offset: 1px; }
.contact-form .button { margin-top: 0.5rem; }

.form-error {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.88rem;
  color: #f0b49a;
}
.form-error--summary {
  margin: 0 auto;
  max-width: 34rem;
  padding: 0.85rem 1rem;
  border: 1px solid #f0b49a;
  border-radius: 4px;
}

/* Honeypot: für Menschen unsichtbar, für Bots ein verlockendes Feld.
   Bewusst nicht display:none – manche Bots ignorieren solche Felder. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* --- Sprung an den Seitenanfang ------------------------------------------ */

/* Wie die Blätter-Knöpfe auf der Werkseite: runder Umriss, füllt sich beim
   Überfahren. Gefüllter Hintergrund, weil er über Bildern schwebt.
   Unsichtbar über "visibility" statt "display": So ist er ohne JavaScript
   weder sicht- noch mit der Tabulatortaste erreichbar. */
.to-top {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 20;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--ink);
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink);
  font: inherit;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 6px 18px -8px rgba(38, 51, 58, 0.55);
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.2s ease, visibility 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}
.to-top.is-visible { visibility: visible; opacity: 1; }
.to-top:hover { background: var(--ink); color: var(--sand); }

/* --- 9. Fußbereich -------------------------------------------------------- */

.site-footer { background: var(--ink); color: var(--sand); }
.site-footer :focus-visible { outline-color: var(--sand); }
.site-footer__legal {
  margin: 0;
  padding: 0 var(--page-pad) clamp(2.5rem, 6vw, 4rem);
  text-align: center;
  font-size: 0.9rem;
  /* 0.45 ergab nur 3,3:1 auf dem dunklen Grund – 0.59 erreicht 4,56:1. */
  color: rgba(231, 225, 215, 0.59);
}
.site-footer__sep { padding: 0 0.4rem; }
/* Zugang zur Verwaltung: für den Inhaber jederzeit erreichbar, für Besucher
   unaufdringlich. Die Trefferfläche ist trotz kleiner Schrift ausreichend groß. */
.site-footer__login {
  display: inline-block;
  padding: 0.5rem 0.25rem;
  color: rgba(231, 225, 215, 0.55);
  text-decoration: none;
}
.site-footer__login:hover { color: var(--sand); text-decoration: underline; }

/* Im Fußbereich steht das Zeichen auf dunklem Grund und richtet sich deshalb
   nach dem Login-Link daneben, nicht nach der Kopfleiste. Etwas kleiner, damit
   es in der Zeile nicht dominiert. */
.social-icon--footer {
  width: 34px;
  height: 34px;
  vertical-align: middle;
  color: rgba(231, 225, 215, 0.55);
}
/* Auch hier ein gerades Maß: 18 px in 34 px sind genau 8 px je Seite. */
.social-icon--footer svg { width: 18px; height: 18px; }
.social-icon--footer:hover { color: var(--sand); }
.page-contact .site-footer__legal { padding-top: 2rem; }

/* --- 10. Kleine Bildschirme ---------------------------------------------- */

@media (max-width: 1000px) {
  /* Auf mittleren Bildschirmen (Tablet) höchstens zwei Spalten. */
  .grid--cols-2, .grid--cols-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 64rem;
  }
}

@media (max-width: 900px) {
  .detail__layout,
  .prose__layout--with-portrait { grid-template-columns: minmax(0, 1fr); }
  .detail__figure { max-width: none; justify-self: stretch; }
  .prose__portrait { max-width: 22rem; }
}

@media (max-width: 640px) {
  /* Kopfleiste auf dem Telefon: bleibt oben stehen, bleibt aber flach.
     Höchstens 48 px – deshalb kein Innenabstand oben/unten, sondern eine
     Mindesthöhe für die Zeile. Die Links füllen diese Höhe vollständig aus:
     So bleibt die Trefferfläche mit 40 px daumenfreundlich, obwohl die
     Leiste selbst niedrig ist. */
  /* Die folgenden Werte sind am Gerät ausgemessen, nicht geschätzt: Bei 360 px
     Breite (verbreitetste kleine Bildschirmgröße) braucht die Navigation
     ~211 px, der Name ~108 px – zusammen mit den Abständen bleibt so ein
     kleiner Puffer. */
  .site-header__inner {
    min-height: 48px;
    padding-block: 0;
    padding-inline: 0.875rem;
    gap: 0.6rem;
    flex-wrap: nowrap;                /* niemals zweizeilig werden */
  }
  .wordmark {
    font-size: 0.95rem;
    min-width: 0;                     /* darf notfalls schrumpfen … */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;              /* … statt die Zeile zu sprengen */
  }
  .site-nav { flex: 0 0 auto; }       /* die Navigation schrumpft nie */
  .site-nav ul { gap: 0.6rem; flex-wrap: nowrap; }
  .site-nav a {
    display: flex;
    align-items: center;
    min-height: 40px;                 /* Trefferfläche trotz flacher Leiste */
    padding-inline: 0;
    font-size: 0.92rem;
    white-space: nowrap;
  }
  .site-nav .nav-pill { padding: 0 0.7rem; }

  /* --- Menü hinter dem Knopf (nur Telefon, nur mit JavaScript) -------------
     Ohne die Markierung "js" am Dokument greift nichts hiervon: Dann bleibt
     die Navigation eine gewöhnliche Reihe in der Leiste - genau wie bisher.
     Der Knopf wäre ohne Skript ja wirkungslos, also erscheint er auch nicht.
     Instagram bleibt in dem Fall ausgeblendet; die Zeile ist dort auf die
     Kante ausgemessen und trägt kein viertes Element. */
  .site-nav__social { display: none; }

  .js .nav-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-right: -0.5rem;         /* optisch bündig mit dem Seitenrand */
    padding: 0;
    border: 0;
    background: none;
    color: var(--ink);
    cursor: pointer;
    order: 2;                      /* immer ganz rechts */
  }
  /* Drei Striche aus einem Element: der mittlere ist der Kasten selbst, die
     äußeren sind seine beiden Schattenrisse. */
  .js .nav-toggle__bars,
  .js .nav-toggle__bars::before,
  .js .nav-toggle__bars::after {
    display: block;
    width: 20px;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
  }
  .js .nav-toggle__bars { position: relative; }
  .js .nav-toggle__bars::before,
  .js .nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
  .js .nav-toggle__bars::before { top: -6px; }
  .js .nav-toggle__bars::after  { top: 6px; }

  /* Im geöffneten Zustand werden aus den Strichen ein Kreuz. */
  .js .nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
  .js .nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { top: 0; transform: rotate(45deg); }
  .js .nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { top: 0; transform: rotate(-45deg); }

  /* Die Klappe legt sich über den Inhalt, statt ihn nach unten zu schieben:
     So bleibt die Leseposition erhalten, wenn man das Menü wieder schließt. */
  .js .site-nav__list {
    position: fixed;
    top: 48px;                     /* genau unter der Leiste */
    left: 0;
    right: 0;
    z-index: 11;
    display: block;
    background: var(--sand);
    border-bottom: 1px solid var(--line);
    padding: 0.5rem 0 1rem;
    /* Zugeklappt ist die Liste weder sichtbar noch mit der Tabulatortaste
       erreichbar - "visibility" sorgt für beides, "transform" für die
       Bewegung. Mit display:none gäbe es keinen Übergang. */
    visibility: hidden;
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s ease;
  }
  .js .site-nav.is-open .site-nav__list {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
  }
  .js .site-nav__list a {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    min-height: 52px;              /* großzügig für den Daumen */
    padding: 0 var(--page-pad);
    font-size: 1.15rem;
    color: var(--ink);
  }
  .js .site-nav__list a[aria-current] { font-weight: 500; }
  /* In der Klappe steht neben dem Zeichen auch das Wort - ein Symbol allein
     wäre in einer Liste aus Wörtern ein Fremdkörper. */
  .js .site-nav__list .site-nav__social { display: block; margin-top: 0.35rem; }
  .js .site-nav__list .social-icon {
    width: auto;
    height: auto;
    justify-content: flex-start;
    border-radius: 0;
    color: var(--ink);
  }
  .js .site-nav__list .social-icon__label { display: inline; }

  /* Fläche hinter der Klappe: dämpft den Inhalt und schließt auf Tippen. */
  .js .nav-scrim {
    position: fixed;
    inset: 48px 0 0;
    z-index: 10;
    background: rgba(38, 51, 58, 0.35);
    border: 0;
  }
  .grid,
  .grid--cols-1, .grid--cols-2, .grid--cols-3 {
    grid-template-columns: minmax(0, 1fr);
    max-width: 32rem;
  }
}

/* Sehr schmale Geräte (iPhone SE der 1. Generation, 320 px):
   Hier reicht der Platz nicht für Name UND Navigation. Ein abgeschnittener
   Name („Jan F. Va…“) sieht nach Fehler aus – deshalb entfällt er ganz und
   die Navigation rückt nach rechts. Auf der Seite selbst steht der Name
   weiterhin als Überschrift. */
@media (max-width: 340px) {
  .wordmark { display: none; }
  .site-header__inner { justify-content: flex-end; }
}

/* Nutzer, die reduzierte Bewegung wünschen, bekommen keine Übergänge. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
  .card:hover .card__mat { transform: none; }
}

/* Druckausgabe: dunkle Flächen und Navigation weglassen. */
@media print {
  .site-header, .contact-block, .detail__nav, .filters { display: none; }
  body { background: #fff; }
  .card__mat, .detail__figure { box-shadow: none; }
}
