/* Viewer-Gestaltung, Phase 0.
   Bewusst schlicht — das CI-Theme kommt in Phase 1 (T-026). Was hier schon
   verbindlich ist: Kontraste, Fokus-Sichtbarkeit und Zielgrößen. */

/* Hausschrift, mitgeliefert statt nachgeladen — der Katalog liegt
   geschlossen auf media.igefa.de und fragt keinen fremden Dienst. */
@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/mulish-latin-400-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'Mulish';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/mulish-latin-700-normal.woff2') format('woff2');
}

/* Farben aus dem Corporate Design, übernommen aus
   frontend/assets/css/tokens.css des Website-Baus — keine frei gewählten
   Werte. Der Akzent eines einzelnen Katalogs überschreibt `--akzent`. */
:root {
  --navy: #00334d;
  --akzent: #0068ab;
  --akzent-hell: #009ee3;
  --grund: #ffffff;
  --text: #1a1a1a;
  --gedaempft: #595959; /* 7:1 auf Weiß */
  --rand: #d4d4d4;
  --buehne: #f2f2f2;
  /* Kopf und Leiste zusammen. Die Bühne bekommt den Rest; ändert sich die
     Höhe einer der beiden, gehört dieser Wert nachgemessen. */
  --rahmen-hoehe: 4.75rem;
}

* {
  box-sizing: border-box;
}

/* Eine Klasse mit eigenem `display` schlägt die Browser-Regel für `[hidden]`.
   Das traf schon den Zoom-Dialog und dann den Inhalt-Knopf, der ohne
   erkanntes Verzeichnis versteckt sein soll und trotzdem dastand. Einmal
   zentral, statt an jeder Klasse einzeln. */
[hidden] {
  display: none !important;
}

/* Spaltenlayout über die volle Fensterhöhe: Kopf und Leiste nehmen sich, was
   sie brauchen, die Bühne bekommt den Rest. Ohne das wächst der Katalog über
   den Bildschirmrand hinaus — die Engine passt die Seite an die verfügbare
   BREITE an, und ohne begrenzte Höhe wird die Bühne einfach mitgezogen.
   dvh statt vh, damit die ein- und ausfahrende Browserleiste auf dem Handy
   nicht dauernd das Layout verschiebt. */
body {
  margin: 0;
  font-family: 'Mulish', Arial, sans-serif;
  color: var(--text);
  background: var(--grund);
  line-height: 1.5;
}

/* Fokus muss immer sichtbar sein — WCAG 2.4.7. Kontrast des Rings ≥ 3:1. */
:focus-visible {
  outline: 3px solid var(--akzent);
  outline-offset: 2px;
}

/* Marke links, Titel in der Mitte, Suche rechts — wie in der Vorlage. Der
   Kopf bleibt eine dünne weiße Leiste, damit die Seite die Fläche bekommt. */
.kopf {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.3rem 1.25rem;
  border-bottom: 1px solid var(--rand);
}

/* 30 px Marke in einer 42 px flachen Leiste — das Original (FlipBuilder)
   misst oben wie unten 46 px, flacher ist besser. */
.kopf-marke {
  flex: 0 0 auto;
  height: 30px;
  width: auto;
}

.kopf-titel {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-size: clamp(1rem, 2.2vw, 1.3rem);
  font-weight: 700;
  color: var(--navy);
  text-align: center;
  /* Ein langer Katalogtitel darf den Kopf nicht umbrechen lassen. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kopf-suche {
  flex: 0 0 auto;
  position: relative;
}

/* Die Bühne braucht eine BERECHNETE Höhe, keine Mindesthöhe.
   Die Engine liest die Höhe ihres Behälters aus und verkleinert die Seite nur,
   wenn dieser Wert feststeht. Aus einem `flex: 1` allein ergibt sich keiner:
   Der Behälter würde einfach mit dem Inhalt mitwachsen — genau das ließ den
   Katalog 427 px unter den Bildschirmrand rutschen.
   Abgezogen werden Kopfzeile, Bedienhinweis und Leiste. */
/* ---------------------------------------------------------------------------
   Untergrund
   Die Vorlagennamen (holz, holz-dunkel, grau, dunkel) müssen mit
   src/hintergrund.ts und generator/src/cli.ts übereinstimmen. Ein TS-Test
   (test/vorlagen-drift.test.ts) hält die beiden Code-Seiten deckungsgleich,
   diese CSS-Datei kann er aber nicht prüfen — bei Änderungen hier mitdenken.
   Kommt aus katalog.json (Feld `hintergrund`) und wird als data-Attribut an
   die Bühne geschrieben. Bewusst als CSS statt als Bilddatei: kein Binärdatei
   im Repo, keine Lizenzfrage, kein zusätzlicher Download — und die Maserung
   lässt sich durch Ändern zweier Farbwerte umfärben.
   --------------------------------------------------------------------------- */

.buehne[data-hintergrund='holz'] {
  --holz-grund: #8a5a33;
  --holz-dunkel: #6b431f;
}

.buehne[data-hintergrund='holz-dunkel'] {
  --holz-grund: #4a3220;
  --holz-dunkel: #2f2113;
}

.buehne[data-hintergrund^='holz'] {
  background-color: var(--holz-grund);
  background-image:
    /* Abdunklung zu den Rändern — lässt die Fläche als Tisch wirken statt als Farbfeld */
    radial-gradient(135% 105% at 50% 32%, rgba(255, 255, 255, 0.12), rgba(0, 0, 0, 0.48) 100%),
    /* Maserung, längs zu den Dielen. Drei Lagen mit leicht verschiedenen
       Winkeln und Perioden — eine allein sieht aus wie ein Raster. */
    repeating-linear-gradient(0.7deg, rgba(0, 0, 0, 0.06) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-0.5deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 8px),
    repeating-linear-gradient(0.3deg, rgba(0, 0, 0, 0.035) 0 2px, transparent 2px 17px),
    /* Dielenfugen, waagerecht wie bei einer Tischplatte. Zwei Perioden, die
       kein gemeinsames Vielfaches haben — sonst fällt die Wiederholung auf. */
    repeating-linear-gradient(180deg, var(--holz-dunkel) 0 2px, transparent 2px 137px),
    repeating-linear-gradient(180deg, rgba(0, 0, 0, 0.14) 0 1px, transparent 1px 211px);
}

/* Hintergrundbild. Die URL setzt der Viewer erst, wenn das Bild geladen ist —
   bis dahin steht das gezeichnete Holz darunter, und bei einem fehlenden Bild
   bleibt es stehen. */
.buehne[data-hintergrund='bild'] {
  background-color: var(--holz-grund, #8a5a33);
  background-position: center;
}

/* Kleine Texturen wiederholen sich, große Fotos füllen. Entschieden wird das
   anhand der tatsächlichen Bildgröße, nicht per Einstellung. */
.buehne[data-darstellung='kachel'] {
  background-repeat: repeat;
  background-size: auto;
}

.buehne[data-darstellung='fuellend'] {
  background-repeat: no-repeat;
  background-size: cover;
}

.buehne[data-hintergrund='grau'] {
  background: #e9e9e9;
}

.buehne[data-hintergrund='dunkel'] {
  background: #262626;
}

/* Das Buch soll auf dem Untergrund liegen, nicht darauf kleben.
   Auf hellem Grau wäre der Schatten zu hart, dort fällt er weicher aus. */
.buehne[data-hintergrund]:not([data-hintergrund='grau']) .seite {
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
}

.buehne[data-hintergrund='grau'] .seite {
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.18);
}

.buehne {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;
  background: var(--buehne);
  /* Kein Deckel nach oben: mit `clamp(…, 1000px)` blieb auf einem 1440 px
     hohen Fenster die Buehne bei 1000 stehen, die Leiste stand mitten im
     Bild und darunter lagen 366 px leere Flaeche. Die Engine begrenzt die
     Seite ohnehin ueber `maxWidth`/`maxHeight`. */
  height: max(320px, calc(100dvh - var(--rahmen-hoehe)));
  /* Die Engine positioniert die nicht sichtbaren Seiten absolut; ohne
     Beschneidung ragen sie unter den Bildschirmrand und erzeugen eine
     Bildlaufleiste, obwohl nichts zu sehen ist. */
  overflow: hidden;
}

.katalog {
  flex: 1;
  min-width: 0;
  /* Feste Höhe statt Mindesthöhe: Die Engine liest sie aus und verkleinert
     die Seite, wenn sie sonst nicht hineinpasst. */
  height: 100%;
}

.katalog:focus-visible {
  outline-offset: 4px;
}

/* Zielgröße: 44 px an der Bühne, 30 px in der Leiste. WCAG 2.5.8 verlangt
   24 px — die Leiste bleibt darüber und gibt dem Katalog jede Höhe, die sie
   nicht selbst braucht. */
.blaettern {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--akzent);
  background: var(--grund);
  border: 1px solid var(--rand);
  border-radius: 50%;
  cursor: pointer;
}

.blaettern:hover,
.werkzeug:hover,
.werkzeug[aria-expanded='true'] {
  background: var(--akzent);
  color: #fff;
  border-color: var(--akzent);
}

/* Dieselben Knöpfe noch einmal in der Leiste, kleiner und ohne Rand — die
   großen am Bühnenrand bleiben der Hauptweg. */
.blaettern.klein {
  width: 30px;
  height: 30px;
  border-color: transparent;
  background: none;
}

.blaettern:disabled,
.blaettern.klein:disabled {
  color: var(--rand);
  cursor: default;
  background: none;
  border-color: transparent;
}

/* Jedes Zeichen ist gezeichnet, keine Icon-Schrift. Strich statt Fläche, damit
   die Farbe aus dem Knopf kommt. */
.blaettern svg,
.werkzeug svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.seite {
  background: var(--grund);
}

.seite img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.leiste {
  padding: 0 1.25rem;
  color: var(--gedaempft);
  font-size: 0.9rem;
}

.leiste {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--rand);
}

.leiste p {
  margin: 0;
}

.leiste-gruppe {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  /* Beide äußeren Gruppen gleich breit, damit die Seitenzahl wirklich mittig
     steht und nicht mit der Zahl der Werkzeuge wandert. */
  flex: 1 1 0;
}

.leiste-gruppe:last-child {
  justify-content: flex-end;
}

.leiste-mitte {
  flex: 0 0 auto;
  justify-content: center;
}

.seitenstand {
  min-width: 7.5rem;
  text-align: center;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* Werkzeuge links und rechts: Zielgröße 44 px, Beschriftung nur für
   Screenreader — der Titel erscheint als Tooltip. */
.werkzeug {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  color: var(--akzent);
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
}

.werkzeug-text {
  font-size: 1.15rem;
  font-weight: 700;
}

/* --- Inhaltsverzeichnis --------------------------------------------------- */

.panel {
  border-top: 1px solid var(--rand);
  background: var(--grund);
  max-height: 40dvh;
  overflow-y: auto;
}

/* Die Trefferliste schwebt unter dem Suchfeld, statt das Layout zu schieben. */
.suche-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 20;
  width: min(30rem, 90vw);
  padding: 0.75rem 1rem;
  border: 1px solid var(--rand);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
  max-height: 60dvh;
}

.eintrag-liste {
  margin: 0;
  padding: 0.5rem 0;
  list-style: none;
}

.eintrag {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  /* 44 px Zielgröße, auch wenn der Text nur eine Zeile hoch ist. */
  min-height: 44px;
  padding: 0.5rem 1.5rem;
  font: inherit;
  text-align: left;
  color: var(--text);
  background: none;
  border: 0;
  cursor: pointer;
}

.suche-panel .eintrag {
  padding-inline: 0;
  align-items: start;
}

.eintrag:hover {
  background: #f2f6fa;
  color: var(--akzent);
}

.eintrag-label {
  flex: 1;
  min-width: 0;
  line-height: 1.4;
}

.eintrag-seite {
  flex: 0 0 auto;
  color: var(--gedaempft);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.eintrag:hover .eintrag-seite {
  color: inherit;
}

.suche-feld {
  width: min(18rem, 40vw);
  min-height: 32px;
  padding: 0 0.75rem;
  font: inherit;
  color: var(--text);
  background: var(--grund);
  border: 1px solid var(--rand);
  border-radius: 6px;
}

.suche-feld:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 1px;
}

.suche-stand {
  margin: 0;
  font-size: 0.9rem;
  color: var(--gedaempft);
}

.nur-screenreader {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.fehler,
.hinweis-noscript {
  margin: 1rem 1.5rem;
  padding: 1rem;
  border-left: 4px solid #b3261e;
  background: #fdeceb;
  color: #410e0b;
}

@media (max-width: 700px) {
  /* Auf dem Telefon ist kein Platz für drei Dinge im Kopf. Der Titel steht
     ohnehin im <title> des Dokuments. */
  .kopf-titel {
    display: none;
  }

  .suche-feld {
    width: min(12rem, 45vw);
  }

  /* Zehn Knöpfe passen auf 390 px nicht in eine Zeile — die Leiste brach auf
     drei um und schob die Seite aus dem Bild. Erste und letzte Seite fallen
     deshalb weg; Pos1 und Ende leisten dasselbe, und die großen Pfeile am
     Bühnenrand bleiben. */
  .blaettern[data-richtung='erste'],
  .blaettern[data-richtung='letzte'] {
    display: none;
  }

  /* Auch zu acht passen die Knöpfe auf 390 px nicht nebeneinander — gemessen
     ragte die rechte Gruppe 69 px hinaus. Die Seitennavigation bekommt
     deshalb eine eigene Zeile, die Werkzeuge teilen sich die zweite. */
  .leiste {
    flex-wrap: wrap;
    padding-inline: 0.5rem;
  }

  /* Zwei Zeilen Leiste statt einer: der Bühne steht entsprechend weniger zu,
     sonst scrollt die Seite um die zweite Zeile. Gemessen 60 + 107 px. */
  :root {
    --rahmen-hoehe: 7.5rem;
  }

  .leiste-mitte {
    order: -1;
    flex: 1 0 100%;
  }

  .seitenstand {
    min-width: auto;
    font-size: 0.85rem;
  }

  .buehne {
    flex-wrap: wrap;
  }

  .katalog {
    order: -1;
    flex-basis: 100%;
  }

  .blaettern {
    flex: 1;
    border-radius: 6px;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* --- Vergrößerte Ansicht ------------------------------------------------
   Der Dialog füllt den Bildschirm; geschoben wird im Scroll-Container, damit
   Tastatur, Wischgeste und Systemzoom weiter funktionieren. */
/* Die Klassenregel schlaegt die Browser-Regel fuer `dialog:not([open])` —
   ohne das Gegenstueck steht der geschlossene Dialog sichtbar unter der Seite. */
.zoom:not([open]) {
  display: none;
}

.zoom {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--grund);
  display: flex;
  flex-direction: column;
}

.zoom::backdrop {
  background: rgb(0 0 0 / 70%);
}

.zoom-leiste {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--rand);
}

.zoom-stand {
  flex: 1;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.zoom-stufe,
.zoom-schliessen {
  min-height: 44px;
  padding: 0 0.9rem;
  font: inherit;
  color: var(--akzent);
  background: var(--grund);
  border: 1px solid var(--rand);
  border-radius: 6px;
  cursor: pointer;
}

.zoom-stufe[aria-pressed='true'],
.zoom-stufe:hover,
.zoom-schliessen:hover {
  background: var(--akzent);
  color: #fff;
  border-color: var(--akzent);
}

.zoom-buehne {
  flex: 1;
  display: flex;
  gap: 2px;
  align-items: center;
  justify-content: center;
  overflow: auto;
  padding: 1rem;
  background: #1c1c1c;
  cursor: grab;
}

.zoom-buehne.zieht {
  cursor: grabbing;
}

/* Das Seitenbild darf nicht selbst ziehbar sein — sonst übernimmt das
   Drag-and-Drop des Browsers und das Schieben endet nach wenigen Pixeln. */
.zoom-buehne img {
  -webkit-user-drag: none;
  user-select: none;
}

/* Bei „passend" liegt das Bild in der Mitte; sobald vergrößert wird, setzt JS
   eine feste Breite und der Container scrollt. `align-items: start` verhindert,
   dass das überhohe Bild oben abgeschnitten und unerreichbar wird. */
.zoom-buehne[data-stufe='passend'] img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
}

.zoom-buehne:not([data-stufe='passend']) {
  align-items: start;
  justify-content: start;
}

.zoom-buehne:not([data-stufe='passend']) img {
  max-width: none;
  max-height: none;
  flex: 0 0 auto;
}

@media (prefers-reduced-motion: reduce) {
  .zoom-buehne {
    scroll-behavior: auto;
  }
}

/* --- Anklickbares Verzeichnis auf der Seite ----------------------------
   Unsichtbar, bis jemand darauf zeigt — die gedruckte Seite soll aussehen wie
   gedruckt. Die Bandhöhe ist die der Verzeichniszeile und damit kleiner als
   die sonst üblichen 44 px; größer ginge nur auf Kosten des Nachbarn. Wer
   genauer treffen will, vergrößert. */
.seite {
  position: relative;
}

.verweis {
  position: absolute;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 2px;
  cursor: pointer;
  transition: background-color 0.12s ease-in-out;
}

.verweis:hover,
.verweis:focus-visible {
  background: color-mix(in srgb, var(--akzent) 22%, transparent);
}
