/* ============================================================
   DESIGN 57 – Veröffentlichungsreif
   ------------------------------------------------------------
   1. Der Knopf ins Design-Archiv ist weg. Dahinter lagen 74
      Entwürfe und Labore – nichts für eine offene Seite.

   2. Die Fußzeile trägt Impressum und Datenschutz. Beide sind in
      Deutschland Pflicht und müssen von jeder Seite aus
      erreichbar sein.

   3. Die drei Featured-Karten öffnen dasselbe Werk-Fenster wie
      alles andere – der dritte Bereich derselben Maschine, kein
      neues Bauteil. Vorerst mit Platzhaltern.

   DESIGN 56 – Eigene Schriften
   ------------------------------------------------------------
   1. Die Schriften kommen nicht mehr von Google, sondern aus
      assets/fonts/. Sonst ginge die IP jedes Besuchers an Google –
      ohne Einwilligung ein DSGVO-Verstoß.
   2. Der Lebenslauf ist von der Seite genommen. Er enthält
      Anschrift und Telefonnummer; auf einer offenen Seite ist das
      für jeden abrufbar.
   3. Die Platzhaltertexte sprechen Englisch, und die Seite hat
      eine Teilen-Vorschau.

   DESIGN 55 – Rechtehinweis
   ------------------------------------------------------------
   Unter den beiden Auftragskarten steht jetzt eine Zeile: Die
   Arbeiten sind im Angestelltenverhältnis entstanden, die Rechte
   liegen bei den Unternehmen und Lizenzgebern.

   UNTER den Karten und nicht darin – er gilt für beide Stellen,
   und im Fließtext einer Karte läse er sich wie eine
   Entschuldigung. Als Fußnote ist er das, was er ist: eine
   Angabe.

   DESIGN 54 – Lebenslauf und Auftragsarbeiten
   ------------------------------------------------------------
   1. Der CV-Knopf steht in der KOPFZEILE der Laufbahn, nicht
      unter der Liste. Die Zeile „Career" ist ohnehin da – der
      Knopf kostet dort nur die Differenz zur Texthöhe (21px
      statt 58px). Die Kästen wachsen also fast nicht.

   2. Die beiden Auftragskarten öffnen DASSELBE Werk-Fenster wie
      die persönlichen Arbeiten. Kein zweiter Betrachter, keine
      zweite Galerie – nur eine zweite Liste (data/auftrag.json
      aus assets/auftrag/, siehe tools/build_werke.py).

   3. „Details →" führte bis hierher ins Leere. Es erscheint jetzt
      erst, wenn wirklich etwas dahinterliegt – und sagt dann, wie
      viel.

   DESIGN 53 – Weißer Rahmen um jede Arbeit
   ------------------------------------------------------------
   Jede Arbeit steht jetzt in einem weißen Rahmen – als Kachel im
   Werk-Fenster und in der großen Ansicht. 2px, wie jeder andere
   Rahmen der Seite, als eine Variable --mass-bild-rahmen.

   Der Rahmen sitzt bei der Kachel auf der KACHEL und nicht auf
   dem Bild: Der Titel liegt beim Darüberfahren als Band über dem
   unteren Bildrand und würde den Rahmen sonst durchschneiden.

   DESIGN 52 – Skills nach ihren Angaben, und nichts wächst
   ------------------------------------------------------------
   1. Elf Skill-Karten nach ihren eigenen Angaben. Content
      Marketing raus, Word und PowerPoint dazu.

   2. DIE KÄSTEN WACHSEN NICHT. Zwei Stellen drohten das:
      – Die Laufbahn hat seit Design 51 eine dritte Zeile je
        Station, rund 102px. An vier Stellen gegengerechnet,
        bleiben 26px.
      – Die Skill-Karten waren in Design 51 von 215 auf 260px
        gewachsen. Zurück auf 215px, sechs Spalten.

   3. Die Rückseite wiederholt den Kartennamen nicht mehr. Er
      kostete zwei Drittel des Platzes und sagte nichts, was die
      Vorderseite nicht schon gesagt hat.

   DESIGN 51 – Jahreszahl oben, Skills durchgesehen
   ------------------------------------------------------------
   1. Die Jahreszahl steht ÜBER der Position (Fassung B aus dem
      Datum-Labor). Sie stand zweimal am Ende der Zeile und ging
      beide Male unter – und sie nahm der Position rund 85px weg,
      weshalb „Marketing Manager & Graphic Designer" umbrach.
      Ohne dritte Spalte bricht nichts mehr.

   2. Skills: zwölf Karten wurden zehn. Notion und Meta Business
      Suite raus, Campaign Planning raus (nie ihre Aufgabe), an
      dessen Stelle Email Marketing – das steht in ihrer eigenen
      FOCUS-Zeile. Alle Rückseiten überarbeitet.

   3. Fünf Spalten statt sechs. Zehn Karten gehen dann glatt auf.

   DESIGN 50 – Der Brief wird schneller
   ------------------------------------------------------------
   Nur eine Änderung, und sie steht nicht hier, sondern in
   tools/build_brief.py: Der Umschlag bewegt sich in 60 ms je
   Bild statt in 90, die beiden Ruhezeiten sind kürzer.

   Ein Durchlauf dauert 3,68 s statt 5,12 s, die Bewegung selbst
   0,48 s statt 0,90 s – fast doppelt so schnell.

   Bewegung und Ruhe sind ZWEI Zahlen, weil sie zwei verschiedene
   Dinge tun: die eine, wie flüssig es wirkt; die andere, wie oft
   es wiederkommt.

   DESIGN 49 – Ruhiges Mauerwerk
   ------------------------------------------------------------
   1. Die Kacheln im Werk-Fenster springen nicht mehr seitwärts.
      Ursache waren CSS-Spalten (columns): Der Browser VERTEILT
      dort selbst und rechnet neu, sobald eine Höhe dazukommt –
      bei nachgeladenen Bildern also dauernd. Jetzt drei echte
      Spalten, und das Skript verteilt einmal, aus den Maßen in
      der Werkliste.

   2. Leiste und Bildraster stehen auf derselben Kante
      (--mass-fenster-polster). Die Leiste stand auf 1rem, die
      Bilder auf 2,2rem – seit die Leiste Knöpfe trägt, sieht man
      das.

   3. Die Blätterpfeile hören 40rem aus der Mitte auf, statt am
      Bildschirmrand zu kleben. Auf einem 2560er Monitor lagen
      sie über tausend Pixel neben dem Bild.

   4. Es gibt genau EINE Kastenfarbe: --bg-2. Das Kästchen im
      Hero war eine Spur heller – Rest der halbdurchsichtigen
      Fassung, die bis Design 46 dort stand.

   DESIGN 48 – Eine Leiste, richtige Knöpfe
   ------------------------------------------------------------
   1. Das Werk-Fenster hat nur noch EINE Leiste. Die Filter sind
      hineingewandert, der Titel weicht ihnen (er wiederholte nur
      die angeklickte Karte). 183px über dem ersten Bild werden
      zu 100px.

   2. Der kleine Knopf hielt sich nicht an das Gesetz des großen:
      Sein Sockel war 16 bei Druckweg 4 statt 12. Er gab dadurch
      weniger nach und bewegte sich sichtbar anders. Jetzt
      40/28/4 – Sockel 12 = 3 × Druck, wie beim großen.

   3. Und hier lag der eigentliche Fehler im Labor: In einer Zeile
      mit align-items:center schrumpft ein Knopf um seine MITTE.
      Er muss aber von oben nachgeben, die Unterkante steht.

   DESIGN 47 – Was dahinter liegt, bleibt dahinter
   ------------------------------------------------------------
   Zwei Stellen, an denen etwas durchschien, das nicht sollte.
   Beide hatten dieselbe Ursache in zwei Ausprägungen: Ein Kasten
   verdeckt nur, was er wirklich verdeckt.

   1. Das Kästchen im Hero war halbdurchsichtig (4 % Weiß). Die
      Bildröhrenzeilen lagen nie davor – das Kästchen war nur nie
      da. Jetzt undurchsichtig, in genau der Farbe, die vorher
      herauskam.

   2. Die Linie der Laufbahn lief durch die Kästchen. Die Farbe
      stimmte, aber die Linie ist POSITIONIERT und wird deshalb in
      einem späteren Durchgang gemalt als ein nicht positionierter
      Untergrund. position:relative bringt beide in denselben.

   DESIGN 46 – Verlauf und Heranfahren
   ------------------------------------------------------------
   Die Vorschaubilder tragen keinen Filter mehr, sondern eine
   ÜBERLAGE: einen Verlauf von unten. Ein Filter verändert die
   Farben des Bildes selbst und kann schmutzig wirken – eine
   Überlage nimmt nur Licht weg und kann es nicht.

   Beim Darüberfahren weicht der Verlauf zurück und das Bild
   rückt eine Spur näher (1.05).

   DESIGN 45 – Der Brief wird plastisch
   ------------------------------------------------------------
   Der Umschlag war flach, weil seine Fläche EINE Farbe war –
   Konturen und Kanten ändern daran nichts. Jetzt liegt ein
   gerasterter Verlauf darin (Schachbrett zwischen den Tönen),
   die Lasche hat einen eigenen Verlauf, und darunter liegt ein
   versetzter Wurfschatten.

   Alles Weitere in tools/build_brief.py.

   DESIGN 44 – Der Brief ohne Kontur
   ------------------------------------------------------------
   Der Umschlag hat keine dunkle Kontur mehr und trägt die
   gestuften Ecken der Knöpfe. Die Form entsteht allein aus Licht
   und Schatten – dieselbe Bauart wie die Knöpfe der Seite, die
   mit --btn-rand:0px ebenfalls ohne Kontur stehen.

   Alles Weitere in tools/build_brief.py.

   DESIGN 43 – Datum und Farbe
   ------------------------------------------------------------
   1. Das Jahr steht in einer eigenen Spalte, nicht mehr am Ende
      der Ortszeile – dort ging es unter.
   2. Kein Sepiaton mehr auf den Vorschaubildern. Nur noch
      zurückgenommene Sättigung: Die Farben bleiben die eigenen,
      sie treten nur zurück. Ein Braunstich sah schmutzig aus.
   3. Der Umschlag: Ruhezustand zurück auf das X aus Design 41,
      und die Lasche ist rund statt nadelspitz.

   DESIGN 42 – Laufbahn ausgerichtet
   ------------------------------------------------------------
   1. Punkte und Linie der Laufbahn sitzen jetzt ausgerechnet
      aufeinander statt auf geschätzten Pixelwerten.
   2. Position zuerst, Arbeitgeber und Jahr in der Zeile darunter.
   3. Zwei weitere Stationen (Brink's Treff, RISE | FX).
   4. Der Brief bewegt sich durchgehend statt in Sprüngen –
      siehe tools/build_brief.py.

   DESIGN 41 – Laufbahn
   ------------------------------------------------------------
   1. Die Statuskarte ist einer Laufbahn gewichen – dem einzigen,
      was auf der Seite wirklich fehlte. Die knappen Angaben
      stehen jetzt im Terminal daneben.
   2. Der Brief ist auf 32×32 neu gezeichnet: fünf Farbtöne statt
      zwei, Schrägen in Einerschritten. Anzeige 64px.

   DESIGN 40 – Der Brief öffnet sich
   ------------------------------------------------------------
   1. Der Umschlag dreht sich nicht mehr, er ÖFFNET sich und
      schiebt einen Zettel heraus – nach einer Skizze der
      Nutzerin. 24×24 statt 16×16, weil der Zettel Platz braucht.
   2. Die Blätterpfeile sind ausgefüllte Dreiecke.
   3. „Industries" ersetzt durch „Beyond work".

   DESIGN 39 – Der Brief im Coin-Stil
   ------------------------------------------------------------
   Der Umschlag ist neu gebaut: acht Bilder, dieselbe Technik und
   derselbe Takt wie der Coin. Der Postkasten und der Flug sind
   entfallen – zwei Bewegungen für eine Aussage waren zu viel.
   Dazu die Kontaktzeile umgestellt: Die Offenheit für andere
   Bereiche steht jetzt vorn.

   DESIGN 38 – Der Brief
   ------------------------------------------------------------
   Im Kontaktabschnitt steht nicht mehr der Coin, sondern ein
   Umschlag, der in einen Postkasten fällt. Der Coin gehört an
   den Eingang – dort ist er der Einwurf, der die Seite startet.
   Am Ende der Seite geht es ums Schreiben, nicht ums Starten.

   DESIGN 37 – Englisch und Mauerwerk
   ------------------------------------------------------------
   1. Die Seite spricht Englisch. lang="en".
   2. Die Galerie ist ein Mauerwerk – nichts wird mehr zugeschnitten.
   3. Echte Inhalte: Statuskarte, Bio, Schwerpunkte, beide
      Auftragsarbeiten aus dem Lebenslauf.
   4. Neue Ausrichtung im Kontaktabschnitt: Es geht um eine feste
      Position, nicht um freie Projekte.

   DESIGN 36 – Inhalte
   ------------------------------------------------------------
   Diese Variante sammelt die ECHTEN Angaben der Nutzerin und
   ersetzt Platzhalter. Sie bleibt offen, solange Inhalte
   nachkommen, und wird eingefroren, sobald nichts mehr fehlt –
   eine bewusste Ausnahme von der Snapshot-Regel, weil es sonst
   für jede einzelne Zeile eine eigene Variante bräuchte.

   Bereits eingesetzt:
     E-Mail    isabelle.jarugski@gmail.com
     LinkedIn  linkedin.com/in/isabelle-jarugski

   Noch offen: siehe die Notiz zu Design 36.

   DESIGN 35 – Space Grotesk
   ------------------------------------------------------------
   DREI SCHRIFTEN MIT KLAREN AUFGABEN:

     Space Grotesk    LIEST    – alles, was man liest oder anklickt:
                                 Überschriften, Kartentitel, Fließtext,
                                 Knöpfe, Navigation, Formular.
     JetBrains Mono   BESCHRIFTET – nur noch technische Kleinteile:
                                 Terminal, Marken, Zähler, Schlagworte.
     Press Start 2P   SIGNIERT – vier Stellen, unverändert.

   Inter fällt ganz weg. Sie stand nur an einer einzigen Stelle
   (body) und wurde von zwei anderen Schriften ohnehin überdeckt.
   JetBrains Mono trug vorher 38 Regeln und war damit heimlich die
   Grundschrift der Seite – das war das, was neben Space Grotesk
   nicht mehr passte.

   DESIGN 34 – Ruhe
   ------------------------------------------------------------
   1. PIXELSCHRIFT NUR NOCH ALS SIGNATUR – vier Stellen statt
      siebzehn. Sie war zu mächtig und unangenehm zu lesen.
      Überschriften und Kartentitel tragen jetzt JetBrains Mono.
   2. Navigation fährt beim Herunterscrollen weg.
   3. Vorschaubilder der Karten entfärbt, Farbe beim Darüberfahren.
      NUR auf den Karten – im Werk-Fenster ist die Farbe die Arbeit.
   4. Die Galerie im Fenster bekommt Luft: größere Kacheln,
      größere Abstände, keine Konturen, Titel erst beim Hovern.

   Sterne und Bildröhre bleiben – beides ausdrücklich gewünscht.

   DESIGN 33 – Bildröhre
   ------------------------------------------------------------
   Die Zeilen und der Randschein vom Eingangsbildschirm liegen
   jetzt über der ganzen Seite – aber HINTER allem, nicht darüber.
   Sie scheinen dort durch, wo der Untergrund frei liegt, und
   verschwinden hinter Karten, Navigation und Arbeiten.

   DESIGN 32 – Der Einwurf, fein justiert
   ------------------------------------------------------------
   1. Die Münze fällt jetzt wirklich IN den Schlitz, statt oben
      auf dem Deckel liegen zu bleiben.
   2. Der helle Rahmen um Münze und Box ist weg. Es war der
      Fokusring des Knopfes – beide sitzen im selben Knopf,
      deshalb umschloss er sie gemeinsam.

   DESIGN 31 – Die Schrift, wirklich diesmal
   ------------------------------------------------------------
   1. DIE URSACHE DER WEICHEN ÜBERSCHRIFTEN WAR font-weight.
      Überschriften sind <h2>/<h3> und damit vom Browser aus FETT.
      'Press Start 2P' hat aber nur einen Schnitt. Ohne fette
      Fassung fälscht der Browser sie, indem er die Buchstaben
      verschmiert – und genau das sah man.
      h1 war die einzige Stelle mit font-weight:400. Deshalb war
      ausgerechnet der Name im Hero scharf.
   2. Bilder in der Bildschau wieder ins Fenster eingepasst.
   3. Favicon unter neuem Dateinamen.
   4. Die drei Featured Projects sind von IQ Technologies.

   DESIGN 30 – Schrift wirklich scharf, ruhige Bildgröße
   ------------------------------------------------------------
   1. Die Pixelschrift in den Abschnitten war weiterhin weich –
      nicht wegen der Kantenglättung, sondern weil jeder Abschnitt
      dauerhaft in einer eigenen Grafikebene hing. Erklärung unten
      bei .reveal.
   2. Kein Aufblitzen mehr nach dem Münzeinwurf.
   3. Bilder in der Bildschau starten in einer ruhigen Spaltenbreite
      statt fensterfüllend. Originalgröße bleibt einen Klick entfernt.

   DESIGN 29 – Einwurf, scharfe Pixelschrift, Bilder in Originalgröße
   ------------------------------------------------------------
   1. „Insert Coin to Continue" als Eingangsbildschirm. Aus dem
      Coin-Labor übernommen, Fassung B – aber ohne den sichtbaren
      Rahmen und mit einer Box statt eines flachen Schlitzes.
   2. Pixelschrift ist überall gestochen scharf. Es fehlte
      -webkit-font-smoothing:none an allen Stellen außer dem Logo.
   3. Die Bildschau zeigt Bilder in ihrer eigenen Größe und lässt
      scrollen, statt sie ins Fenster zu quetschen.

   DESIGN 28 – Menü, festes Fenstermaß, vier Kategorien
   ------------------------------------------------------------
   1. Navigation auf schmalen Fenstern als aufklappbares Menü.
      Die Leiste passte nicht mehr und lief aus dem Bild.
   2. Das Werk-Fenster hat jetzt IMMER dieselbe Größe, egal welche
      Kategorie und welcher Filter. Vorher richtete es sich nach
      dem Inhalt und sprang bei jedem Wechsel.
   3. Vier Kategorien statt fünf (Digital Art + Traditional
      Drawings = Drawings). Damit passt ein Raster aus zwei
      Spalten – die breitgezogene erste Karte entfällt.
   4. Auftragsarbeiten: zwei Karten.

   DESIGN 27 – Zoom und richtige Druckbewegung
   ------------------------------------------------------------
   1. Die Knöpfe drücken jetzt überall gleich. Ein Arcade-Knopf
      wird beim Drücken flacher; damit das nach „gedrückt" aussieht,
      muss seine UNTERKANTE stehen bleiben. Dafür sitzt jeder Knopf
      in einem Halter fester Höhe (.knopf-halter). Vorher schrumpfte
      in der Titelleiste stattdessen die Leiste selbst mit – und das
      ganze Fenster sprang.
   2. Zoom in der Bildschau: Knöpfe, Mausrad, Doppelklick, Ziehen.
      Am Handy Aufziehen mit zwei Fingern und Doppeltippen.
   3. Bilder werden in voller Auflösung aufbereitet (siehe
      tools/build_werke.py, FASSUNG 2).

   DESIGN 26 – Filter und Arcade-Knöpfe
   ------------------------------------------------------------
   1. Bilder überlagerten sich beim schnellen Blättern. Ursache
      war die Blende am Bild: Sie lief noch, während schon das
      nächste Bild eingesetzt wurde. Jetzt wird nach dem Dekodieren
      hart getauscht – ohne Lücke, weil vorgeladen wird.
   2. Filterzeile im Fenster, gespeist aus Unterordnern.
   3. Die eckigen Behelfsknöpfe sind weg. Übersicht, Schließen,
      Blättern und Filter benutzen jetzt das Buttonsystem der
      Seite (.btn .btn-sm) – dieselbe Form wie „Contact me".

   DESIGN 25 – Bildschau
   ------------------------------------------------------------
   1. Das einzelne Werk wird nicht mehr im Fenster gezeigt, sondern
      formatfüllend in einer eigenen Ebene. Das Raster bleibt im
      Fenster – das war der Teil, der gefallen hat.
   2. Das Aufblitzen beim Blättern ist weg. Zwei Ursachen:
      die Bühne hatte keine feste Höhe und fiel beim Wechsel
      zusammen, und jeder Blätterschritt baute den gesamten Inhalt
      samt Vorschaustreifen neu auf.
   3. Wischen auf dem Handy.

   DESIGN 24 – Werke
   ------------------------------------------------------------
   1. Das Skript liegt jetzt in script.js statt im HTML – aus
      demselben Grund, aus dem auch das CSS eine eigene Datei hat.
   2. Die Galerie ist in zwei benannte Blöcke geteilt:
      Auftragsarbeiten (drei Karten) und Persönliche Arbeiten
      (fünf Kategorien, aus data/werke.json geladen).
   3. Die Filterzeile ist weg. Zwei überschriebene Blöcke sagen
      dasselbe, ohne dass man erst etwas anklicken muss.
   4. Neu: das Werk-Fenster.

   DESIGN 23 – Platzhalterbild in den Karten
   ------------------------------------------------------------
   Statt sechs Farbverläufen liegt jetzt in jeder Karte das
   Platzhalterbild des Nutzers (Dazai-bg.png), damit sichtbar wird,
   wie die Karten mit einem echten Bild wirken.

   Jede Karte hat ZWEI übereinanderliegende Hintergründe:
     1. das Platzhalterbild (dummy-thumb.webp)
     2. der Farbverlauf                  – letzte Rückfallebene

   NACHTRAG 2026-08-30: Davor stand als erste Stufe `project-N.jpg`.
   Diese Dateien hat es nie gegeben, und der Browser fragte sie bei
   jedem Aufruf vergeblich an. Das echte Vorschaubild kommt inzwischen
   aus der Werkliste, siehe --cover weiter unten.

   DESIGN 22 – Maßstab ohne Einrasten
   ------------------------------------------------------------
   Das Einrasten aus Design 21 ist wieder raus. Es sprang, und ein
   Sprung ist das Gegenteil von dem, was hier gewollt ist. Die Seite
   scrollt wieder frei; Abschnitte blenden nur noch ein und aus.

   Der Maßstab aus Design 21 BLEIBT – das war der Teil, der funktioniert
   hat, und er gilt weiterhin für jede Auflösung.

   Optimiert wurde das Ein- und Ausblenden an zwei Stellen:
     1. Sichtlinien wieder auf freies Scrollen abgestimmt (0,88 / 0,08).
        Die 0,75 aus Design 21 waren nur sinnvoll, solange die Abschnitte
        einrasteten.
     2. NEU – Nachlauf: Ein sichtbarer Abschnitt bleibt sichtbar, bis er
        einen deutlich weiteren Rahmen verlässt. Ohne das kippt ein Block,
        der genau auf der Linie steht, bei jedem Mausrad-Zucken hin und
        her. Genau dieses Zucken hat sich als „Flackern" angefühlt.

   DESIGN 21 – Maßstab (übernommen)
   ------------------------------------------------------------
   1. DER MASSSTAB HÄNGT JETZT AN DER FENSTERBREITE.
      Auf 2560px wirkte die Seite ruhig, auf 1920px zu groß – die
      Maße waren feste Pixel, das Fenster aber ein Drittel schmaler.
      Alle Größen stehen deshalb als --mass-* im :root und werden
      unter 1920px einmal gemeinsam eine Stufe kleiner gesetzt.
      Das ist Design 20 – nur nicht mehr als eigene Fassung,
      sondern als zweite Stufe derselben Seite.

   DESIGN 19 – Ruhiges Einblenden
   ------------------------------------------------------------
   Das Flackern kam von der schieren MENGE animierter Elemente:
   elf Blöcke, darunter die Galerie mit sechs Bildkacheln, wurden
   beim Scrollen ständig ein- und ausgeblendet. Jeder davon musste
   dafür als eigene Grafikebene gezeichnet werden.

   Jetzt blenden nur noch die fünf ABSCHNITTE als Ganzes ein.
   Da sie hoch sind, bleiben sie lange sichtbar und schalten selten –
   das ist der eigentliche Grund für die Ruhe.
   Zusätzlich: kürzerer Weg, kürzere Dauer, spätereres Ausblenden.

   Aus Design 14 übernommen:
     1. Pixelschrift nur in Vielfachen von 8px
     2. Hero-Innenabstand oben und unten gleich, größer als die Navbar
     3. Überschrift nach Zeilenlänge bemessen, nicht nach Gefühl

   Aus Design 06/07 übernommen:
     - Schein des Kreises enger und kräftiger
     - Kreis kleiner: Schädel ragt oben heraus, Unterkante hinter den Steinen
     - Steine sitzen jetzt wirklich auf der Button-Linie
     - „Insert Coin" blinkt wieder; die Laola-Welle wanderte auf die
       kleinen Überschriften über den Abschnitten
     - drehender Pixel-Coin im Kontaktbereich
   Aufbau: Hero · Featured · About · Skills · Galerie · Kontakt

   Formensprache (aus dem Original abgeleitet, siehe Obsidian):
     - Flächen sind eckig
     - gestufte Pixelecken NUR bei Drückbarem (Buttons, Filter)
     - Markenfarben #A35E46 / #F1B184, weiche Verläufe
     - minimalistisch: vorhandene Elemente stärken statt neue stapeln
   ============================================================ */

/* ============================================================
   DIE SCHRIFTEN - SELBST AUSGELIEFERT
   ------------------------------------------------------------
   Bis Design 55 lud die Seite sie von fonts.googleapis.com. Damit
   ging die IP-Adresse jedes Besuchers an Google, und das ist ohne
   Einwilligung ein DSGVO-Verstoss - das Landgericht Muenchen hat
   das 2022 so entschieden. Es ist die bekannteste Abmahnwelle der
   letzten Jahre gegen kleine Websites.

   Jetzt liegen die Dateien unter assets/fonts/ (26 Stueck, 364 KB
   zusammen). Niemand ausser dem eigenen Server erfaehrt noch, dass
   jemand die Seite besucht.

   WARUM 26 DATEIEN UND NICHT DREI
   Jede Schrift ist nach Schriftsystem zerlegt - Latein, Latein
   erweitert, Kyrillisch, Griechisch, Vietnamesisch. Der Browser holt
   nur, was auf der Seite wirklich vorkommt; die unicode-range in
   jeder Regel sagt ihm, welche Zeichen darin stehen. Das ist genau
   die Aufteilung, die Google selbst ausliefert.

   font-display:swap - der Text erscheint sofort in einer Ersatz-
   schrift und wird ausgetauscht, sobald die eigene da ist. Ohne das
   bliebe die Seite kurz leer.

   SPACE GROTESK HAT KEIN KYRILLISCH. Zwei Werktitel der Nutzerin
   stehen kyrillisch da. Sie werden in einer Systemschrift gesetzt -
   das war mit Google genauso, es ist keine Verschlechterung.
   ============================================================ */

@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-500-cyrillic-ext.woff2') format('woff2');
  unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-500-cyrillic.woff2') format('woff2');
  unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-500-greek.woff2') format('woff2');
  unicode-range:U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-500-vietnamese.woff2') format('woff2');
  unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-500-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-500-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-700-cyrillic-ext.woff2') format('woff2');
  unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-700-cyrillic.woff2') format('woff2');
  unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-700-greek.woff2') format('woff2');
  unicode-range:U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-700-vietnamese.woff2') format('woff2');
  unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/jetbrains-mono-700-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Press Start 2P';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/press-start-2p-400-cyrillic-ext.woff2') format('woff2');
  unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face{
  font-family:'Press Start 2P';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/press-start-2p-400-cyrillic.woff2') format('woff2');
  unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face{
  font-family:'Press Start 2P';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/press-start-2p-400-greek.woff2') format('woff2');
  unicode-range:U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face{
  font-family:'Press Start 2P';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/press-start-2p-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Press Start 2P';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/press-start-2p-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-400-vietnamese.woff2') format('woff2');
  unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-400-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-400-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-500-vietnamese.woff2') format('woff2');
  unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-500-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:500;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-500-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-700-vietnamese.woff2') format('woff2');
  unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-700-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url('assets/fonts/space-grotesk-700-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root{
  --bg: #08080b;
  --bg-2: #0c0c11;
  --text: #f6f6f8;
  --text-dim: #96969f;

  /* Markenfarben, vom Nutzer festgelegt – siehe Notiz „07 Farbpalette" */
  --brand-dark:  #A35E46;
  --brand-light: #F1B184;
  --brand-mid:   #C9825F;
  --brand-deep:  #6B3B2C;
  --brand-ink:   #8A4A34;
  --accent: var(--brand-light);

  /* Dieselbe Farbe wie jeder andere Kasten der Seite. Bis Design 48
     war das Kaestchen im Hero eine Spur heller (#121215) - Rest der
     halbdurchsichtigen Fassung, die davor dort stand.
     ES GIBT JETZT GENAU EINE KASTENFARBE: --bg-2. */
  --badge-bg: var(--bg-2);
  --badge-border: rgba(255,255,255,0.09);

  --riser-primary: var(--brand-deep);
  --riser-secondary: #b98a6d;
  --riser-social: #0e0e12;
  --outline: #2a1712;

  /* ---- Buttonmaße ----
     Alle Maße der Buttons hängen an diesen sechs Werten. Wer die Größe
     ändern will, ändert hier – Zeilenhöhen, Druckweg und Kappe ziehen
     automatisch mit. Vorher standen die Werte an neun Stellen verstreut.
       Höhe   = Ruhezustand
       Kappe  = farbige Fläche oben (der Rest ist der sichtbare Sockel)
       Druck  = wie viel die Höhe je Stufe abnimmt (Hover, gedrückt) */
  /* Nur die Höhen verkleinert (66 -> 56, Kappe 46 -> 38).
     Die BREITE hängt an font-size und padding des .btn-face – beides
     unverändert, damit die Buttons genauso breit bleiben wie zuvor. */
  /* ---- MASSSTAB ----
     Diese Werte gelten für breite Fenster (über 1920px). Weiter unten
     im Abschnitt ANPASSUNGEN werden sie unter 1920px alle gemeinsam
     eine Stufe kleiner gesetzt – an genau EINER Stelle.

     Wer die ganze Seite größer oder kleiner will, ändert hier.
     Zwei Regeln dabei beachten:
       - Pixelschrift ('Press Start 2P') nur in Vielfachen von 8px
       - Pixelgrafiken nur in Vielfachen ihrer Grundgröße
         (Coin 16px, Skelett 230px) */
  --mass-abschnitt:      7rem;    /* Abstand oben/unten je Abschnitt */
  --mass-breite:         1400px;  /* Textbreite der Abschnitte */
  --mass-kopf:           3rem;    /* Abstand unter der Überschrift */

  /* ---- ABSTAENDE: zwei Zahlen fuer zwei Situationen ----
     Vorher standen dafuer acht verschiedene Werte in der Datei
     (1rem, .8rem, 1.1rem, 1.6rem, 1.9rem ...), jeder einzeln
     gewachsen. Das Auge liest daraus keine Ordnung, sondern Zufall.

       eng   Was ZUSAMMENGEHOERT - eine Ueberschrift und ihr eigener
             Untertext. Sie sind EIN Gedanke, also duerfen sie sich
             beruehren.
       weit  Was GETRENNT ist - ein Block und der naechste.

     Wer die Seite luftiger oder enger will, aendert diese zwei. */
  --abstand-eng:          .5rem;
  --abstand-weit:        3.5rem;
  --mass-luecke:         1.75rem; /* Rasterabstand Featured und Galerie */
  --mass-feat-bild:      250px;
  --mass-feat-text:      1.5rem;
  /* SECHS Spalten. Bei elf Karten geht ohnehin nichts glatt auf, also
     zurueck auf die Breite von vor Design 51 - die Karten sollen nicht
     wachsen.
     Gerechnet: (Breite + Luecke) / (Mindestbreite + Luecke), abgerundet.
     FUENF Spalten bei zehn Karten - zwei volle Reihen.
       (1400 + 17,6) / (250 + 17,6) = 5,30 -> 5   ->  5 + 5 */
  --mass-skill-spalte:   250px;
  --mass-skill-luecke:   1.1rem;
  --mass-skill-hoehe:    78px;
  --mass-galerie-spalte: 300px;
  --mass-galerie-bild:   270px;
  --mass-bild-verlauf:    96px;   /* weiche Unterkante der Kartenbilder */
  --mass-galerie-text:   1.4rem;
  --mass-coin-polster:   3.5rem;
  --mass-brief:          64px;    /* Vielfaches von 32 */
  --mass-karte-polster:  1.75rem; /* Terminal und Statuskarte */
  /* Leiste UND Bildraster des Werk-Fensters. Eine Zahl, damit die
     Knoepfe oben und die Bilder darunter auf derselben Kante stehen. */
  --mass-fenster-polster: 2.2rem;
  --mass-flip-deckblatt: 168px;   /* Breite des Deckblatts im Banner */
  --mass-flip-ecke:       46px;   /* das Eselsohr am Deckblatt */
  --mass-abspielen:       64px;   /* die Marke auf einer Video-Kachel */
  /* Der weisse Rahmen um jede Arbeit - Kachel UND grosse Ansicht.
     2px wie jeder andere Rahmen der Seite. EINE Zahl fuer beide
     Stellen, damit sie nicht auseinanderlaufen koennen. */
  --mass-bild-rahmen: 1px;

  --btn-h: 56px;
  --btn-face: 38px;
  --btn-press: 6px;

  /* Der SOCKEL (Hoehe minus Kappe) ist dreimal der Druckweg - genau wie
     beim grossen Knopf (56-38=18 = 3 x 6). Nur dann sieht die Bewegung
     gleich aus. Bis Design 47 stand hier 46/30, also Sockel 16 bei
     Druck 4: Der kleine Knopf gab weniger nach als der grosse.
     Wer die Groesse aendert, muss die Rechnung mitfuehren:
         Hoehe - Kappe  =  3 x Druck */
  --btn-sm-h: 40px;
  --btn-sm-face: 28px;
  --btn-sm-press: 4px;

  /* Breite der dunklen Kontur rings um den Button.
     3px = wie ursprünglich, 0px = ohne Kontur (aktueller Versuch).
     ZURÜCK ZUM ALTEN BUTTON: hier einfach 3px eintragen. */
  --btn-rand: 0px;

  --pixel-clip: polygon(
    8px 0, calc(100% - 8px) 0, calc(100% - 4px) 0, calc(100% - 4px) 4px, 100% 4px, 100% 8px,
    100% calc(100% - 8px), 100% calc(100% - 4px), calc(100% - 4px) calc(100% - 4px), calc(100% - 4px) 100%, calc(100% - 8px) 100%, 8px 100%,
    4px 100%, 4px calc(100% - 4px), 0 calc(100% - 4px), 0 calc(100% - 8px),
    0 8px, 0 4px, 4px 4px, 4px 0
  );
  --pixel-clip-cap: polygon(
    0 8px, 0 4px, 4px 4px, 4px 0,
    calc(100% - 4px) 0, calc(100% - 4px) 4px, 100% 4px, 100% 8px,
    100% 100%, 0 100%
  );

  /* Weicher Markenverlauf. Anfang und Ende gleich, damit die Kachel
     nahtlos anschließt und die Bewegung unsichtbar zurückspringt. */
  --brand-gradient: linear-gradient(
    100deg,
    var(--brand-dark) 0%,
    var(--brand-light) 50%,
    var(--brand-dark) 100%
  );
  /* Kachel etwa so breit wie der Name bei 24px (rund 408px) – so durchläuft
     die Schrift die volle Farbrampe. Siehe Notiz „07 Farbpalette". */
  --brand-tile: 440px;
}

*{ box-sizing:border-box; margin:0; padding:0; }
/* Kein scroll-snap-type mehr: Das Einrasten aus Design 21 sprang beim
   Scrollen. Die Seite scrollt wieder frei, das Ein- und Ausblenden
   übernimmt allein das Skript in index.html. */
html{ scroll-behavior:smooth; }

/* ============================================================
   DIE ZWEI SCHRIFTEN UND IHRE AUFGABEN
   ------------------------------------------------------------
   'Press Start 2P' war an siebzehn Stellen im Einsatz - als
   Grundschrift fuer jede Ueberschrift und jeden Kartentitel. Das
   war zu viel: Die Schrift ist laut, breit und auf Dauer muehsam
   zu lesen. Sie ist ein AKZENT, keine Textschrift.

   JETZT NOCH VIER STELLEN - die Signatur der Seite:
     1. der Name im Hero
     2. das Logo IJ in der Navigation
     3. "Insert Coin to Continue" im Eingangsbildschirm
     4. "Insert Coin" im Kontaktabschnitt

   Alles andere - Abschnittsueberschriften, Kartentitel, Knoepfe,
   Navigation, Fenstertitel - traegt jetzt 'JetBrains Mono'. Die war
   ohnehin schon geladen und passt zum Terminal-Motiv im About.
   Gross, fett und gesperrt gesetzt behaelt sie Haltung, ohne zu
   schreien.

   AN DEN VIER PIXELSTELLEN GILT WEITERHIN:
     font-weight:400          - die Schrift hat nur einen Schnitt.
                                Ohne diese Angabe faelscht der Browser
                                ein Fett und verschmiert die Kanten.
     font-smoothing:none      - keine Kantenglaettung.
     Groessen in Vielfachen von 8px.
   ============================================================ */

.nav-logo,
h1,
.insert-coin .blink-title,
.intro-text{
  font-weight:400;
  -webkit-font-smoothing:none;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:geometricPrecision;
}



/* Space Grotesk ist jetzt die Grundschrift. Inter stand nur hier und
   war damit praktisch unsichtbar - zwei Sans-Schriften nebeneinander
   sind ohnehin eine zu viel. */
body{ background:var(--bg); color:var(--text); font-family:'Space Grotesk', sans-serif; overflow-x:hidden; }
img{ image-rendering:pixelated; }

@keyframes blink{ 0%,49%{opacity:1;} 50%,100%{opacity:0;} }

/* ============================================================
   NAVBAR – schwebende Glasplatte, eckig
   ============================================================ */

.nav-wrap{
  position:fixed; top:0; left:0; right:0; z-index:60;
  display:flex; justify-content:center;
  padding:1.25rem 6vw;
  pointer-events:none;
  transition:padding .25s ease;
}
.nav-wrap.scrolled{ padding-top:.7rem; }

.nav{
  width:fit-content; max-width:calc(100vw - 2rem);
  position:relative;
  pointer-events:auto;
  display:flex; align-items:center; gap:1.8rem;
  padding:.9rem 1.6rem;
  background:rgba(12,12,17,0.5);
  /* Weichzeichner bewusst schwächer und ohne saturate(): Der Bereich hinter
     der festen Leiste muss bei JEDEM Scrollbild neu berechnet werden. 18px
     plus Sättigung war der teuerste Posten der Seite. 12px sehen praktisch
     gleich aus und kosten spürbar weniger. */
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
  border:2px solid var(--badge-border);
  transition:background .25s ease, border-color .25s ease;
}
.nav-wrap.scrolled .nav{
  background:rgba(12,12,17,0.8);
  border-color:rgba(255,255,255,0.13);
}

.nav-logo{
  position:relative;
  /* ebenfalls Vielfaches von 8 (siehe .nav-links .lbl) */
  font-family:'Press Start 2P', monospace; font-size:16px; color:var(--text);
  -webkit-font-smoothing:none;
  text-decoration:none; flex:none; padding-right:1.8rem;
}
.nav-logo span{ color:var(--accent); }
.nav-logo::after{
  content:''; position:absolute; right:0; top:50%; transform:translateY(-50%);
  width:2px; height:18px; background:rgba(255,255,255,0.12);
}

.nav-links{ display:flex; align-items:center; gap:1.4rem; list-style:none; }
.nav-links a{ display:inline-flex; align-items:center; gap:.55rem; text-decoration:none; }

/* Optische Korrektur: 'Press Start 2P' setzt seine Großbuchstaben höher
   in die Zeile, als die Zeilenmitte liegt. Ein exakt mittig ausgerichtetes
   Quadrat wirkt dadurch zu tief. Ein Pixel nach oben gleicht das aus.

   Die Kästchen bleiben gedämpft. Farbe bekommt nur der aktive Reiter –
   dadurch führt das Auge sofort zur aktuellen Stelle. */
.nav-links .mk{
  width:7px; height:7px; flex:none; display:block;
  position:relative; top:-1px;
  background:rgba(255,255,255,0.16);
  transition:background .15s ease;
}
.nav-links a.active .mk{
  background:var(--brand-light);
  animation:blink 1s steps(1) infinite;
}

.nav-links .lbl{
  font-family:'Space Grotesk', sans-serif; font-weight:700;
  /* WICHTIG – die Rastergröße:
     'Press Start 2P' zeichnet auf 8 Einheiten je Geviert. Nur bei
     Vielfachen von 8px entspricht eine Schrifteinheit ganzen Bildschirm-
     pixeln. 10px ergaben 1,25 Pixel je Einheit – der Browser musste
     glätten, und in Verbindung mit dem Verlauf im Text (background-clip)
     verschwanden dünne Striche. Deshalb hier 8px.
     Erlaubt sind: 8, 16, 24 … NIEMALS krumme Werte. */
  font-size:.7rem; line-height:1;
  /* Zusätzliche Absicherung: schaltet die Kantenglättung ganz ab.
     Für eine Pixelschrift genau richtig – harte Kanten sind erwünscht. */
  -webkit-font-smoothing:none;
  color:var(--text-dim);
  transition:color .15s ease;
  letter-spacing:.09em; text-transform:uppercase;
}

/* WARUM ES HIER KEINEN FARBVERLAUF GIBT
   -------------------------------------
   Drei Anläufe, den Verlauf per background-clip:text in die Beschriftung zu
   legen, sind gescheitert – die Buchstaben wurden immer wieder eingedrückt.
   Der Browser behandelt die Schrift dabei als Maske, und Striche von wenigen
   Pixeln Breite halten das nicht aus.

   Ein Ersatz als Linie unter der Schrift war dem Nutzer zu viel. Es bleibt
   also beim Einfachsten: die Beschriftung wechselt auf eine kräftige
   Volltonfarbe. Ruhig, gestochen scharf, eindeutig. */
.nav-links a:hover .lbl,
.nav-links a.active .lbl{
  color:var(--brand-light);
}

/* ============================================================
   BUTTONS – das Bausystem des Originals
   Gestufte Ecken kennzeichnen alles Drückbare.
   ============================================================ */

.btn{
  position:relative; display:inline-flex; align-items:flex-start; text-decoration:none;
  padding:var(--btn-rand); height:var(--btn-h); background:var(--outline); clip-path:var(--pixel-clip);
  --riser:#000; box-shadow:5px 5px 0 rgba(0,0,0,0.45);
  transition:height .12s ease-out, box-shadow .12s ease-out;
  border:none; cursor:pointer; font-family:inherit;
}
.btn:hover{ height:calc(var(--btn-h) - var(--btn-press)); box-shadow:2px 2px 0 rgba(0,0,0,0.45); }
.btn:active{ height:calc(var(--btn-h) - var(--btn-press) * 2); box-shadow:0 0 0 rgba(0,0,0,0.45); }
.btn-base{ position:absolute; inset:var(--btn-rand); clip-path:var(--pixel-clip); background:var(--riser); }
.btn-face{
  position:relative; display:flex; align-items:center; justify-content:center; gap:.7rem;
  height:var(--btn-face); width:100%; flex:none;
  /* Schriftgröße unverändert – gewünscht war nur ein kleineres Maß,
     keine andere Beschriftung. */
  font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:.78rem; padding:0 1.25rem;
  text-shadow:1.5px 1.5px 0 rgba(0,0,0,0.35); clip-path:var(--pixel-clip-cap);
  box-shadow:inset 0 3px 0 rgba(255,255,255,0.4); transition:box-shadow .12s ease-out;
  letter-spacing:.09em; text-transform:uppercase;
}
.btn:hover .btn-face{ box-shadow:inset 0 2px 0 rgba(255,255,255,0.25); }
.btn:active .btn-face{ box-shadow:inset 0 1px 0 rgba(255,255,255,0.15); }

.btn-primary{ --riser:var(--riser-primary); }
.btn-primary .btn-face{ background:linear-gradient(100deg, var(--brand-dark), var(--brand-light)); color:#fff; }

.btn-secondary{ --riser:var(--riser-secondary); }
.btn-secondary .btn-face{ background:#fff; color:var(--brand-ink); text-shadow:1.5px 1.5px 0 rgba(138,74,52,0.24); }

.btn-social{ --riser:var(--riser-social); }
.btn-social .btn-face{
  background:linear-gradient(180deg, #2c2c35, #191920);
  color:var(--text-dim); padding:0 1.15rem; font-size:.72rem;
  text-shadow:1.5px 1.5px 0 rgba(0,0,0,0.45);
  box-shadow:inset 0 3px 0 rgba(255,255,255,0.14);
  transition:color .12s ease-out, box-shadow .12s ease-out;
}
.btn-social:hover .btn-face{ color:var(--text); box-shadow:inset 0 2px 0 rgba(255,255,255,0.10); }

/* Kleinere Bauform desselben Systems – für die Galerie-Filter */
/* Kleine Bauform für die Galerie-Filter. Eigene Variablen, damit das
   Größenverhältnis zur großen Bauform erhalten bleibt. */
/* Kleine Bauform. Seit Design 24 ohne Fundstelle, weil die Filterzeile
   weggefallen ist. Bleibt trotzdem stehen: Es ist die dokumentierte
   zweite Buttongroesse, und die Fallstudien-Links der Auftragsarbeiten
   werden sie voraussichtlich wieder brauchen. Sie kostet vier Zeilen. */
.btn-sm{ height:var(--btn-sm-h); box-shadow:4px 4px 0 rgba(0,0,0,0.45); }
.btn-sm:hover{ height:calc(var(--btn-sm-h) - var(--btn-sm-press)); box-shadow:2px 2px 0 rgba(0,0,0,0.45); }
.btn-sm:active{ height:calc(var(--btn-sm-h) - var(--btn-sm-press) * 2); box-shadow:0 0 0 rgba(0,0,0,0.45); }
.btn-sm .btn-face{ height:var(--btn-sm-face); font-size:8px; padding:0 1rem; }

/* ============================================================
   HERO
   ============================================================ */

.hero{
  position:relative; min-height:100vh; display:flex; flex-direction:column;
  /* REGEL 2: Innenabstand oben und unten gleich groß, und größer als die
     Navbar (rund 75px inkl. ihres eigenen Abstands). Dadurch sitzt der Block
     wirklich mittig im Sichtfenster und kann nicht an der Leiste kleben.
     Vorher stand hier ein einseitiger Abstand von 9rem unten – der schob
     alles nach oben gegen die Navbar.
     Bewusst kein transform: das würde die Pixelgrafik auf halbe Pixel
     schieben und ausfransen lassen. */
  /* Seitlich KEIN Polster mehr - das sitzt jetzt auf .hero-inner,
     damit der Hero denselben Kasten hat wie ein Abschnitt. */
  justify-content:center; padding:7rem 0; isolation:isolate;
}
/* Die beiden weichgezeichneten Hintergrund-Schleier wurden in Design 07
   entfernt. Sie stammten aus dem Originalentwurf und wurden durch den
   Leuchtkreis überflüssig – zwei Lichtquellen im selben Bild nehmen sich
   gegenseitig die Wirkung. Der Hero ist jetzt sauber schwarz. */

/* Unterkanten beider Spalten auf eine Linie: das Skelett steht auf Button-Höhe.
   Zweite Spalte "auto", damit die Grafik ihre feste Rastergröße behält. */
/* Schmaler als zuvor (1400px) und mit kleinerem Abstand: Die Textspalte war
   bei 1400px rund 880px breit – deutlich mehr, als die Zeilen brauchen – und
   das Skelett rutschte dadurch weit nach rechts.
   Jetzt: 1180 - 56 Abstand - 460 Grafik = 664px für den Text. */
/* DERSELBE KASTEN WIE EIN ABSCHNITT, Zeichen fuer Zeichen:
   max-width:var(--mass-breite) + padding 6vw + margin:0 auto.

   Das ist der ganze Trick. Vorher stand hier eine eigene Rechnung
   (max-width:1180px, Polster am .hero), die zufaellig aehnlich aussah -
   gemessen lag der Hero 44px (bei 2560) bis 115px (bei 1920) daneben,
   der Text zu weit links und das Skelett zu weit rechts.

   Mit demselben Kasten koennen die Kanten gar nicht mehr auseinander-
   laufen, auch dann nicht, wenn jemand spaeter --mass-breite aendert. */
.hero-inner{
  display:grid; grid-template-columns:1fr auto; align-items:end;
  gap:3.5rem; width:100%;
  max-width:var(--mass-breite); padding:0 6vw; margin:0 auto;
}

.badge{
  display:inline-flex; align-items:center; gap:.65rem;
  /* Regel 1: 8px statt .6rem (= 9,6px) */
  font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:.72rem; line-height:1.6;
  color:var(--text-dim); background:var(--badge-bg); border:2px solid var(--badge-border);
  padding:.7rem 1rem; margin-bottom:2rem;
  letter-spacing:.1em; text-transform:uppercase;
}
/* gleiche optische Korrektur wie beim Navbar-Kästchen */
.badge .dot{
  width:8px; height:8px; background:var(--accent);
  position:relative; top:-1px;
  animation:blink 1s steps(1) infinite;
}

/* REGEL 1: 'Press Start 2P' nur in Vielfachen von 8px – nur dann liegen die
   Buchstaben exakt auf dem Bildschirmraster. Deshalb feste Werte statt clamp:
   eine gleitende Größe trifft das Raster fast nie.
   REGEL 3: 24px ergibt für „Isabelle Jarugski" rund 408px Zeilenlänge – gut
   lesbar in der 664px breiten Spalte und deutlich ruhiger als die 29,6px
   zuvor. */
h1{
  font-family:'Press Start 2P', monospace; font-weight:400;
  font-size:24px; line-height:1.7; margin-bottom:1.75rem;
}
/* inline-block: Die Box umschließt genau den Text. Wäre sie breiter,
   bekäme die Schrift nur den Anfang der Farbrampe ab und der Verlauf
   sähe fast einfarbig aus. */
h1 .name{
  display:inline-block; white-space:nowrap;
  background-image:var(--brand-gradient);
  background-size:var(--brand-tile) 100%;
  background-position:0 0;
  -webkit-background-clip:text; background-clip:text; color:transparent;
  text-shadow:3px 3px 0 rgba(163,94,70,0.20);
  animation:nameDrift 11s linear infinite;
}
@keyframes nameDrift{
  from{ background-position:0 0; }
  to{ background-position:var(--brand-tile) 0; }
}

/* Der laufende Verlauf zeichnet den Text bei jedem Bild neu – das ist teuer,
   weil die Schrift dabei als Maske dient. Sobald der Hero aus dem Sichtfeld
   ist, wird er angehalten. Sichtbar ist er dann ohnehin nicht. */
body.hero-fort h1 .name{ animation-play-state:paused; }

.tagline{
  font-family:'JetBrains Mono', monospace; font-size:.95rem; line-height:1.8;
  color:var(--text-dim); max-width:34rem; margin-bottom:2.5rem;
}

/* Feste Mindesthöhe = Ruhehöhe der Buttons.
   Ohne sie bestimmt der höchste Button die Zeilenhöhe. Beim Hovern schrumpft
   er von 66px auf 59px – fährt man schnell über mehrere, sind kurzzeitig alle
   kleiner und die ganze Zeile wird flacher. Genau dadurch zuckte der Text
   darüber. Mit fester Höhe kann das nicht mehr passieren. */
/* .hinweis-privat ist seit Design 65 entfallen - die Aussage steht
   jetzt im Satz darueber ("A personal portfolio of ...") und
   vollstaendig im Fuss. Zwei Saetze, die dasselbe umkreisen, sind
   einer zu viel. */

.cta-row{ display:flex; align-items:flex-end; gap:.9rem; flex-wrap:wrap; min-height:var(--btn-h); }

/* ---- Hero-Grafik ----
   Pixel-Art im 5er-Raster (logisch 230x230). NUR in ganzzahligen
   Vielfachen von 230 anzeigen, sonst franst sie aus.
   --art-trim rechnet den leeren unteren Bildrand heraus. */
.hero-visual{
  --art-w: 460px;
  --art-trim: 92px;
  position:relative;
  display:flex; align-items:flex-end; justify-content:center;
}
.hero-art-wrap{
  position:relative;
  width:var(--art-w);
  margin-bottom:calc(var(--art-trim) * -1);
  /* DER LEERE RAND RECHTS WIRD HERAUSGERECHNET - dieselbe Ueberlegung
     wie --art-trim unten, nur zur Seite.

     Die Datei ist 1150 Punkte breit, das Skelett endet bei 1040. Die
     restlichen 110 sind durchsichtig. Ohne sie abzuziehen ist zwar der
     KASTEN mit den Abschnitten buendig, das sichtbare Skelett aber
     endet 44 Punkte davor - und ausgerichtet aussehen soll, was man
     sieht, nicht was im Baum steht.

     Als Rechnung und nicht als feste Zahl: So stimmt sie auch bei
     --art-w:230 (dann sind es 22 Punkte). */
  margin-right:calc(var(--art-w) * -110 / 1150);
  line-height:0;
}
/* Seit der sauber freigestellten Grafik (ELLENDEnoBGx500) darf der Kreis wieder
   groß sein und bis in die Felsen reichen – die haben jetzt echte gemalte Pixel.
   Die frühere 61-%-Grenze ist damit hinfällig. */
.hero-orb{
  position:absolute;
  /* Größe so gewählt, dass der Schädel oben herausragt (Schädel beginnt bei
     11,7 % der Bildhöhe) und die Unterkante hinter den Steinen verschwindet.
       Oberkante  = 43 % - 28 % = 15 %   -> unter dem Schädel
       Unterkante = 43 % + 28 % = 71 %   -> im dichten Felsbereich */
  top:43%; left:50%;
  transform:translate(-50%,-50%);
  width:56%; aspect-ratio:1;
  border-radius:50%;
  background:radial-gradient(
    circle at 50% 42%,
    #F7CBA8 0%,
    var(--brand-light) 34%,
    var(--brand-mid) 66%,
    var(--brand-dark) 100%
  );
  /* Schein bewusst eng und kräftig statt weit auslaufend:
     nur zwei Ringe, beide dicht am Rand, dafür höhere Deckkraft. */
  box-shadow:
    0 0 26px 2px rgba(241,177,132,0.78),
    0 0 58px 8px rgba(241,177,132,0.40);
  z-index:0; pointer-events:none;
}
#heroArt{
  position:relative; z-index:1;
  display:block; width:100%; height:auto;
  user-select:none; -webkit-user-drag:none;
}

/* ============================================================
   ABSCHNITTE – gemeinsamer Rahmen
   ============================================================ */

/* Wieder ein schlichter Block: keine Mindesthöhe, keine Mittigkeit, kein
   Rastpunkt. Jeder Abschnitt ist genau so hoch wie sein Inhalt. Die beiden
   Maße kommen aus dem Maßstab oben. */
section{
  position:relative;
  padding:var(--mass-abschnitt) 6vw;
  max-width:var(--mass-breite);
  margin:0 auto;
}
.section-head{ margin-bottom:var(--mass-kopf); }
.eyebrow{
  display:inline-flex; align-items:center; gap:.6rem;
  font-family:'JetBrains Mono', monospace; font-size:.75rem; color:var(--brand-mid);
  text-transform:uppercase; letter-spacing:.12em;
  margin-bottom:var(--abstand-eng);
}
.eyebrow::before{ content:''; width:22px; height:2px; background:var(--accent); }
/* Regel 1: feste 24px statt clamp(1.1rem, 2vw, 1.6rem). Der bisherige
   Höchstwert lag bei 25,6px – optisch fast gleich, aber nicht auf dem Raster. */
/* Abschnittsueberschriften tragen seit Design 34 die Monoschrift.
   Gross, fett und leicht gesperrt behaelt sie Haltung, ohne zu schreien -
   die Pixelschrift war hier zu maechtig und muehsam zu lesen. */
.section-title{
  font-family:'Space Grotesk', sans-serif;
  font-weight:700; font-size:1.9rem; line-height:1.3;
  letter-spacing:-.005em; color:var(--text);
}
.section-sub{
  font-family:'Space Grotesk', sans-serif; font-size:.88rem; line-height:1.9;
  color:var(--text-dim); max-width:44rem;
  margin-top:var(--abstand-eng);
}

/* Bildplatzhalter, drei Ebenen: echtes Bild -> Platzhalterbild -> Verlauf.
   Die oberste vorhandene Datei gewinnt. Erzeugt von tools/build_dummy.py. */
.thumb{
  background-color:var(--bg-2);
  background-repeat:no-repeat; background-size:cover; background-position:center;
  position:relative;
}
/* KEINE project-N.jpg MEHR. Sie standen hier bis zum 2026-08-30 als
   erste Rueckfallstufe, hat es aber nie gegeben - ein Rest des
   Urentwurfs, in dem jede Karte ein festes Bild haben sollte. Der
   Browser fragte sie bei JEDEM Aufruf vergeblich an, noch bevor das
   Skript lief. Zwei 404 pro Besuch, gemessen.

   Was bleibt, traegt den Fall "Karte ohne Bilder": das Platzhalterbild
   und darunter ein Farbverlauf in den Markenfarben. */
.thumb-1{ --fallback:
  url('assets/images/dummy-thumb.webp'),
  linear-gradient(135deg, rgba(163,94,70,.75), rgba(241,177,132,.35));
  background-image:var(--fallback); }
.thumb-2{ --fallback:
  url('assets/images/dummy-thumb.webp'),
  linear-gradient(150deg, rgba(201,130,95,.7), rgba(107,59,44,.5));
  background-image:var(--fallback); }
.thumb-3{ --fallback:
  url('assets/images/dummy-thumb.webp'),
  linear-gradient(120deg, rgba(241,177,132,.45), rgba(163,94,70,.7));
  background-image:var(--fallback); }
.thumb-4{ --fallback:
  url('assets/images/dummy-thumb.webp'),
  linear-gradient(160deg, rgba(138,74,52,.75), rgba(201,130,95,.4));
  background-image:var(--fallback); }
.thumb-5{ --fallback:
  url('assets/images/dummy-thumb.webp'),
  linear-gradient(135deg, rgba(107,59,44,.7), rgba(201,130,95,.45));
  background-image:var(--fallback); }
/* .thumb-6 ist am 2026-08-29 entfallen: 1 bis 3 gehören den Featured-
   Karten, 4 und 5 den beiden Stellen. Die sechste wartete auf eine Karte,
   die es nie gab. Kommt eine dritte Stelle dazu, ist sie drei Zeilen
   Arbeit - nach dem Muster von .thumb-5 darüber. */

/* ============================================================
   FEATURED PROJECTS – drei große Karten
   ============================================================ */

.featured-grid{ display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--mass-luecke); }
.feat{
  background:var(--bg-2); border:2px solid var(--badge-border);
  display:flex; flex-direction:column;
  transition:border-color .15s ease, transform .15s ease;
}
.feat:hover{ border-color:var(--brand-light); transform:translateY(-3px); }
/* Die Trennlinie sitzt am TEXTBLOCK, nicht am Bild - siehe Kommentar
   bei .kategorie-bild. */
.feat .thumb{ height:var(--mass-feat-bild); }
.feat .body{
  /* Eigener Untergrund - dieselbe Ueberlegung wie bei
     .kategorie-body. */
  position:relative; z-index:1;
  background:var(--bg-2); border-top:2px solid var(--badge-border); }
.feat .num{
  position:absolute; top:.7rem; left:.7rem; z-index:1;
  font-family:'JetBrains Mono', monospace; font-weight:700; font-size:.9rem; line-height:1;
  color:var(--bg); background:var(--accent); padding:.45rem .55rem;
  letter-spacing:.06em;
}
.feat .body{ padding:var(--mass-feat-text); display:flex; flex-direction:column; gap:.8rem; flex:1; }
.feat .where{
  font-family:'JetBrains Mono', monospace; font-size:.7rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--brand-mid);
}
.feat h3{ font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:1.18rem; line-height:1.6; }
.feat p{ font-family:'Space Grotesk', sans-serif; font-size:.83rem; line-height:1.75; color:var(--text-dim); }
/* Solange ein Projektordner leer ist, blendet das Skript diesen
   Hinweis aus - er fuehrte bis Design 56 ins Leere. */
.feat .more[hidden]{ display:none; }

.feat[data-featured].hat-werke{ cursor:pointer; }
.feat[data-featured].hat-werke:hover{ border-color:var(--brand-light); }
.feat[data-featured].hat-werke:focus-visible{
  outline:2px solid var(--brand-light); outline-offset:3px;
}
/* Das Vorschaubild kommt aus dem Ordner, sobald eines da ist. Das
   Skript setzt nur die Variable, die Gestaltung bleibt hier. */
.feat[data-featured] .thumb{ background-image:var(--cover, none), var(--fallback); }

.feat .more{ margin-top:auto; font-family:'Space Grotesk', sans-serif; font-size:.78rem; color:var(--accent); }

/* ============================================================
   ABOUT – Terminal-Fenster
   ============================================================ */

/* stretch statt start: Beide Spalten werden gleich hoch. Die Statuskarte
   verteilt ihre Zeilen dann über die volle Höhe. */
.about-grid{ display:grid; grid-template-columns:1.35fr 1fr; gap:2.5rem; align-items:stretch; }

.terminal{ background:var(--bg-2); border:2px solid var(--badge-border); }
.terminal-bar{
  display:flex; align-items:center; gap:.5rem;
  padding:.7rem 1rem; border-bottom:2px solid var(--badge-border);
  font-family:'JetBrains Mono', monospace; font-size:.7rem; color:var(--text-dim);
}
.terminal-bar .tdot{ width:9px; height:9px; }
.tdot.r{ background:#ff5f56; } .tdot.y{ background:#ffbd2e; } .tdot.g{ background:#27c93f; }
.terminal-bar .tname{ margin-left:.4rem; }
.terminal-body{
  padding:var(--mass-karte-polster); font-family:'JetBrains Mono', monospace;
  font-size:.9rem; line-height:2; color:var(--text-dim);
}
.terminal-body .prompt{ color:var(--accent); }
.terminal-body .cmd{ color:var(--text); }
.terminal-body p{ margin-bottom:1.1rem; }
.terminal-body p:last-child{ margin-bottom:0; }
.terminal-body .cursor{
  display:inline-block; width:8px; height:1em; background:var(--accent);
  vertical-align:middle; animation:blink 1s steps(1) infinite;
}

/* ============================================================
   DIE LAUFBAHN
   ------------------------------------------------------------
   Stand hier bis Design 40 eine Liste aus Schlagwort und Wert
   ("Location: Berlin"). Die hatte zwei Probleme: Sie wiederholte
   halb, was das Terminal daneben ohnehin sagt, und sie fuellte
   sich zuletzt mit Angaben, die niemand braucht ("Tools",
   "Beyond work").

   Jetzt steht dort das, was auf der ganzen Seite fehlte: der WEG.
   Wer einstellt, sucht ihn zuerst - und er lag bisher unten in der
   Galerie versteckt.

   Die knappen Angaben (Ort, Status, Sprachen) sind ins Terminal
   gewandert. Dort gehoeren sie hin: Ein Terminal gibt Auskunft.
   ============================================================ */

.laufbahn{
  background:var(--bg-2); border:2px solid var(--badge-border);
  padding:var(--mass-karte-polster);
  display:flex; flex-direction:column;
}

/* Die Kopfzeile trug bis Design 55 einen Knopf zum Lebenslauf. Er ist
   entfallen: Ein Lebenslauf enthaelt Anschrift und Telefonnummer, und
   auf einer offenen Seite ist das fuer jeden abrufbar - auch fuer
   Maschinen, die Adressen einsammeln. Wer ihn braucht, fragt danach.
   Zum Zurueckholen: siehe archiv/design-55-rechtehinweis/. */

.laufbahn-titel{
  font-family:'JetBrains Mono', monospace;
  font-weight:700; font-size:.72rem; line-height:1.6;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--brand-mid);
  /* Enger seit Design 52 - siehe Rechnung im Kopf dieser Datei. */
  margin-bottom:1.15rem;
}

/* Punkt und Linie sitzen AUSGERECHNET aufeinander, nicht geschaetzt.
   ------------------------------------------------------------------
   Der Punkt ist ein Rasterfeld von 14px in der ersten Spalte, senkrecht
   mittig zur ERSTEN Textzeile (align-self:center). Die Linie liegt bei
   left:6px und ist 2px breit - ihre Mitte sitzt damit auf 7px, genau wie
   die Mitte der 14px-Spalte.

   Damit die Linie am ersten und letzten Punkt endet und nicht ins Leere
   laeuft, braucht die erste Zeile eine feste Hoehe: 22px, Mitte also 11px.
   Deshalb steht bei .posten eine Zeilenhoehe in Pixeln und nicht als
   Vielfaches - nur so laesst sich damit rechnen. */

/* Der Abstand zwischen den Stationen ist seit Design 52 enger. Er muss
   die Stationen nicht mehr allein trennen - das tut die Jahreszahl, die
   jetzt als eigene Zeile obenauf steht. */
.laufbahn-liste{
  list-style:none; position:relative;
  display:flex; flex-direction:column; gap:.95rem;
}

/* 18px Zeilenhoehe der Jahreszahl -> Mitte bei 9px. Bis Design 50 war
   die erste Zeile die Position mit 22px, also 11px. Wer die erste Zeile
   tauscht, muss diese Zahl mittauschen: halbe Zeilenhoehe. */
.laufbahn-liste::before{
  content:''; position:absolute; left:6px; top:9px; bottom:9px;
  width:2px; background:var(--badge-border);
}

/* Drei Spalten: Punkt, Text, Jahr.
   Das Jahr stand bis Design 42 am Ende der Ortszeile und ging dort
   unter - eine kleine Angabe hinter einem langen Firmennamen liest
   niemand. In einer eigenen Spalte steht es untereinander und laesst
   sich mit einem Blick abfahren, ohne die Position zu verdraengen. */
/* ZWEI Spalten: Punkt und Text. Die Jahreszahl ist die erste ZEILE.

   Sie stand bis Design 50 in einer dritten Spalte rechts und davor am
   Ende der Ortszeile. Beides ging unter, und der Grund war beide Male
   derselbe: Sie stand dort, wo die Zeile AUFHOERT. Das Auge liest von
   links und ist am rechten Rand schon fertig.

   Oben steht sie dort, wo das Auge ANFAENGT - der Aufbau jedes
   Lebenslaufs: erst wann, dann was, dann wo.

   UND SIE NIMMT KEINE BREITE MEHR WEG. Die dritte Spalte kostete rund
   85px; von den 410px der Karte blieben 309 fuer den Text, und
   "Marketing Manager & Graphic Designer" braucht 306. Die Zeile stand
   auf der Kante und brach um. Ohne Jahresspalte tut sie das nicht mehr. */
.laufbahn-liste li{
  display:grid;
  grid-template-columns:14px 1fr;
  column-gap:1rem; row-gap:0;
}
.laufbahn-liste li .jahr  { grid-column:2; grid-row:1; justify-self:start; }
.laufbahn-liste li .posten{ grid-column:2; grid-row:2; }
.laufbahn-liste li .meta  { grid-column:2; grid-row:3; }

/* Eckig, nicht rund: Auf dieser Seite ist nichts rund, und ein Quadrat
   passt zum Pixelraster. */
.laufbahn-liste li::before{
  content:''; grid-column:1; grid-row:1; align-self:center;
  box-sizing:border-box; width:14px; height:14px;
  background:var(--bg-2); border:2px solid var(--brand-mid);
  /* Bringt das Kaestchen in denselben Malvorgang wie die Linie -
     sonst laeuft sie mitten hindurch. Siehe Kopf dieser Datei. */
  position:relative;
}
/* Die aktuelle Stelle ist ausgefuellt. */
.laufbahn-liste li:first-child::before{
  background:var(--brand-light); border-color:var(--brand-light);
}

/* Die Position ist die Auskunft, die Jahreszahl die Einordnung.
   Die Zeilenhoehe darf hier frei gewaehlt werden: Bis Design 50 war die
   Position die ERSTE Zeile und bestimmte damit, wo die senkrechte Linie
   anfaengt - seit Design 51 tut das die Jahreszahl mit ihren 18px. */
.laufbahn .posten{
  font-weight:700; font-size:1.02rem; line-height:20px; color:var(--text);
}
.laufbahn .meta{
  font-size:.88rem; line-height:1.5; color:var(--text-dim);
}
/* line-height in PIXELN, nicht als Vielfaches - nur mit einer festen
   Zahl laesst sich die Mitte fuer die Linie ausrechnen. */
.laufbahn .jahr{
  font-family:'JetBrains Mono', monospace;
  font-size:.78rem; line-height:18px; letter-spacing:.05em; color:var(--accent);
  white-space:nowrap;
}

/* Fuer schmale Fenster ist nichts mehr zu tun: Die Laufbahn ist seit
   Design 51 ohnehin einspaltig. Die Sonderregel ist entfallen. */

/* ============================================================
   SKILLS – Karten ohne zweite Zeile
   ============================================================ */

.skill-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(var(--mass-skill-spalte),1fr)); gap:var(--mass-skill-luecke); }
/* ---- Skill-Karten ----
   Klick dreht die Karte um. Warum drehen statt aufklappen: Beim Aufklappen
   würde die Karte wachsen, die Zeile mitwachsen und alles darunter springen.
   Die Drehung braucht dagegen eine feste Höhe und verschiebt gar nichts. */
.skill{
  position:relative; height:var(--mass-skill-hoehe);
  padding:0; border:none; background:none;
  font:inherit; color:inherit; text-align:left;
  cursor:pointer;
  perspective:900px;
}
/* Innerer Rahmen trägt die Drehung. Dadurch lassen sich beide Seiten
   gemeinsam kippen – das brauchen wir für die Vorschau beim Darüberfahren. */
.skill-inner{
  position:absolute; inset:0;
  transform-style:preserve-3d;
  transition:transform .55s cubic-bezier(.22,.61,.36,1);
}
.skill-seite{
  position:absolute; inset:0;
  display:flex; align-items:center; gap:.9rem;
  padding:.95rem 1.15rem;
  background:var(--bg-2); border:2px solid var(--badge-border);
  backface-visibility:hidden;
  transition:border-color .15s ease;
}
.skill-hinten{ transform:rotateY(180deg); }

/* Beim Darüberfahren leuchtet die Umrandung im hellen Markenton auf –
   wie bei allen anderen Kästen. Ging in Design 11 versehentlich verloren. */
.skill:hover .skill-seite,
.skill:focus-visible .skill-seite{ border-color:var(--brand-light); }

/* Beim Darüberfahren kippt die Karte ein Stück an. Das zeigt ohne Worte,
   dass sie sich drehen lässt – die beste Einladung zum Klicken. */
.skill:hover .skill-inner,
.skill:focus-visible .skill-inner{ transform:rotateY(-14deg); }
.skill.gedreht .skill-inner{ transform:rotateY(180deg); }
.skill.gedreht:hover .skill-inner,
.skill.gedreht:focus-visible .skill-inner{ transform:rotateY(194deg); }

/* Zwei versetzte Punkte unten rechts – deuten ein Umschlagen an und sind
   deutlicher als ein einzelner Punkt. */
.skill-vorne::after,
.skill-vorne::before{
  content:''; position:absolute; bottom:7px;
  width:5px; height:5px; background:var(--brand-mid);
  transition:background .15s ease, opacity .15s ease;
}
.skill-vorne::after{ right:7px; opacity:.75; }
.skill-vorne::before{ right:15px; opacity:.35; }
.skill:hover .skill-vorne::after,
.skill:hover .skill-vorne::before{ background:var(--brand-light); opacity:1; }

.skill .icon{
  width:38px; height:38px; flex:none;
  display:flex; align-items:center; justify-content:center;
  background:linear-gradient(140deg, var(--brand-dark), var(--brand-light));
  font-family:'JetBrains Mono', monospace; font-weight:700; font-size:.7rem; color:#2a1712;
  letter-spacing:.04em;
}
.skill .name{ font-family:'Space Grotesk', sans-serif; font-size:.85rem; color:var(--text); }

/* Seit Design 52 OHNE den wiederholten Kartennamen. Er kostete rund
   22px von den 33,6px, die im schmalen Fenster ueberhaupt da sind, und
   liess damit nur EINE Zeile fuer die Schlagworte.

   Gerechnet, schmales Fenster:
     Karte 68px - 2 x 15,2 Polster - 4 Rahmen  =  33,6px Platz
     zwei Zeilen zu .74rem/1,4                 =  33,2px

   Wer den Namen zurueckwill, braucht eine hoehere Karte
   (--mass-skill-hoehe) - beides zusammen geht nicht. */
.skill-hinten{
  font-family:'Space Grotesk', sans-serif; font-size:.74rem; line-height:1.4;
  color:var(--text-dim);
}

/* ============================================================
   GALERIE – Filter im Button-System, dann Karten
   ============================================================ */


/* Der Abstand zum Text darueber sitzt HIER, nicht am letzten Absatz.
   Sonst haenge er davon ab, welcher Absatz gerade der letzte ist - mit
   Rechtehinweis ein anderer als ohne. */
.gallery-grid,
.kategorie-grid{ margin-top:calc(var(--abstand-weit) / 2); }

.gallery-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(var(--mass-galerie-spalte),1fr)); gap:var(--mass-luecke); }

/* Die Auftragsarbeiten sind zwei feste Karten, keine wachsende Liste.
   Mit auto-fill wuerden sie sich je nach Fensterbreite auf drei oder vier
   Spalten verteilen und dabei schmal werden. */
.auftrag-grid{ grid-template-columns:repeat(2, 1fr); }
@media (max-width:700px){
  .auftrag-grid{ grid-template-columns:1fr; gap:1.6rem; }
}
.work{
  background:var(--bg-2); border:2px solid var(--badge-border);
  display:flex; flex-direction:column;
  transition:border-color .15s ease, transform .15s ease;
}
.work:hover{ border-color:var(--brand-light); transform:translateY(-3px); }
/* bewusst hoch, damit vom Bild mehr zu sehen ist */
.work .thumb{ height:var(--mass-galerie-bild); }
.work .body{
  position:relative; z-index:1;
  background:var(--bg-2); border-top:2px solid var(--badge-border); }
/* Die Jahreszahl steht seit Design 62 IM KARTENTEXT, nicht auf dem Bild.
   Über einem einspaltigen Handybild war der halbdurchsichtige Kasten kein
   Eckchen mehr, sondern ein Balken quer darüber.

   VOR DIESER REGEL STAND EIN VERIRRTES ".work". Zwischen ihm und ".wann"
   lag nur ein Kommentar, und Kommentare trennen keine Selektoren - der
   Browser las also ".work .wann", "nur innerhalb einer Auftragskarte".
   Aufgefallen ist es nicht, weil beide Fundstellen zufällig dort stehen.
   Beim nächsten Gebrauch anderswo wäre die Jahreszahl unformatiert
   gewesen. Am 2026-08-29 beim Aufräumen gefunden und richtiggestellt.

   Die frühere Marke .kindtag ist mit entfallen: Sie stand seit Design 62
   ohne Fundstelle da, laut eigenem Kommentar "bleibt als Bauteil stehen". */
.wann{
  font-family:'JetBrains Mono', monospace;
  font-size:.72rem; letter-spacing:.05em; color:var(--accent);
}
.work .body{ padding:var(--mass-galerie-text); display:flex; flex-direction:column; gap:.8rem; flex:1; }
.work h3{ font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:1.18rem; line-height:1.6; }
.work p{ font-family:'Space Grotesk', sans-serif; font-size:.82rem; line-height:1.7; color:var(--text-dim); }
.work .tags{ display:flex; gap:.45rem; flex-wrap:wrap; }
.work .tags span{
  font-family:'JetBrains Mono', monospace; font-size:.68rem; color:var(--brand-mid);
  border:1px solid var(--badge-border); padding:.2rem .5rem;
}
/* Solange der Ordner leer ist, blendet das Skript diesen Hinweis aus.
   Er fuehrte bis Design 53 ins Leere - reiner Text ohne Ziel. */
.work .more[hidden]{ display:none; }

/* Eine Karte mit Arbeiten dahinter ist anfassbar und sagt das auch. */
.work[data-auftrag].hat-werke{ cursor:pointer; }
.work[data-auftrag].hat-werke:hover{ border-color:var(--brand-light); }
.work[data-auftrag].hat-werke:focus-visible{
  outline:2px solid var(--brand-light); outline-offset:3px;
}

/* Das Vorschaubild kommt aus dem Ordner (cover.*), sobald eines da ist.
   Das Skript setzt nur die Variable - die Gestaltung bleibt hier.

   ES SETZT AUSSERDEM --fallback AUF none, sobald ein Cover da ist. Sonst
   liegt das Platzhalterbild dahinter, und bei einem Cover MIT DURCHSICHT
   sieht man es hindurchscheinen - ihr IQ-Bild besteht zu 79 Prozent aus
   Durchsicht. Ohne die zweite Schicht steht dort der Kartengrund. */
.work[data-auftrag] .thumb{ background-image:var(--cover, none), var(--fallback); }

/* Der Rechtehinweis unter den Auftragskarten.
   Kleiner und gedaempft: Er ist eine Angabe, keine Aussage ueber die
   Arbeit. Wer ihn sucht, findet ihn; wer die Arbeiten ansieht, stolpert
   nicht darueber. */
.rechte-hinweis{
  /* Kein Abstand nach oben: Er steht direkt unter dem Satz darueber,
     als dessen naechste ZEILE - also auch in derselben Schrift und
     Groesse wie .block-sub.

     KEINE Lesebreite: Er soll auf eine Zeile. Bei 88 Zeichen in .88rem
     sind das rund 620px, die Abschnittsbreite ist 1180px. Deshalb ist
     der Satz kurz gehalten - eine Zeile ist hier wichtiger als der
     letzte Nebensatz. */
  margin-top:0;
  font-family:'Space Grotesk', sans-serif;
  font-size:.88rem; line-height:1.9; color:var(--text-dim);
}

.work .more{ margin-top:auto; font-family:'Space Grotesk', sans-serif; font-size:.78rem; color:var(--accent); }

/* ============================================================
   GALERIE - Blockueberschriften
   ============================================================ */

.block-titel{
  font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:.8rem; line-height:1.8;
  color:var(--accent); margin-bottom:var(--abstand-eng);
  letter-spacing:.1em; text-transform:uppercase;
}
/* Der zweite Block braucht Abstand zum ersten, der erste keinen zur
   Abschnittsueberschrift - die bringt ihren eigenen schon mit.

   AM BLOCKTITEL SELBST, nicht ueber Geschwister-Selektoren. Vorher
   stand hier '.kategorie-grid + .block-titel' - und sobald etwas
   dazwischenkam (der Rechtehinweis), griff die Regel nicht mehr und
   der Titel klebte am Absatz darueber. Genau das war auf ihrem
   Bildschirmfoto zu sehen. */
.block-titel{ margin-top:var(--abstand-weit); }
.section-head + .block-titel{ margin-top:0; }

/* GENAU WIE .section-sub. Vorher .82rem/1.8 gegen .88rem/1.9 - zwei
   Groessen fuer dieselbe Sorte Text, und das sieht man. */
.block-sub{
  font-family:'Space Grotesk', sans-serif; font-size:.88rem; line-height:1.9;
  color:var(--text-dim); max-width:44rem;
  /* NULL: Blocktitel, Blocktext und Rechtehinweis sind EIN Textblock,
     und der Hinweis soll wie die naechste ZEILE desselben Absatzes
     stehen - nicht wie ein eigener Absatz.
     Das darf auf null, weil der Abstand zum Inhalt seit Design 64 am
     Raster sitzt (.gallery-grid, .kategorie-grid { margin-top }) und
     nicht mehr am letzten Absatz. */
  margin-bottom:0;
}

/* Einspaltig stapelt sich alles, was auf dem Schirm nebeneinander steht.
   Ohne mehr Luft steht der Rechtehinweis auf der Karte und der naechste
   Titel auf dem Hinweis.

   DIESER BLOCK STEHT HINTER ALLEN DREI GRUNDREGELN - zweimal falsch
   platziert, zweimal wirkungslos, beide Male von tools/pruefe_css.py
   gefunden. Bei gleicher Spezifitaet gewinnt die spaetere Regel. */
/* Keine Sonderwerte mehr fuer schmale Fenster: Seit die Abstaende an
   zwei Variablen haengen, stimmen sie in beide Richtungen. Hier standen
   bis Design 63 drei abweichende Zahlen. */

/* ============================================================
   KATEGORIE-KARTEN
   ------------------------------------------------------------
   VIER KARTEN, ZWEI SPALTEN, KEIN AUSREISSER.
   Bis Design 27 gab es fuenf Kategorien. Fuenf gehen in drei Spalten
   nicht auf, deshalb nahm die erste Karte zwei Spalten ein - und genau
   das gefiel nicht ("die eine Karte so in die Breite gezogen").

   Seit Digital Art und Traditional Drawings zu Drawings zusammengelegt
   sind, sind es vier. Vier gehen in zwei Spalten glatt auf: 2 + 2.
   Alle Karten sind gleich gross, die Sonderregel ist ersatzlos weg.

   BEI EINER FUENFTEN KATEGORIE: entweder eine sechste dazunehmen, oder
   auf drei Spalten wechseln und die alte Sonderregel wiederbeleben -
   sie steht in Design 27.
   ============================================================ */

.kategorie-grid{
  display:grid; grid-template-columns:repeat(2, 1fr);
  gap:var(--mass-luecke);
}

.kategorie-karte{
  display:flex; flex-direction:column; text-align:left;
  padding:0; border:2px solid var(--badge-border);
  background:var(--bg-2); color:inherit; cursor:pointer;
  transition:border-color .15s ease, transform .15s ease;
}
.kategorie-karte:hover{ border-color:var(--brand-light); transform:translateY(-3px); }
.kategorie-karte:focus-visible{ outline:2px solid var(--brand-light); outline-offset:2px; }
.kategorie-karte:disabled{ cursor:default; opacity:.55; }
.kategorie-karte:disabled:hover{ border-color:var(--badge-border); transform:none; }

.kategorie-bild{
  display:block; width:100%; height:var(--mass-galerie-bild);
  object-fit:cover;
}
/* DIE TRENNLINIE SITZT AM TEXTBLOCK, NICHT AM BILD.
   Sie war eine halbdurchsichtige weisse Linie (9 % Weiss) quer ueber die
   volle Breite - und sie sass am <img>. Beim Darueberfahren faehrt das
   Bild auf 1.05 heran, und die Linie wanderte MIT nach oben, mitten ins
   Bild hinein. Bei den Auftragskarten sass sie am .thumb und war deshalb
   immer sichtbar.

   Am Textblock kann ihr das nicht passieren: Der wird nicht bewegt und
   nicht vergroessert. Die Linie sitzt immer exakt auf der Naht. */
.kategorie-body{ border-top:2px solid var(--badge-border); }
/* Kategorie ohne Bilder: kein Loch, sondern der Markenverlauf. */
.kategorie-bild.leer{
  background:linear-gradient(135deg, rgba(163,94,70,.65), rgba(241,177,132,.28));
}

.kategorie-body{
  /* EIGENER UNTERGRUND, sonst nuetzt z-index nichts.
     Beim Darueberfahren faehrt das Bild auf 1.05 heran und ragt unten
     ueber seine Kante hinaus. z-index:1 hebt diesen Block darueber -
     aber ein DURCHSICHTIGER Block verdeckt nichts. Man sah drei Punkte
     Bild unterhalb der Trennlinie, und weil die Karte sich gleichzeitig
     um drei Punkte hebt, wanderte diese Linie beim Hovern.
     Gemessen: Ruhe (12,12,17) unter der Linie, Hover (17,20,21). */
  background:var(--bg-2);
  /* MALT UEBER DEM BILD. Beim Darueberfahren faehrt das Bild auf 1.05
     heran; ein Element mit transform wird wie ein positioniertes gemalt,
     also NACH dem normalen Inhalt - und ragte damit fuenf Punkte ueber
     die Oberkante dieses Blocks. Genau das war der Balken, der beim
     Hovern erschien.

     Die Karte schneidet oben und seitlich ab (overflow:hidden), aber
     nach unten steht dieser Block im Weg, kein Rand. */
  position:relative; z-index:1;
  display:flex; flex-direction:column; gap:.55rem;
  padding:var(--mass-galerie-text);
}
.kategorie-name{
  font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:1.2rem; line-height:1.6;
  color:var(--text);
}
.kategorie-anzahl{
  font-family:'Space Grotesk', sans-serif; font-size:.78rem; color:var(--accent);
}

.galerie-hinweis{
  font-family:'Space Grotesk', sans-serif; font-size:.82rem; line-height:1.8;
  color:var(--text-dim); grid-column:1 / -1;
}

@media (max-width:700px){
  .kategorie-grid{ grid-template-columns:1fr; gap:1.6rem; }
}

/* ============================================================
   DAS WERK-FENSTER
   ------------------------------------------------------------
   FORMENSPRACHE: Das Fenster ist eine FLAECHE, keine Taste - also
   eckig, ohne gestufte Ecken. Gestufte Ecken bekommt nur, was man
   druecken kann: Schliessen, Uebersicht und die Blaetterpfeile.
   Diese Regel stammt aus dem Original der Nutzerin, siehe
   "04 Navbar Labor".
   ============================================================ */

.fenster-lage{
  position:fixed; inset:0; z-index:200;
  display:flex; align-items:center; justify-content:center;
  padding:4vh 4vw;
  /* Dunkler als vorher (0.86). Das war die zweite Haelfte ihres
     Wunsches: der Rest ruhig staerker abgedunkelt - moeglich
     geworden, weil die Bildroehre jetzt darueber liegt. */
  background:rgba(4,4,6,0.93);
  opacity:0;
  transition:opacity .22s ease;   /* Dauer = BLENDE_MS in script.js */
}
.fenster-lage[hidden]{ display:none; }
.fenster-lage.offen{ opacity:1; }

body.fenster-offen{ overflow:hidden; }

.fenster{
  /* IMMER dieselbe Groesse - height, nicht max-height.
     Vorher richtete sich das Fenster nach seinem Inhalt: Zwei Bilder
     ergaben ein flaches Fenster, zwanzig ein hohes, und beim Umschalten
     des Filters sprang es. Wer etwas vergleichen will, braucht einen
     festen Rahmen; nur der Inhalt darin scrollt. */
  width:min(1180px, 100%); height:88vh;
  display:flex; flex-direction:column;
  background:var(--bg-2); border:2px solid var(--badge-border);
  /* Kleiner, kurzer Versatz. Ein weit aufspringendes Fenster wirkt unruhig -
     dieselbe Ueberlegung wie beim Einblenden der Abschnitte. */
  transform:translateY(10px);
  transition:transform .22s ease;
}
.fenster-lage.offen .fenster{ transform:translateY(0); }

/* ============================================================
   DER KNOPFHALTER
   ------------------------------------------------------------
   Ein Arcade-Knopf wird beim Druecken FLACHER - seine Hoehe nimmt ab.
   Damit das nach "gedrueckt" aussieht, muss die UNTERKANTE stehen
   bleiben und nur die Oberkante nachgeben.

   Auf der Seite loesen das die Knopfzeilen mit
       align-items:flex-end + min-height
   In der Titelleiste und in der Bildschau ging das nicht: Dort stand
   der Knopf mittig bzw. war fest positioniert. Beim Hovern schrumpfte
   deshalb die Titelleiste mit und das ganze Fenster sprang.

   Der Halter hat eine feste Hoehe und richtet den Knopf an seiner
   Unterkante aus. Damit kann sich nichts mehr um ihn herum bewegen.
   ============================================================ */

.knopf-halter{
  display:inline-flex; align-items:flex-end; gap:.6rem;
  height:var(--btn-sm-h); flex:none;
}

.fenster-leiste{
  display:flex; align-items:center; gap:1rem;
  /* Seitlich GENAU wie das Bildraster darunter - siehe
     --mass-fenster-polster. Vorher 1rem: Die Knoepfe standen dadurch
     ueber die Bilder hinaus. */
  padding:.85rem var(--mass-fenster-polster);
  background:var(--bg); border-bottom:2px solid var(--badge-border);
  /* GIBT IHRE HOEHE NICHT HER. Als Flex-Element von .fenster duerfte sie
     sonst schrumpfen - und dann standen die Knoepfe halb unter dem
     Bildraster. */
  flex:none;
  /* Feste Hoehe, damit der Knopf darin gedrueckt werden kann, ohne dass
     die Leiste selbst schmaler wird. */
  min-height:calc(var(--btn-sm-h) + 1.4rem);
}
.fenster-titel{
  font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:.78rem; line-height:1.6;
  color:var(--text);
  letter-spacing:.09em; text-transform:uppercase;
}
.fenster-zaehler{
  font-family:'JetBrains Mono', monospace; font-size:.72rem; color:var(--text-dim);
}
.fenster-leiste .luecke{ flex:1; }

/* Die Titelleiste traegt jetzt einen echten Knopf des Seitensystems
   (.btn .btn-sm). Der eigene Behelfsknopf ist entfallen. */

/* Deutlich mehr Innenabstand als der Rest der Seite. Das Fenster ist
   randvoll mit Bildern - ohne Luft am Rand wirkt es gedraengt. */
.fenster-koerper{ overflow:auto; padding:var(--mass-fenster-polster); }

/* ---- Filterzeile ----
   Sitzt zwischen Titelleiste und Raster und bleibt beim Scrollen stehen -
   bei vierzig Fotos will man nicht erst wieder hochscrollen, um die
   Gruppe zu wechseln. */

/* Kein eigener Balken mehr, sondern ein Teil der Leiste.

   height + align-items:flex-end sind KEIN Schmuck: Der Knopf wird beim
   Druecken flacher. Damit das nach "gedrueckt" aussieht, muss die
   Unterkante stehen bleiben und nur die Oberkante nachgeben. In einer
   Zeile mit align-items:center schrumpft er um seine Mitte und die
   Bewegung sieht verkehrt herum aus. Genau derselbe Grund wie beim
   .knopf-halter darueber. */
.fenster-filter{
  display:flex; align-items:flex-end; gap:.6rem; flex-wrap:wrap;
  height:var(--btn-sm-h); flex:none;
}
.fenster-filter[hidden]{ display:none; }

/* Auf schmalen Fenstern bricht die Leiste um. Dann steht die Filter-
   zeile wieder unter dem Titel - aber ohne zweiten Rahmen und ohne
   zweites Polster, also immer noch schmaler als bis Design 47. */
@media (max-width:820px){
  /* EINE Zeile: Filter links, "Close" rechts. Die Filter schieben sich
     seitwaerts, wenn sie nicht alle passen - die gewohnte Geste auf einem
     Handy, und besser als eine zweite Zeile, die Platz frisst, den die
     Bilder brauchen. */
  .fenster-leiste{ flex-wrap:nowrap; gap:.6rem; padding-left:1rem; padding-right:1rem; }

  /* WARUM HIER LUFT NACH OBEN UND UNTEN STEHT
     overflow-x:auto macht daraus einen Schiebekasten - und ein solcher
     schneidet ab, was nicht hineinpasst. Nach oben laesst er sich nicht
     einmal schieben.

     Die Knoepfe sind genau so hoch wie der Kasten war (--btn-sm-h), und
     ihr Schlagschatten ragt vier Punkte darueber hinaus. Also wurde oben
     abgeschnitten.

     height:auto plus Polster: Der Kasten richtet sich nach den Knoepfen,
     nicht umgekehrt. flex-end bleibt - der Knopf muss beim Druecken von
     OBEN nachgeben, die Unterkante steht. */
  .fenster-filter{
    flex-wrap:nowrap; flex:1 1 auto; min-width:0;
    height:auto; align-items:flex-end;
    padding-top:6px; padding-bottom:6px;
    overflow-x:auto;
    scrollbar-width:none;
  }
  .fenster-filter::-webkit-scrollbar{ display:none; }
  .fenster-filter .btn{ flex:none; }

  .fenster-leiste .luecke{ display:none; }
  .fenster-leiste .knopf-halter{ flex:none; }
  .fenster-titel, .fenster-zaehler{ flex:none; }
}

/* ---- Ansicht 1: Raster ---- */

/* ============================================================
   DIE GALERIE ALS MAUERWERK
   ------------------------------------------------------------
   Vorher ein Raster mit fester Kachelhoehe und object-fit:cover -
   alle Kacheln gleich gross, das Bild zugeschnitten. Ordentlich,
   aber: Ein Moodboard im Hochformat, ein Panorama und ein Quadrat
   wurden auf dasselbe Rechteck gestutzt. Bei einer Illustratorin
   heisst das, dass das Format der Arbeit verlorengeht, bevor man
   sie ueberhaupt geoeffnet hat - und das Format ist bei einem
   Plakat oder Moodboard ein Teil der Arbeit.

   Mauerwerk: Spalten, in denen jedes Bild seine eigenen
   Verhaeltnisse behaelt. NICHTS wird zugeschnitten. Gemacht mit
   CSS-Spalten, also ohne eine Zeile JavaScript.

   DER PREIS: Die Reihenfolge laeuft spaltenweise von oben nach
   unten, nicht zeilenweise von links nach rechts. Fuer eine
   Galerie, in der man schaut statt liest, ist das vertretbar.

   VORAUSSETZUNG: Die Maße stehen als Attribute am Bild (siehe
   script.js). Der Browser haelt den Platz damit frei, bevor das
   Bild geladen ist - ohne das springt das Mauerwerk beim Laden.
   ============================================================ */
/* Drei nebeneinanderliegende Spalten - KEIN columns.
   Der Unterschied ist der ganze Punkt: Bei columns verteilt der
   Browser den Inhalt und rechnet dabei staendig neu. Hier sind es
   drei gewoehnliche Kaesten, und das Skript legt jede Kachel einmal
   in einen davon. Danach bewegt sich nichts mehr.
   Die Spaltenzahl steht ebenfalls im Skript (siehe spaltenZahl) -
   sie muss dort stehen, weil dort verteilt wird. */
.werk-raster{
  display:flex; align-items:flex-start; gap:2rem;
}
.werk-spalte{
  flex:1; min-width:0;
  display:flex; flex-direction:column; gap:2rem;
}

.werk-kachel{
  display:block; position:relative; width:100%; padding:0;
  background:var(--bg-2); cursor:pointer; overflow:hidden;
  transition:transform .15s ease;
  /* Weisser Rahmen um jede Arbeit. Er sitzt auf der KACHEL und nicht auf
     dem Bild: Der Titel erscheint beim Darueberfahren als Band ueber dem
     unteren Bildrand und ist an der Kachel ausgerichtet - auf dem Bild
     laege er ueber dem Rahmen und schnitte ihn unten durch. */
  border:var(--mass-bild-rahmen) solid #fff;
}
.werk-kachel:hover{ transform:translateY(-3px); }
.werk-kachel:focus-visible{ outline:2px solid var(--brand-light); outline-offset:3px; }
/* height:auto - das Bild behaelt seine eigenen Verhaeltnisse.
   Genau das ist der Unterschied zum Raster. */
.werk-kachel img{ display:block; width:100%; height:auto; }

/* Der Titel erscheint erst beim Darueberfahren, als Band ueber dem
   unteren Bildrand. Dauerhaft sichtbar ergaben vierzig Titel eine
   zweite Textflaeche unter den Bildern - genau das wirkte "voll". */
.werk-kachel .titel{
  position:absolute; left:0; right:0; bottom:0;
  padding:.7rem .8rem; text-align:left;
  font-family:'Space Grotesk', sans-serif; font-size:.78rem;
  color:var(--text);
  background:linear-gradient(to top, rgba(8,8,11,0.92), rgba(8,8,11,0));
  opacity:0; transition:opacity .18s ease;
}
.werk-kachel:hover .titel,
.werk-kachel:focus-visible .titel{ opacity:1; }

@media (max-width:700px){
  .fenster-lage{ padding:0; }
  .fenster{ width:100%; height:100%; max-height:100vh; }
}
@media (prefers-reduced-motion:reduce){
  .fenster-lage, .fenster{ transition:none; }
}

/* ============================================================
   DIE BILDSCHAU – ein einzelnes Werk, formatfuellend
   ------------------------------------------------------------
   ALLES HIER IST position:fixed. Das ist der Grund, warum nichts
   mehr springt: Die Bedienelemente haengen am Fensterrand, nicht am
   Bild. Wechselt das naechste Werk von Hoch- auf Querformat, bewegt
   sich deshalb nur das Bild selbst.

   Vorher hing alles in einem normalen Fluss - beim Wechsel fiel die
   Buehne kurz auf null Hoehe zusammen und wuchs dann wieder. Das war
   das Aufblitzen.
   ============================================================ */

.bildschau{
  position:fixed; inset:0; z-index:210;
  /* Scrollbar - im eingepassten Zustand gibt es nichts zu scrollen, beim
     Hineinzoomen aber schon. */
  display:flex; overflow:auto;
  /* Fast deckend, nicht ganz: Das Raster schimmert schwach durch und
     man behaelt das Gefuehl, wo man herkommt. */
  background:rgba(4,4,6,0.97);
  opacity:0;
  transition:opacity .22s ease;   /* Dauer = BLENDE_MS in script.js */
}
.bildschau[hidden]{ display:none; }
.bildschau.offen{ opacity:1; }

/* Die Buehne. margin:auto zentriert das Bild in beide Richtungen und
   schneidet nichts ab, wenn es groesser ist als das Fenster.
   justify-content:center wuerde bei Ueberlaenge den Anfang abschneiden. */
.schau-buehne{
  margin:auto;
  padding:5.5rem 1rem 7rem;   /* Platz fuer die Knoepfe oben und unten */
}

.schau-bild{
  display:block;
  /* EINGEPASST.
     Das Bild ist so gross, wie es GANZ ins Fenster passt - nicht groesser.
     Zwei Anlaeufe daneben: volle Fensterbreite (Design 29) und eine feste
     Spaltenbreite von 1200px (Design 30) waren beide zu wuchtig; bei der
     Groesse faellt jedes Korn und jede Kompressionsspur auf.

     Zum Vergroessern gibt es die Zoomknoepfe und den Doppelklick - dann
     wird auch gescrollt. Wer sich ein Bild genau ansehen will, sagt das
     also selbst; von allein draengt sich nichts auf.

     Die Breite setzt das Skript ueber --bild-breite, siehe script.js
     unter GROESSE UND ZOOM. */
  width:var(--bild-breite, auto);
  height:auto;
  /* Derselbe Rahmen wie auf der Kachel. Dank box-sizing:border-box ist
     die Breite, die das Skript setzt, die AEUSSERE - das Bild wird also
     um vier Punkte schmaler, statt dass der Rahmen ueber den berechneten
     Platz hinausragt. */
  border:var(--mass-bild-rahmen) solid #fff;
}

.schau-oben-rechts{ position:fixed; top:1.4rem; right:max(1.4rem, calc(50% - 40rem)); z-index:2; }
.schau-zoom{ position:fixed; bottom:1.3rem; right:max(1.4rem, calc(50% - 40rem)); z-index:2; }

/* ---- DIE KLICKZONEN ----
   Zwei Streifen an den Fensterraendern. Im Ruhezustand unsichtbar; beim
   Darueberfahren erscheinen ein Dreieck und ein schwacher Verlauf, damit
   man sieht, wie weit die Zone reicht.

   IHRE BREITE IST ZUGLEICH DER FREIE RAND DES BILDES. Das Skript misst
   sie am Element und rechnet sie ab - deshalb kann ein Bild nie unter
   einer Zone liegen, egal wie das Fenster steht. Genau das war die
   Beschwerde an den alten Pfeilknoepfen.

   top:0/bottom:0 und z-index:1: Die Zonen liegen unter den Knoepfen
   (z-index:2), die deshalb weiterhin ihre Klicks bekommen. */
.schau-zone{
  position:fixed; top:0; bottom:0; z-index:1;
  /* MINDESTBREITE steht fest, die tatsaechliche setzt das Skript:
     Die Zone reicht bis an das Bild, damit zwischen ihr und dem Bild
     keine tote Flaeche bleibt. Nur die Mindestbreite geht in die
     Rechnung fuer die Bildgroesse ein - alles andere waere ein
     Zirkelschluss. Siehe zonenStellen() in script.js. */
  min-width:var(--schau-zone);
  width:var(--zone-jetzt, var(--schau-zone));
  border:0; padding:0; cursor:pointer; background:none;
  display:flex; align-items:center;
}
.schau-zone.links { left:0;  justify-content:flex-end;   padding-right:1.5rem; }
.schau-zone.rechts{ right:0; justify-content:flex-start; padding-left:1.5rem; }

/* Der Verlauf ist eine eigene Schicht. Sonst muesste er sich die
   Deckkraft mit dem Zeichen teilen - und das Zeichen soll dauerhaft
   zu sehen sein, der Verlauf erst beim Darueberfahren. */
.schau-zone::before{
  content:''; position:absolute; inset:0;
  opacity:0; transition:opacity .2s ease;
}
.schau-zone.links::before{
  background:linear-gradient(to right, rgba(163, 94, 70, .22), transparent);
}
.schau-zone.rechts::before{
  background:linear-gradient(to left, rgba(163, 94, 70, .22), transparent);
}
.schau-zone:hover::before,
.schau-zone:focus-visible::before{ opacity:1; }

/* DAUERHAFT SICHTBAR, nur gedaempft. Ihr Einwand war, dass man nicht
   erkennt, dass dort etwas zu klicken ist - ein Zeichen, das erst beim
   Darueberfahren erscheint, kann das nicht leisten: Man faehrt nur
   dorthin, wenn man schon weiss, dass es sich lohnt.

   position:relative haelt es ueber dem Verlauf. */
.schau-zone .zeichen{
  position:relative;
  color:var(--brand-light);
  opacity:.45; transition:opacity .2s ease;
}
.schau-zone:hover .zeichen,
.schau-zone:focus-visible .zeichen{ opacity:1; }
.schau-zone .dreieck{ width:16px; height:22px; }

/* IM VERGROESSERTEN ZUSTAND STUMM. Dort reicht das Bild ueber seinen
   freien Rand hinaus und liegt unter den Zonen - ein Ziehen zum
   Verschieben wuerde sonst auf einer Zone enden und blaettern.

   Ausgeblendet, aber NICHT display:none: Das Skript misst ihre Breite,
   um den freien Rand zu bestimmen. Eine Zone ohne Breite wuerde die
   Grundgroesse des Bildes verschieben, sobald man hineinzoomt. */
.bildschau.vergroessert .schau-zone{ opacity:0; pointer-events:none; }

/* ---- DIE BLENDE ----
   Beim Blaettern bleibt eine Kopie des alten Bildes an genau ihrer
   Stelle stehen und wird weggeblendet. Das neue Bild steht zu diesem
   Zeitpunkt schon darunter - es loest sich also eines im anderen auf.

   position:fixed mit den Maassen des alten Bildes: Haetten wir die
   Kopie in die Buehne gehaengt, wuerde sie beim naechsten Bild anderen
   Formats mitspringen. So bleibt sie liegen, wo sie war.

   Steht HINTER .schau-bild, damit width hier gewinnt - bei gleicher
   Spezifitaet entscheidet die Reihenfolge. */
.schau-abgang{
  position:fixed; z-index:1; pointer-events:none;
  left:var(--ab-x); top:var(--ab-y);
  width:var(--ab-w); height:auto;
  opacity:1; transition:opacity .3s ease;
}
.schau-abgang.weg{ opacity:0; }

/* Ein einzelnes Zeichen braucht eine Mindestbreite, damit alle
   Zeichenknoepfe gleich breit sind. */
.schau-pfeil .btn-face{ min-width:2.6rem; padding:0 .6rem; font-size:10px; }

.schau-fuss{
  position:fixed; left:0; right:0; bottom:1.3rem; z-index:2;
  display:flex; align-items:baseline; justify-content:center; gap:1rem;
  padding:0 6rem;
  /* Damit ein Klick daneben weiterhin die Schau schliesst. */
  pointer-events:none;
}
.schau-titel{
  font-family:'Space Grotesk', sans-serif; font-weight:700; font-size:.78rem; line-height:1.7;
  color:var(--text);
  letter-spacing:.09em; text-transform:uppercase;
}
.schau-zaehler{
  font-family:'JetBrains Mono', monospace; font-size:.75rem; color:var(--text-dim);
}

/* ---- Handy und schmale Fenster ----
   Auf dem Beruehrungsbildschirm blaettert man durch Wischen (siehe
   script.js). Die Pfeile bleiben trotzdem sichtbar, ruecken aber nach
   unten neben die Bildunterschrift, damit sie nicht mitten auf dem
   Bild liegen. */

@media (max-width:700px){
  .schau-buehne{ padding:4.5rem .5rem 6rem; }
  /* Alles in Daumennaehe an den unteren Rand. */
  .schau-oben-rechts{ top:auto; bottom:1rem; right:1rem; }
  /* Die Zonen bleiben, wo sie sind - an den Raendern. Nur schmaler:
     Auf einem Telefon ist Wischen die eigentliche Geste, und jeder
     Punkt, den die Zone nimmt, fehlt dem Bild. */

  /* Am Handy zoomt man mit zwei Fingern oder durch Doppeltippen.
     Zwei zusaetzliche Knoepfe waeren hier nur im Weg. */
  .schau-zoom{ display:none; }
  .schau-fuss{
    bottom:5.2rem; padding:0 1rem;
    flex-direction:column; align-items:center; gap:.35rem; text-align:center;
  }
  .fenster-filter{ padding:.8rem 1rem; }
}

@media (prefers-reduced-motion:reduce){
  .bildschau, .schau-bild{ transition:none; }
}

/* ============================================================
   VORSCHAUBILDER DER KARTEN: ZURUECKGENOMMEN, FARBE BEIM HOVERN
   ------------------------------------------------------------
   ZWEI BAUARTEN, und der Unterschied ist der ganze Punkt:

     Filter    veraendert die Farben DES BILDES SELBST.
     Ueberlage legt etwas DARUEBER und laesst das Bild in Ruhe -
               sie nimmt nur Licht weg.

   Ein Filter kann schmutzig wirken, eine Ueberlage nie. Genau daran
   sind Sepia (bis D42) und weniger Saettigung (D43-D45) gescheitert.

   Jetzt eine UEBERLAGE: ein Verlauf von unten. Oben bleibt das Bild
   frei, nach unten wird es dunkler. Die Karte waechst dadurch optisch
   aus dem Untergrund heraus, statt als Rechteck darauf zu liegen -
   und die Titel, die im Werk-Fenster ueber dem unteren Bildrand
   liegen, bekommen nebenbei ihren Kontrast geschenkt.

   Dazu: beim Darueberfahren weicht der Verlauf zurueck UND das Bild
   rueckt eine Spur naeher (1.05). Die Bewegung ist absichtlich winzig -
   sie soll auffallen, ohne dass man sie benennen kann.

   NUR AUF DEN KARTEN. Im Werk-Fenster und in der Bildschau liegt
   nichts ueber den Bildern: Dort IST die Farbe die Arbeit.

   Der Verlauf liegt auf ::after, das Bild auf ::before. Beide sitzen
   im .thumb und nicht auf dem Element selbst - sonst laegen sie auch
   ueber der Nummer und der Marke darin. Die Beschriftungen haben
   z-index:1 und bleiben dadurch aussen vor.

   WICHTIG: overflow:hidden, sonst tritt das herangefahrene Bild ueber
   den Rand der Karte hinaus.
   ============================================================ */

.feat .thumb,
.work .thumb,
.kategorie-karte{ overflow:hidden; }

/* --- Das Bild: leicht abgedunkelt, faehrt beim Hovern heran --- */
.feat .thumb::before,
.work .thumb::before{
  content:''; position:absolute; inset:0;
  background:inherit;
  filter:brightness(.9);
  transition:filter .3s ease, transform .45s ease;
}
.kategorie-bild{
  filter:brightness(.9);
  transition:filter .3s ease, transform .45s ease;
}

.feat:hover .thumb::before,
.work:hover .thumb::before,
.kategorie-karte:hover .kategorie-bild{ filter:none; transform:scale(1.05); }

/* --- Die Ueberlage: die weiche Unterkante ---
   FESTE HOEHE, kein Anteil der Bildhoehe. Das ist der ganze
   Unterschied zur Fassung bis zum 2026-08-29: Damals begann der
   Verlauf bei 30 Prozent und lief bis unten. Auf einer schmalen,
   einspaltigen Karte in voller Breite wurde daraus ein dunkler Balken
   quer ueber dem Bild - deshalb war er dort abgeschaltet.

   Mit fester Hoehe bleibt es bei jeder Kartengroesse dasselbe: die
   Unterkante des Bildes, die in den Kartentext uebergeht. Damit gilt
   die Regel jetzt ueberall. */
.feat .thumb::after,
.work .thumb::after{
  content:''; position:absolute; left:0; right:0; bottom:0;
  height:var(--mass-bild-verlauf); pointer-events:none;
  background:linear-gradient(to bottom, rgba(8,8,11,0), rgba(8,8,11,0.92));
  transition:opacity .3s ease;
}
/* Die Kategoriekarte traegt den Verlauf selbst, weil ihr Bild ein
   echtes <img> ist und kein Hintergrund. Ihre Unterkante liegt nicht
   am Kartenende, sondern bei der Bildhoehe - deshalb wird von dort
   nach oben gerechnet. */
.kategorie-karte{ position:relative; }
.kategorie-karte::after{
  content:''; position:absolute; left:0; right:0;
  top:calc(var(--mass-galerie-bild) - var(--mass-bild-verlauf));
  height:var(--mass-bild-verlauf); pointer-events:none;
  background:linear-gradient(to bottom, rgba(8,8,11,0), rgba(8,8,11,0.92));
  transition:opacity .3s ease;
}

.feat:hover .thumb::after,
.work:hover .thumb::after,
.kategorie-karte:hover::after{ opacity:.15; }

/* ============================================================
   AUF SCHMALEN FENSTERN LIEGT NICHTS AUF DEN BILDERN
   ------------------------------------------------------------
   DIESER BLOCK MUSS HIER STEHEN, direkt hinter den Regeln, die er
   aufhebt. Er stand zuerst vierhundert Zeilen weiter oben in einem
   anderen 700er-Block - bei gleicher Spezifitaet gewinnt die SPAETERE
   Regel, also der Verlauf. Die Nutzerin sah den Balken deshalb
   weiterhin, obwohl die Regel dagegen in der Datei stand.

   WARUM DER VERLAUF HIER STOERT
   Auf dem Schirm ist eine Karte klein und der Verlauf ein Abklingen
   zum unteren Rand. Auf dem Handy ist die Karte einspaltig und volle
   Breite - aus dem Abklingen wird ein dunkler Balken quer ueber dem
   Bild. Dieselbe Regel, zwei voellig verschiedene Wirkungen.

   Das Heranfahren entfaellt gleich mit: Ohne Mauszeiger ist es eine
   Bewegung, die niemand ausloesen kann.
   ============================================================ */

@media (max-width:700px){
  /* DER VERLAUF BLEIBT. Bis zum 2026-08-29 stand hier ein
     display:none fuer ihn - noetig, solange er einen ANTEIL der
     Bildhoehe einnahm und dadurch auf einer einspaltigen Karte zum
     Balken wurde. Mit fester Hoehe an der Unterkante gibt es diesen
     Unterschied nicht mehr, und die Karten sehen auf jedem Geraet
     gleich aus.

     WAS HIER BLEIBT, ist das Heranfahren: Ohne Mauszeiger ist es eine
     Bewegung, die niemand ausloesen kann. */
  .feat .thumb::before,
  .work .thumb::before,
  .kategorie-bild{ filter:none; transform:none; }
}

/* ============================================================
   KONTAKT – Insert Coin
   ============================================================ */

.insert-coin{
  background:var(--bg-2); border:2px solid var(--badge-border);
  padding:var(--mass-coin-polster); text-align:center;
}
.insert-coin .blink-title{
  font-family:'Press Start 2P', monospace; font-size:1rem; line-height:1.7;
  color:var(--accent); margin-bottom:1.5rem;
  animation:blink 1s steps(1) infinite;
}

/* Der Brief oeffnet sich und schiebt einen Zettel heraus
   (tools/build_brief.py). Die Bewegung steckt in der Datei selbst - sechs
   Bilder mit langen Ruhezeiten dazwischen. Hier braucht es deshalb keine
   Animation, nur die richtige Groesse.

   ER DREHT SICH NICHT. Ein Umschlag, der sich um die eigene Achse dreht,
   sieht aus wie ein Sammelgegenstand im Spiel; ein Umschlag, der sich
   oeffnet, sagt "schreib mir".

   GRUNDGROESSE 32px, nicht 16 wie der Coin. Bei 24 mussten die Schraegen
   in Zweierschritten laufen, und das sah grob aus; bei 32 laufen sie in
   Einerschritten. Genau diese feine Treppe erkennt man als Pixel-Art.
   Dazu fuenf Farbtoene statt zwei - Licht oben links, Schatten unten
   rechts. Eine Flaeche aus einer Farbe sieht flach aus, egal wie fein
   das Raster ist.

   Angezeigt wird in Vielfachen von 32 (32 / 64 / 96). Der Coin bleibt bei
   Vielfachen von 16 - jede Grafik hat ihr eigenes Raster, die Regel lautet
   "Vielfache der Grundgroesse". Siehe "09 Pixelraster der Grafik". */
.insert-coin .brief{
  display:block; margin:0 auto 1.5rem;
  width:var(--mass-brief); height:var(--mass-brief);
  image-rendering:pixelated;
}


.insert-coin p{
  font-family:'Space Grotesk', sans-serif; font-size:.9rem; line-height:1.9;
  color:var(--text-dim); max-width:32rem; margin:0 auto 2.25rem;
}
.contact-row{ display:flex; gap:.9rem; justify-content:center; flex-wrap:wrap; align-items:flex-end; min-height:var(--btn-h); }

/* ---- Kontaktformular ----
   Aufklappen über eine echte Höhe in Pixeln, die das Skript vor dem Öffnen
   misst und als --h übergibt. Vorher lief es über grid-template-rows 0fr->1fr;
   diese Einheit interpolieren Browser nur grob, das war das Holpern. */
.form-wrap{
  height:0; overflow:hidden;
  /* Länger und mit sehr weich auslaufender Kurve.
     Bewusst OHNE will-change: siehe die Erklärung beim Einblenden weiter unten. */
  transition:height .65s cubic-bezier(.16, 1, .3, 1);
}
.form-wrap.offen{ height:var(--h, 0); }

.form-wrap .contact-form{
  opacity:0; transform:translate3d(0,-10px,0);
  /* ohne Verzögerung: Höhe und Inhalt bewegen sich gemeinsam,
     das wirkt wie ein Vorgang statt wie zwei. */
  transition:opacity .6s ease, transform .6s cubic-bezier(.16, 1, .3, 1);
}
.form-wrap.offen .contact-form{ opacity:1; transform:translate3d(0,0,0); }

/* Diese Regel ist in Design 10 versehentlich mitentfernt worden. Ohne sie
   erbte das Formular die zentrierte Ausrichtung des Kontaktbereichs, und die
   Felder zogen sich über die ganze Breite der Kachel.
   padding-top gibt dem Formular Luft zum „Email"-Button darüber. */
.contact-form{
  display:grid; grid-template-columns:1fr 1fr; gap:1.1rem;
  text-align:left; padding-top:3rem; max-width:44rem; margin:0 auto;
}
.contact-form label{ display:flex; flex-direction:column; gap:.5rem; }
.contact-form label.weit{ grid-column:1 / -1; }
.contact-form label span{
  font-family:'JetBrains Mono', monospace; font-size:.72rem;
  text-transform:uppercase; letter-spacing:.1em; color:var(--brand-mid);
}
.contact-form input,
.contact-form textarea{
  font-family:'Space Grotesk', sans-serif; font-size:.88rem;
  color:var(--text); background:rgba(255,255,255,0.03);
  border:2px solid var(--badge-border);
  padding:.75rem .9rem; width:100%; resize:vertical;
  transition:border-color .15s ease, background .15s ease;
}
.contact-form input:focus,
.contact-form textarea:focus{
  outline:none; border-color:var(--accent);
  background:rgba(255,255,255,0.06);
}
/* Linksbündig wie die Beschriftungen darüber – so hat das Formular eine
   durchgehende linke Kante. */
/* min-height wie bei allen anderen Button-Zeilen: Die Buttons schrumpfen
   beim Hovern von 66px auf 59px. Ohne feste Zeilenhöhe würde sich dabei das
   Formular verschieben – genau wie früher im Hero. */
.form-fuss{
  grid-column:1 / -1;
  display:flex; justify-content:flex-start; align-items:flex-end;
  margin-top:.5rem; min-height:var(--btn-h);
}
@media (max-width:700px){
  .contact-form{ grid-template-columns:1fr; }
}

/* Die Fusszeile traegt seit Design 57 die beiden Pflichtseiten.
   Auf schmalen Fenstern untereinander statt nebeneinander - zwei
   Verweise und eine Zeile Text passen dort nicht in eine Reihe. */
.fuss{
  display:flex; flex-wrap:wrap; align-items:center;
  justify-content:center; gap:.6rem 1.4rem;
}
/* Die vollstaendige Fassung der Klarstellung. Sie steht im Fuss, weil
   sie auf JEDER Seite gelten soll - und weil dort hingehoert, was
   erklaert statt anzupreisen. flex-basis:100% zwingt sie in eine eigene
   Zeile, sonst quetscht sie sich neben die Verweise. */
.fuss-privat{
  flex-basis:100%; max-width:70ch; margin:0 auto;
  font-size:.9em; line-height:1.7; opacity:.75;
}
.fuss-links{ display:flex; gap:1.2rem; }
.fuss-links a{
  color:var(--text-dim); text-decoration:none;
  border-bottom:1px solid var(--badge-border);
}
.fuss-links a:hover{ color:var(--brand-light); border-bottom-color:var(--brand-light); }
.fuss-links a:focus-visible{ outline:2px solid var(--brand-light); outline-offset:3px; }

footer{
  padding:2.5rem 6vw; text-align:center;
  font-family:'Space Grotesk', sans-serif; font-size:.72rem; color:var(--text-dim);
  border-top:2px solid var(--badge-border);
}

/* ============================================================
   ANPASSUNGEN
   ============================================================ */

/* ------------------------------------------------------------
   ZWEITE MASSSTABSSTUFE – Fenster bis 1920px
   ------------------------------------------------------------
   Auf 2560px wirkte die Seite ruhig, auf 1920px zu groß. Der Grund ist
   einfach: Die Maße waren feste Pixel, das Fenster aber ein Drittel
   schmaler. Damit füllt derselbe Block deutlich mehr vom Bildschirm.

   Hier wird deshalb NUR der Maßstab umgeschaltet – kein Layout, keine
   Farben, keine Schriftart. Es sind exakt die Werte aus Design 20.

   Ein 1920er-Monitor meldet rund 1905px (Bildlaufleiste geht ab) und
   fällt damit hier hinein; ein 2560er meldet rund 2545px und behält die
   großen Werte. Bei Windows-Skalierung von 125 % rutscht ein 2560er auf
   2048px – ebenfalls noch oberhalb der Grenze.
   ------------------------------------------------------------ */

@media (max-width:1920px){
  :root{
    --mass-abschnitt:      5rem;
    --mass-breite:         1180px;
    --mass-kopf:           2.25rem;
    --mass-luecke:         1.25rem;
    --mass-feat-bild:      200px;
    --mass-feat-text:      1.2rem;
    /* (1180 + 14,4) / (210 + 14,4) = 5,32 -> 5 */
    --mass-skill-spalte:   210px;
    --mass-skill-luecke:   .9rem;
    --mass-skill-hoehe:    68px;
    --mass-galerie-spalte: 260px;
    --mass-galerie-bild:   210px;
    --mass-bild-verlauf:    76px;   /* 96 -> 76, wie 270 -> 210 */
    --mass-galerie-text:   1.15rem;
    --mass-coin-polster:   2.5rem;
    --mass-brief:          64px;    /* bleibt - 32px waere zu klein fuer den Zettel */
    --mass-karte-polster:  1.4rem;
  }
}


/* Skelett bewusst eine Rasterstufe kleiner als zuvor: 460 statt 690.
   Dazwischen gibt es nichts – erlaubt sind nur Vielfache von 230.
   Zum Zurückdrehen hier wieder --art-w:690px / --art-trim:139px setzen
   und dasselbe im Block für max-width:1120px. */

@media (max-width:1120px){
  .hero-inner{ grid-template-columns:1fr; gap:2.5rem; align-items:stretch; }
  .hero{ padding:7rem 0 4rem; }   /* seitlich polstert .hero-inner */
  /* Regel 1: nächstkleinere Rasterstufe */
  h1{ font-size:16px; }
  .section-title{ font-size:16px; }
  /* LINKSBUENDIG, sobald der Hero einspaltig steht. Der Text darunter
     beginnt links; eine mittige Grafik daneben ergibt zwei Kanten, wo
     eine reicht. Auf breiten Fenstern bleibt sie mittig - dort steht
     sie in einer eigenen Spalte und hat keine Kante zu teilen. */
  .hero-visual{ order:-1; --art-w:460px; --art-trim:92px; justify-content:flex-start; }
  .featured-grid{ grid-template-columns:1fr; }
  .about-grid{ grid-template-columns:1fr; }
}

/* ---- Die Navigation faehrt beim Herunterscrollen weg ----
   Sie ist das dauerhafteste Element auf dem Bild. Weggefahren gibt sie
   den Blick frei, beim Hochscrollen ist sie sofort wieder da.

   WICHTIG - 'top' und nicht 'transform':
   Ein transform haelt das Element dauerhaft in einer eigenen Grafikebene,
   und darin wird Schrift weich gerastert. Das hat in Design 30/31 drei
   Anlaeufe gekostet. Die Leiste ist EIN Element; 'top' zu bewegen kostet
   hier weniger. */
.nav-wrap{ transition:top .28s ease; }
body.nav-weg .nav-wrap{ top:-120px; }

/* ============================================================
   NAVIGATION AUF SCHMALEN FENSTERN
   ------------------------------------------------------------
   Fuenf Verknuepfungen nebeneinander brauchen mehr Platz, als ein Handy
   hat - die Leiste lief aus dem Bild heraus. Ab 900px klappt sie deshalb
   auf Knopfdruck nach unten auf.

   Der Knopf ist bewusst KEIN Arcade-Knopf: Er sitzt in der Navigations-
   platte, und die ist nach der Formensprache der Seite eine Flaeche.
   Drei Striche, die sich beim Oeffnen zu einem Kreuz legen - mehr braucht
   es nicht.
   ============================================================ */

.nav-knopf{
  display:none;   /* wird erst im schmalen Fenster eingeblendet */
  position:relative; flex:none;
  width:34px; height:34px; padding:0;
  background:none; border:0; cursor:pointer;
}
.nav-strich{
  position:absolute; left:7px; width:20px; height:2px;
  background:var(--text);
  transition:transform .18s ease, opacity .18s ease;
}
.nav-strich:nth-child(1){ top:11px; }
.nav-strich:nth-child(2){ top:16px; }
.nav-strich:nth-child(3){ top:21px; }

/* Aufgeklappt: der obere und der untere Strich legen sich zum Kreuz,
   der mittlere verschwindet. */
.nav-knopf[aria-expanded="true"] .nav-strich:nth-child(1){ transform:translateY(5px) rotate(45deg); }
.nav-knopf[aria-expanded="true"] .nav-strich:nth-child(2){ opacity:0; }
.nav-knopf[aria-expanded="true"] .nav-strich:nth-child(3){ transform:translateY(-5px) rotate(-45deg); }

.nav-knopf:focus-visible{ outline:2px solid var(--brand-light); outline-offset:2px; }

@media (max-width:900px){
  .nav-knopf{ display:block; width:28px; height:28px; }

  /* Die Platte wird zur Spalte: oben Logo und Knopf, darunter die Liste. */
  .nav{ flex-wrap:wrap; row-gap:0; gap:.65rem; padding:.55rem .75rem; }

  /* flex:none statt flex:1 - sonst streckt sich das IJ ueber allen freien
     Platz und schiebt den Knopf an den rechten Rand. Der Trennstrich
     hinter dem Logo ist hier ohnehin ausgeblendet, also faellt auch sein
     Innenabstand weg. Jetzt stehen beide nebeneinander, und die Leiste ist
     nur so breit wie ihr Inhalt. */
  .nav-logo{ flex:none; padding-right:0; }

  /* Die Leiste soll nicht mehr sein als IJ, ein Abstand und drei Striche.
     Enger gepolstert und mit kleinerem Knopf: 32 + 10 + 28 + 2 x 12
     ergibt rund 94px. */
  .nav-strich{ left:4px; width:20px; }
  .nav-strich:nth-child(1){ top:8px; }
  .nav-strich:nth-child(2){ top:13px; }
  .nav-strich:nth-child(3){ top:18px; }

  /* DIE LISTE WIRD EINE PLATTE UNTER DER LEISTE.
     ----------------------------------------------------------------
     Vorher stand sie als umbrechende Zeile IN der Leiste - und hielt sie
     damit breit. Denn die natuerliche Breite eines umbrechenden
     Flex-Kastens ist seine MAX-CONTENT-Breite: die Breite, bei der alles
     in EINE Zeile passt. In einer Zeile stuenden Logo, Knopf UND die
     ganze Menueliste nebeneinander. Dass die Liste height:0 hat, aendert
     daran nichts - fuer die Breite zaehlt ihr Inhalt weiter.

     position:absolute nimmt sie aus dieser Rechnung heraus. Die Leiste
     misst danach nur noch Logo und Knopf, und die Platte bekommt ihre
     eigene Mindestbreite. Beide bedingen sich nicht mehr gegenseitig.

     Sie braucht jetzt einen eigenen Untergrund und Rahmen - sie liegt ja
     nicht mehr in der Leiste, sondern darunter. */
  /* GESCHLOSSEN MUSS SIE UNSICHTBAR SEIN, nicht nur flach.
     height:0 allein reicht nicht: Mit 2px Rahmen oben und unten bleibt
     ein 4px hoher Kasten stehen - 13rem breit, direkt unter der Leiste.
     Genau das war der "merkwuerdige Balken". Der Weichzeichner malte
     zusaetzlich einen verschmierten Streifen dorthin.

     Deshalb bekommt sie Rahmen, Untergrund und Weichzeichner ERST beim
     Aufklappen. Geschlossen ist sie ein Nichts von 0 x 0. */
  /* DIE LEISTE WAECHST MIT.
     Geschlossen ist sie nur so breit wie Logo und Knopf, rund 94px. Die
     Platte darunter misst 13rem. Beim Aufklappen sprang die Kante
     deshalb heraus, und man sah zwei verschieden breite Kaesten
     uebereinander.

     Jetzt nimmt die Leiste beim Aufklappen dieselbe Breite an - mit
     derselben Dauer und derselben Kurve wie die Hoehe der Platte, damit
     es EINE Bewegung ist und nicht zwei. Die Klasse setzt das Skript
     zusammen mit dem Aufklappen.

     13rem minus die zwei Rahmen der Platte, damit beide Aussenkanten
     genau uebereinanderliegen: Die Platte sitzt mit left:-2px zwei
     Punkte weiter links und ist vier Punkte breiter. */
  .nav{ transition:min-width .22s ease; }
  .nav.menue-offen{ min-width:13rem; }

  .nav-links{
    position:absolute; top:calc(100% + 2px); left:-2px;
    min-width:13rem;
    border:0 solid var(--badge-border);
    background:none;
    /* Die Hoehe wird beim Aufklappen gemessen und als --h gesetzt -
       dieselbe Loesung wie beim Kontaktformular. Ueber height laesst sich
       weich blenden, ueber 'auto' nicht. */
    flex-direction:column; align-items:stretch; gap:0;
    height:0; overflow:hidden;
    transition:height .22s ease;
  }
  /* + 4px, weil scrollHeight den Rahmen nicht mitzaehlt - ohne das waere
     der letzte Eintrag um vier Punkte beschnitten. */
  .nav-links.offen{
    height:calc(var(--h, 0px) + 4px);
    border-width:2px;
    background:rgba(12,12,17,0.94);
    backdrop-filter:blur(12px);
    -webkit-backdrop-filter:blur(12px);
  }
  /* Der Rahmen der Platte macht die erste Trennlinie ueberfluessig. */
  .nav-links li{ border-top:2px solid var(--badge-border); }
  .nav-links li:first-child{ border-top:0; }
  .nav-links a{ padding:.85rem 1rem; }
  .nav-logo::after{ display:none; }

  /* ---- Aus dem frueheren zweiten 900er-Block ----
     Bis Design 62 stand das alles ein zweites Mal weiter unten in der
     Datei und hat die Regeln hier oben ueberschrieben. Ein Breakpoint
     gehoert an EINE Stelle. */
  /* 6vw, nicht 4vw: Der Hero und jeder Abschnitt stehen auf 6vw, die
     Leiste auf breiten Fenstern ebenfalls. Eine eigene Zahl hier hiess
     nur, dass sie als einzige nicht auf der Kante stand. */
  .nav-wrap{ padding-left:6vw; padding-right:6vw; justify-content:flex-start; }
  .nav-links .lbl{ font-size:8px; }

  /* Mehr Luft unten als oben: Unter dem letzten Abschnitt folgt der
     Fuss, und ohne Abstand klebt beides aneinander. */
  section{ padding:4rem 6vw 5rem; }
  .insert-coin{ padding:2.5rem 1.5rem; }
}

@media (max-width:789px){
  .hero-visual{ --art-w:460px; --art-trim:92px; }
}

@media (max-width:540px){
  .hero-visual{ --art-w:230px; --art-trim:46px; }
}

/* ---- Die drei Knoepfe im Hero in EINE Zeile ----
   Gerechnet fuer 360px Fensterbreite: 6vw Rand je Seite laesst 316px,
   zwei Luecken zu .5rem lassen 300px fuer die Knoepfe. Mit den Werten
   hier brauchen sie zusammen rund 258px.

   Nur die Beschriftung wird kleiner, nicht der Knopf: Hoehe, Sockel und
   Druckweg haengen an --btn-h und bleiben unangetastet. */
@media (max-width:560px){
  .cta-row{ gap:.5rem; flex-wrap:nowrap; }
  .cta-row .btn-face{ font-size:.62rem; padding:0 .55rem; gap:.35rem; letter-spacing:.06em; }
  .cta-row .btn-social .btn-face{ padding:0 .7rem; }
  .cta-row .btn-face svg{ width:12px; height:12px; }
}

@media (prefers-reduced-motion:reduce){
  *{ animation:none !important; transition:none !important; }
  html{ scroll-behavior:auto; }
}

/* ============================================================
   DER BILDLAUFBALKEN
   ------------------------------------------------------------
   MUSS ER SEIN? Ja. Er ist die einzige Anzeige, WIE VIEL Seite
   noch kommt - eine Seite ohne Balken fuehlt sich bodenlos an.
   Verstecken laesst er sich (overflow:overlay, negative Ecken),
   aber es kostet mehr, als es bringt: Man kann dann nicht mehr
   greifen und ziehen, und auf dem Handy ist er ohnehin
   unsichtbar, solange man nicht scrollt.

   ALSO NICHT WEG, SONDERN LEISE. Er war ein Fremdkoerper, weil
   er in Windows-Grau und mit runden Enden kam - auf einer Seite,
   auf der nichts rund und nichts grau ist.

   Jetzt: 10px schmal, eckig, in den Farben der Seite. Der
   Schieber traegt denselben Verlauf wie die Kappe der dunklen
   Knoepfe (#2c2c35 -> #191920) und wird beim Anfassen zum
   Markenton. Die Bahn ist der Seitenuntergrund mit einer
   Trennlinie - dieselbe Farbe wie jeder Rahmen der Seite.

   ZWEI SCHREIBWEISEN, ein Ergebnis:
     ::-webkit-scrollbar   Chrome, Edge, Safari - genaue Kontrolle
     scrollbar-color       Firefox - nur Schieber und Bahn

   Firefox kann keine Verlaeufe im Schieber. Dort steht der
   mittlere Ton als Vollton. Das ist der ganze Unterschied.

   GILT UEBERALL: Seite, Werk-Fenster, jeder Bereich mit eigenem
   Bildlauf. Deshalb steht es auf * und nicht auf body.
   ============================================================ */

*{
  scrollbar-width:thin;
  scrollbar-color:#2c2c35 var(--bg);
}

::-webkit-scrollbar{ width:10px; height:10px; }

::-webkit-scrollbar-track{
  background:var(--bg);
  border-left:2px solid var(--badge-border);
}

/* Eckig, mit einer hellen Oberkante - genau wie die Kappe eines
   Knopfes. Der Balken ist damit erkennbar Teil desselben Systems. */
::-webkit-scrollbar-thumb{
  background:linear-gradient(180deg, #2c2c35, #191920);
  box-shadow:inset 0 2px 0 rgba(255,255,255,0.14);
  border:0;
}
::-webkit-scrollbar-thumb:hover{
  background:linear-gradient(180deg, var(--brand-dark), var(--brand-deep));
  box-shadow:inset 0 2px 0 rgba(255,255,255,0.22);
}
::-webkit-scrollbar-thumb:active{
  background:linear-gradient(180deg, var(--brand-mid), var(--brand-dark));
}

/* Die beiden Pfeilkaesten an den Enden. Sie erben sonst das
   Betriebssystem und sind das einzige Graue, das uebrig bleibt. */
::-webkit-scrollbar-button{ display:none; }
::-webkit-scrollbar-corner{ background:var(--bg); }

/* Im Werk-Fenster liegt der Balken auf dem dunkleren Kartenton.
   Ohne das setzte sich die Bahn hell davon ab. */
.fenster-koerper::-webkit-scrollbar-track{ background:var(--bg-2); }
.fenster-koerper{ scrollbar-color:#2c2c35 var(--bg-2); }


/* ============================================================
   LESEFORTSCHRITT – dünne Leiste am oberen Rand
   ------------------------------------------------------------
   Die Breite setzt das Skript zur Laufzeit über die Variable --p.
   Deshalb steht hier nur der Startwert 0 %.
   ============================================================ */

.progress-track{
  position:fixed; top:0; left:0; right:0;
  height:3px; z-index:100; pointer-events:none;
}
.progress-bar{
  height:100%;
  width:var(--p, 0%);
  background:linear-gradient(90deg,
    var(--brand-dark) 0%,
    var(--brand-mid) 50%,
    var(--brand-light) 100%);
  box-shadow:0 0 8px 1px rgba(241,177,132,0.55);
  transition:width .08s linear;
}

/* ============================================================
   STERNE – sparsam, hinter allem, bleiben beim Scrollen stehen
   ------------------------------------------------------------
   Positionen stecken in CSS statt in style-Attributen, damit HTML
   und CSS getrennt bleiben. Reihenfolge = Reihenfolge im Markup.
   ============================================================ */

.starfield{
  position:fixed; inset:0;
  z-index:-1; pointer-events:none; overflow:hidden;
}
.star{
  --x:50%; --y:50%; --size:2px; --order:0;
  --offset:320ms; --duration:3400ms;
  position:absolute;
  left:var(--x); top:var(--y);
  width:var(--size); height:var(--size);
  background:#fff; border-radius:50%;
  transform:translate(-50%,-50%);
  opacity:0;
  animation:starblink var(--duration) calc(var(--order) * var(--offset)) ease-in-out infinite;
}
@keyframes starblink{
  0%{ opacity:0; }
  50%{ opacity:.85; }
  100%{ opacity:0; }
}

.starfield .star:nth-child(1){ --x:6%; --y:9%; --size:2px; --order:0; }
.starfield .star:nth-child(2){ --x:14%; --y:22%; --size:1px; --order:3; }
.starfield .star:nth-child(3){ --x:22%; --y:6%; --size:2px; --order:6; }
.starfield .star:nth-child(4){ --x:31%; --y:16%; --size:1px; --order:1; }
.starfield .star:nth-child(5){ --x:9%; --y:38%; --size:3px; --order:4; }
.starfield .star:nth-child(6){ --x:18%; --y:52%; --size:1px; --order:7; }
.starfield .star:nth-child(7){ --x:5%; --y:68%; --size:2px; --order:2; }
.starfield .star:nth-child(8){ --x:13%; --y:83%; --size:1px; --order:5; }
.starfield .star:nth-child(9){ --x:26%; --y:74%; --size:2px; --order:8; }
.starfield .star:nth-child(10){ --x:34%; --y:92%; --size:1px; --order:0; }
.starfield .star:nth-child(11){ --x:44%; --y:5%; --size:1px; --order:6; }
.starfield .star:nth-child(12){ --x:52%; --y:18%; --size:2px; --order:2; }
.starfield .star:nth-child(13){ --x:61%; --y:8%; --size:1px; --order:9; }
.starfield .star:nth-child(14){ --x:69%; --y:27%; --size:2px; --order:4; }
.starfield .star:nth-child(15){ --x:78%; --y:12%; --size:3px; --order:1; }
.starfield .star:nth-child(16){ --x:87%; --y:31%; --size:1px; --order:7; }
.starfield .star:nth-child(17){ --x:94%; --y:17%; --size:2px; --order:3; }
.starfield .star:nth-child(18){ --x:72%; --y:58%; --size:1px; --order:5; }
.starfield .star:nth-child(19){ --x:83%; --y:71%; --size:2px; --order:8; }
.starfield .star:nth-child(20){ --x:92%; --y:56%; --size:1px; --order:0; }
.starfield .star:nth-child(21){ --x:66%; --y:88%; --size:2px; --order:6; }
.starfield .star:nth-child(22){ --x:88%; --y:94%; --size:1px; --order:2; }
.starfield .star:nth-child(23){ --x:48%; --y:63%; --size:1px; --order:9; }
.starfield .star:nth-child(24){ --x:57%; --y:79%; --size:2px; --order:4; }




/* ============================================================
   EINBLENDEN BEIM SCROLLEN
   ------------------------------------------------------------
   Bewusst sparsam: Nur die fünf Abschnitte tragen .reveal, nicht
   mehr jede Überschrift und jedes Raster einzeln. Vorher waren es
   elf Elemente – jedes musste beim Umschalten als eigene Grafik-
   ebene gezeichnet werden, und genau das hat geflackert.

   Auch bewusst KEIN translate3d mehr: Das hätte für jeden Abschnitt
   dauerhaft eine große Ebene im Speicher gehalten. Ein kleiner
   2D-Versatz genügt völlig.
   ============================================================ */

.reveal{
  opacity:0;
  transform:translateY(8px);
  transition:opacity .5s ease, transform .5s ease;
}
/* transform:none, NICHT translateY(0).
   ------------------------------------------------------------------
   Das ist der Grund, warum die Ueberschriften und Kartentitel weich
   aussahen, der Name im Hero aber gestochen scharf war: Der Hero steckt
   in keinem .reveal, alle fuenf Abschnitte schon.

   Ein Element mit einem transform - auch mit translateY(0), das nichts
   verschiebt - bleibt dauerhaft in einer eigenen Grafikebene. Text wird
   darin anders gerastert, und -webkit-font-smoothing:none greift dort
   nicht mehr durch. Eine Pixelschrift verliert dadurch genau die harten
   Kanten, von denen sie lebt.

   transform:none loest die Ebene nach der Bewegung wieder auf. Die
   Einblendung selbst bleibt unveraendert - nur der Ruhezustand ist jetzt
   wirklich ein Ruhezustand.

   MERKSATZ: translateY(0) ist nicht dasselbe wie kein transform. */
.reveal.sichtbar{ opacity:1; transform:none; }

@media (prefers-reduced-motion:reduce){
  .reveal{ opacity:1; transform:none; transition:none; }
}

/* DER ZURÜCK-BUTTON stand hier bis zum 2026-08-29 (rund zwanzig Zeilen).
   Er ist die Navigationshilfe der Archiv-Schnappschüsse, und die tragen
   jeweils ihr eigenes Stylesheet. Dieses hier gehört der lebenden Seite
   und dem Schau-Labor; in beiden kommt .back-btn nicht vor.
   Die Regeln stehen unverändert in jedem Snapshot unter archiv/. */


/* ============================================================
   DER EINGANGSBILDSCHIRM
   ------------------------------------------------------------
   Aus dem Coin-Labor uebernommen, Fassung B. Zwei Abweichungen auf
   Wunsch der Nutzerin:
     - KEIN sichtbarer Rahmen. Bildroehrenlinien und Schein genuegen,
       damit es nach Geraet aussieht; die Blende drumherum wirkte zu
       schwer fuer eine "ganz kleine Spielerei".
     - Statt eines flachen Schlitzes eine BOX, in die der Coin faellt.

   Drei Regeln, die ihn von einem Aergernis unterscheiden - alle im
   Skript umgesetzt: nur einmal je Besuch, mit der Tastatur bedienbar,
   und bei prefers-reduced-motion erscheint er gar nicht.
   ============================================================ */

.intro{
  position:fixed; inset:0; z-index:900;
  display:flex; align-items:center; justify-content:center;
  background:var(--bg);
  transition:opacity .45s ease;
}
.intro[hidden]{ display:none; }
.intro.faellt-ab{ opacity:0; pointer-events:none; }

body.intro-offen{ overflow:hidden; }

/* Der Schein der Bildroehre. Sehr zurueckhaltend - ein starker Schein
   saehe nach Effekt aus und nicht nach Geraet. */
.intro-schirm{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  box-shadow:inset 0 0 160px rgba(163,94,70,0.20);
}
/* Zeilen wie auf einer Bildroehre. 4px Abstand, damit sie auch auf
   dichten Bildschirmen als Linien lesbar bleiben und nicht flimmern. */
.intro-linien{
  position:absolute; inset:0;
  background:repeating-linear-gradient(
    to bottom,
    rgba(255,255,255,0.035) 0px,
    rgba(255,255,255,0.035) 1px,
    transparent 1px,
    transparent 4px
  );
}

.intro-mitte{
  position:relative; z-index:2;
  display:flex; flex-direction:column; align-items:center; gap:1.8rem;
}

.intro-werfen{
  /* 2.5rem Abstand statt 1rem: Der Abstand IST der Fallweg. Bei 1rem
     plumpste die Muenze nur 40 Pixel weit, das sah nach nichts aus. */
  display:flex; flex-direction:column; align-items:center; gap:2.5rem;
  background:none; border:0; padding:1rem; cursor:pointer;
}
/* Der Fokusring umschliesst Muenze UND Box - beide sitzen in diesem
   einen Knopf. Sichtbar war er, weil das Skript den Knopf beim Oeffnen
   angesprungen hat; das faellt jetzt weg.

   Die Regel bleibt trotzdem stehen: Wer mit der Tabulatortaste hierher
   kommt, MUSS sehen, wo er ist. Nur von allein zeigt sie sich nicht mehr. */
.intro-werfen:focus-visible{ outline:2px solid var(--brand-light); outline-offset:4px; }

.intro-coin{
  display:block; position:relative; z-index:2;
  /* 64 = 4 x 16. Der Coin ist Pixel-Art im 16er-Raster, krumme Groessen
     lassen ihn ausfransen - siehe "09 Pixelraster der Grafik". */
  width:64px; height:64px;
  image-rendering:pixelated;
}

/* ---- Die Box ----
   Ein Koerper mit Deckel und einem Schlitz darin. Gestufte Ecken, weil
   man sie benutzt - siehe die Formensprache in "04 Navbar Labor". */

.intro-box{
  display:block; position:relative;
  width:136px; height:88px;
  background:linear-gradient(180deg, #17171e, #0d0d12);
  border:2px solid var(--badge-border);
  clip-path:var(--pixel-clip);
  transition:border-color .15s ease;
}
/* Kein Aufhellen der Kontur beim Darueberfahren - auch das las sich als
   heller Rahmen um die Box. Der Mauszeiger zeigt ohnehin schon an, dass
   hier etwas anklickbar ist. */

.intro-deckel{
  position:absolute; left:0; right:0; top:0; height:24px;
  background:linear-gradient(180deg, #2b2b36, #1b1b23);
  border-bottom:2px solid rgba(0,0,0,0.65);
}
/* Der Schlitz im Deckel. Die helle Linie darunter laesst ihn vertieft
   wirken, ohne dass es einen Schatten braucht. */
.intro-deckel::after{
  content:''; position:absolute; left:50%; top:50%;
  transform:translate(-50%, -50%);
  width:74px; height:6px; background:#000;
  box-shadow:0 1px 0 rgba(255,255,255,0.10);
}

.intro-text{
  font-family:'Press Start 2P', monospace; font-size:24px; line-height:1.9;
  color:var(--accent); text-align:center;
  /* Das Blinken ist die halbe Miete an einem Automaten. */
  animation:intro-blinken 1.1s steps(1) infinite;
}
@keyframes intro-blinken{
  0%, 55%  { opacity:1; }
  56%, 100%{ opacity:.15; }
}

/* ---- Der Wurf ----
   ------------------------------------------------------------------
   NACHGERECHNET, nicht geschaetzt. Die Zahlen ergeben sich aus dem Aufbau:

     Abstand Muenze/Box   2.5rem = 40px
     Deckel               24px hoch, der Schlitz liegt mittig  -> 12px
     ----------------------------------------------------------------
     Weg bis zum Schlitz  40 + 12 = 52px

   Bewegt werden muss also die UNTERKANTE der Muenze um 52px - nicht ihre
   Mitte. Vorher wanderte die Mitte auf den Schlitz, und weil die Muenze
   ueber der Box liegt, sah man sie dabei oben auf dem Deckel liegen
   statt darin verschwinden.

   Danach sinkt sie in den Schlitz: scaleY gegen null, verankert an der
   Unterkante (transform-origin). Die Unterkante bleibt damit auf der
   Schlitzlinie stehen und die Muenze schiebt sich hinein. */

.intro.wirft .intro-coin{
  transform-origin:center bottom;
  animation:intro-fallen .55s cubic-bezier(.5, 0, .9, .45) forwards;
}
@keyframes intro-fallen{
  0%   { transform:translateY(0)    scaleY(1); }
  62%  { transform:translateY(52px) scaleY(1); }
  100% { transform:translateY(52px) scaleY(0); }
}

@media (max-width:700px){
  .intro-text{ font-size:16px; }
}

/* Zweite Sicherung: Wer weniger Bewegung will, bekommt den Bildschirm
   ohnehin nicht zu sehen - das entscheidet das Skript. */
@media (prefers-reduced-motion:reduce){
  .intro, .intro-coin, .intro-text, .intro-box, .intro-schirm{
    animation:none !important; transition:none !important;
  }
}


/* Beim Ziehen mit der Maus: der Zeiger zeigt es an. */
.bildschau.vergroessert .schau-bild{ cursor:grab; }
.bildschau.zieht .schau-bild{ cursor:grabbing; }


/* ============================================================
   DIE BILDROEHRE
   ------------------------------------------------------------
   Waagerechte Zeilen und ein Schein, der von den Raendern nach
   innen faellt - derselbe Aufbau wie beim Eingangsbildschirm.

   HINTER ALLEM, nicht darueber. z-index -2 setzt die Ebene sogar
   hinter das Sternenfeld (-1). Sie scheint dort durch, wo der
   Untergrund frei liegt - zwischen den Abschnitten, hinter dem
   Fliesstext - und verschwindet hinter allem, was einen eigenen
   Untergrund hat: Karten, Navigation, Terminal, Werk-Fenster.

   Genau das war die Bedingung: Die Zeilen duerfen sich unter
   keinen Umstaenden auf Schrift oder Arbeiten legen. Als Ebene
   DARUEBER (so stand es im Labor) taten sie das - und ausgerechnet
   die Pixelschrift ist dafuer am empfindlichsten.

   position:fixed, damit die Zeilen beim Scrollen stehenbleiben und
   der Inhalt darunter durchwandert. Wuerden sie mitscrollen, saehe
   es aus wie ein Muster auf Papier statt wie ein Bildschirm.

   pointer-events:none, sonst laege eine unsichtbare Scheibe ueber
   der Seite und kein Knopf waere mehr anklickbar.

   ZUM NACHSTELLEN: die beiden Werte hier drunter. Kraeftiger wird
   es mit groesseren Zahlen, ruhiger mit kleineren.
   ============================================================ */

:root{
  --crt-linie: 0.035;    /* Deckkraft der Zeilen */
  --crt-schein: 0.20;    /* Staerke des Randscheins */
  --crt-weite: 160px;    /* wie weit er nach innen reicht (Handy: 60px) */

  /* Breite der Klickzonen in der Bildschau - und damit zugleich der
     freie Rand, den das Bild einhaelt. Das Skript misst sie am
     Element; hier steht die einzige Zahl. */
  --schau-zone: clamp(64px, 12vw, 200px);

  /* Das Zeilenmuster als Variable, weil es an ZWEI Stellen gebraucht
     wird: auf der Seite selbst und noch einmal auf jeder Ebene, die
     sich darueberlegt. Zwei Abschriften desselben Musters waeren zwei
     Stellen, die man beim Aendern vergessen kann.

     4px Abstand: enger gesetzt flimmern die Zeilen auf dichten
     Bildschirmen, weiter gesetzt wirken sie wie ein Gitter. */
  --crt-raster: repeating-linear-gradient(
    to bottom,
    rgba(255,255,255, var(--crt-linie)) 0px,
    rgba(255,255,255, var(--crt-linie)) 1px,
    transparent 1px,
    transparent 4px
  );
}

.crt{
  position:fixed; inset:0;
  z-index:-2; pointer-events:none;
  box-shadow:inset 0 0 var(--crt-weite) rgba(163, 94, 70, var(--crt-schein));
}

/* 160px sind auf einem 2560er Monitor ein Hauch am Rand. Auf einem 390px
   breiten Handy sind es 40 % der Bildbreite - von JEDER Seite. Dann bleibt
   kaum noch Schwarz uebrig, und genau das stoerte.

   Die Staerke bleibt gleich, nur die Weite schrumpft: Der Schein soll auf
   dem Handy dasselbe TUN, nur weniger Platz nehmen. */
@media (max-width:700px){
  :root{ --crt-weite: 60px; --schau-zone: 44px;
         --mass-abspielen: 48px; }
}

.crt-linien{
  position:absolute; inset:0;
  background:var(--crt-raster);
}


/* ============================================================
   DIE BILDROEHRE BLEIBT AN, WENN ETWAS DARUEBERLIEGT
   ------------------------------------------------------------
   Legt sich eine Ebene ueber die Seite, liegt ihr dunkler Grund
   zwischen der Bildroehre (z-index:-2) und dem Auge. Bei 0.86
   Deckkraft blieben von den Zeilen 14 Prozent - unsichtbar.

   Jede Ebene bekommt die Bildroehre deshalb SELBST: als eigene
   Schicht ueber ihrem Grund und unter ihrem Inhalt. So laesst sich
   beides zugleich haben - ein staerker abgedunkelter Hintergrund
   UND Zeilen und Randschein in voller Staerke.

   position:fixed und nicht absolute: Die Bildschau scrollt beim
   Hineinzoomen. Eine absolut gesetzte Schicht wuerde mitscrollen
   und die Zeilen wanderten mit dem Bild davon.

   pointer-events:none, sonst faengt die Schicht jeden Klick ab -
   auch den auf den freien Grund, der die Ebene schliessen soll.
   ============================================================ */

.fenster-lage::before,
.bildschau::before,
.flipbook-lage::before{
  content:'';
  position:fixed; inset:0; z-index:0;
  pointer-events:none;
  background:var(--crt-raster);
  box-shadow:inset 0 0 var(--crt-weite) rgba(163, 94, 70, var(--crt-schein));
}

/* Der Inhalt gehoert DARUEBER. Ohne diese Zeilen malt die Schicht
   ueber das Fenster: Eine absolut gesetzte Schicht liegt vor allem,
   was im normalen Fluss steht. */
.fenster{ position:relative; z-index:1; }
.flipbook-fenster{ position:relative; z-index:1; }
.schau-buehne{ position:relative; z-index:1; }


/* ============================================================
   AUSGEFUELLTE DREIECKE STATT SPITZER KLAMMERN
   ------------------------------------------------------------
   Vorher standen dort die Zeichen < und >. Die sind duenn, haengen
   an der Schrift und sehen je nach Schriftschnitt anders aus.

   Ein Dreieck aus clip-path haengt an gar nichts: Es ist immer
   gleich, immer scharf und laesst sich in einer Zeile spiegeln.
   currentColor uebernimmt die Farbe des Knopfes, also auch beim
   Darueberfahren.
   ============================================================ */

.dreieck{
  display:block; width:11px; height:14px;
  background:currentColor;
}
.dreieck.links { clip-path:polygon(100% 0, 100% 100%, 0 50%); }
.dreieck.rechts{ clip-path:polygon(0 0, 0 100%, 100% 50%); }


/* ============================================================
   DAS FLIPBOOK
   ------------------------------------------------------------
   Ein Prospekt bei einem Anbieter wie Heyzine. Auf der Seite ist
   es zweierlei: eine KACHEL im Raster, genau dort, wo die Datei im
   Ordner liegt - und eine eigene Ebene, die sich darueber legt.

   WARUM NICHT IN DIE BILDSCHAU
   In der Bildschau zoomt das Mausrad und Ziehen verschiebt das
   Bild. Ein Flipbook braucht beides fuer sich selbst - umblaettern
   heisst ziehen. Die beiden wuerden sich um jede Geste streiten.
   ============================================================ */

/* ---- DIE ABSPIELMARKE AUF EINER VIDEO-KACHEL ----
   Die Kachel zeigt ein Standbild und ist damit von einem Bild nicht zu
   unterscheiden. Das Dreieck sagt, dass sich hier etwas bewegt.

   Es sitzt in einer Scheibe mit halbdurchsichtigem Grund: Ein blosses
   Dreieck geht auf einem hellen Standbild unter, und ein Standbild ist
   oft hell. */
.werk-kachel .abspielen{
  position:absolute; left:50%; top:50%; z-index:2;
  width:var(--mass-abspielen); height:var(--mass-abspielen);
  margin:calc(var(--mass-abspielen) / -2) 0 0 calc(var(--mass-abspielen) / -2);
  display:flex; align-items:center; justify-content:center;
  border-radius:50%;
  background:rgba(8,8,11,0.62);
  border:2px solid rgba(255,255,255,0.82);
  transition:background .18s ease, transform .18s ease;
}
/* Das Dreieck aus clip-path, wie die Pfeile: haengt an keiner Schrift
   und ist bei jeder Groesse gleich scharf. Ein Hauch nach rechts, weil
   ein Dreieck optisch links schwerer wirkt als es ist. */
.werk-kachel .abspielen::before{
  content:''; display:block;
  width:34%; height:40%; margin-left:12%;
  background:#fff;
  clip-path:polygon(0 0, 100% 50%, 0 100%);
}
.werk-kachel:hover .abspielen{
  background:var(--brand-dark); transform:scale(1.08);
}

/* ---- DAS VIDEO IN DER BILDSCHAU ----
   Traegt dieselbe Klasse wie das Bild und damit denselben weissen
   Rahmen und dieselbe Breite aus --bild-breite. Nur der Zoom entfaellt:
   Ein Video hat eine feste Aufloesung, und die Bedienleiste braucht
   ihren Platz an der Unterkante. */
.schau-bild[hidden]{ display:none; }
video.schau-bild{ height:auto; background:#000; }

/* ---- Das Banner ueber dem Raster ----
   ERSTER ANLAUF WAR EINE KACHEL im Mauerwerk. Sie sah aus wie das
   dreizehnte Bild, und genau das war der Einwand: Man versteht nicht,
   dass hier etwas Interaktives liegt.

   Das Banner ist deshalb absichtlich das Gegenteil einer Kachel:
   quer statt hoch, ueber die volle Breite statt in einer Spalte,
   Deckblatt links und Text rechts. Was anders aussieht, wird auch
   anders gelesen.

   DREI SIGNALE, und keines davon ist das Bild selbst - ein Deckblatt
   sieht aus wie ein Bild von einem Deckblatt:
     die Marke "Flipbook", die Aufforderung im Klartext,
     und die Ecke, die sich hebt. */
.werk-oben{
  display:flex; flex-direction:column; gap:var(--abstand-eng);
  margin-bottom:2.5rem;
}

.flipbook-banner{
  display:flex; align-items:center; gap:1.6rem;
  width:100%; padding:1.1rem; text-align:left;
  background:var(--bg);
  border:2px solid var(--brand-dark);
  cursor:pointer;
  /* transform:none im Ruhezustand, nicht translateY(0) - sonst liegt
     der Text dauerhaft in einer eigenen Grafikebene und wird weich.
     Siehe "30 Ruhig und gross". */
  transform:none;
  transition:transform .15s ease, border-color .2s ease;
}
.flipbook-banner:hover{
  transform:translateY(-3px);
  border-color:var(--brand-light);
}
.flipbook-banner:focus-visible{
  outline:2px solid var(--brand-light); outline-offset:3px;
}

/* Das Deckblatt. Schmal genug, dass der Text danebensteht und nicht
   darunter - sonst waere es wieder eine hohe Kachel. */
.flipbook-banner .deckblatt{
  position:relative; flex:none;
  width:var(--mass-flip-deckblatt);
  border:var(--mass-bild-rahmen) solid #fff;
  background:var(--bg-2);
  overflow:hidden;
}
.flipbook-banner .deckblatt img{ display:block; width:100%; height:auto; }

/* Ohne Vorschaubild - kein Netz beim Bilderlauf, oder der Anbieter
   gibt keines her. DIN A4 hochkant als festes Verhaeltnis, damit
   nichts springt. */
.flipbook-banner .deckblatt.ohne-bild{
  aspect-ratio:800 / 1131;
  background:linear-gradient(160deg, var(--brand-dark), var(--bg-2) 70%);
}

/* DIE ECKE, DIE SICH HEBT.
   Ein Eselsohr unten rechts. Es haelt sich lange still und hebt sich
   dann kurz - wer hinsieht, merkt es; wer liest, nicht. Genau darum
   geht es: Bewegung sagt "hier kann man etwas tun", ohne zu blinken.

   SIE WAECHST DURCH transform, NICHT DURCH width UND height.
   Bis zum 2026-08-30 wurden Breite und Hoehe animiert - und beides
   zwingt den Browser bei JEDEM Einzelbild, das Seitenlayout neu zu
   rechnen. Das war das Ruckeln, das ihr aufgefallen ist. Eine
   Verschiebung rechnet dagegen die Grafikkarte, ohne das Layout
   anzufassen.

   Das Element hat deshalb immer seine volle Groesse und steht nur
   verkleinert da. transform-origin unten rechts: So waechst es aus der
   Ecke heraus statt aus seiner eigenen Mitte.

   Beim Darueberfahren bleibt es gehoben - mit derselben weichen Kurve,
   damit der Uebergang aus der Schleife heraus nicht springt. */
.flipbook-banner .ecke{
  position:absolute; right:0; bottom:0;
  width:var(--mass-flip-ecke); height:var(--mass-flip-ecke);
  /* Beide Eigenschaften wachsen aus derselben Ecke heraus statt aus
     ihrer Mitte. */
  transform-origin:100% 100%;
  scale:.58;                /* gehoert der Schleife */
  transform:scale(1);       /* gehoert dem Hovern */
  background:linear-gradient(to bottom right,
              transparent 0 50%, var(--brand-light) 50% 100%);
  animation:flip-ecke 5s ease-in-out infinite;
  /* Lang und weich auslaufend: schnell los, sanft ankommen. */
  transition:transform .55s cubic-bezier(.16, .84, .44, 1);
}
@keyframes flip-ecke{
  0%, 58%, 100%{ scale:.58; }
  76%          { scale:.70; }
}
/* NUR ANGEHALTEN, NICHT ABGESCHALTET.
   Mit animation:none fiele der Wert schlagartig vom laufenden
   Zwischenwert auf den Grundwert zurueck, bevor der Uebergang
   anfaengt - genau das war der Ruck. Angehalten bleibt die Schleife
   stehen, wo sie ist, und das Wachsen laeuft ungestoert daneben.

   1.42 ist so gewaehlt, dass das Ergebnis nie ueber 1 geht:
   .58 x 1.42 = 0.82 im Ruhepunkt, .70 x 1.42 = 0.99 am Gipfel. Groesser
   wuerde die Ecke am Rand des Deckblatts beschnitten. */
.flipbook-banner:hover .ecke,
.flipbook-banner:focus-visible .ecke{
  animation-play-state:paused;
  transform:scale(1.42);
}

.flipbook-banner .text{
  display:flex; flex-direction:column; gap:.55rem; min-width:0;
}
.flipbook-banner .marke{
  font-family:'JetBrains Mono', monospace; font-size:.62rem;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--brand-light);
}
.flipbook-banner .titel{
  font-family:'Space Grotesk', sans-serif; font-weight:700;
  font-size:1.05rem; line-height:1.35; color:var(--text);
}
/* Was in dem Dokument steht. Kommt aus dem Zettel im Ordner, nicht aus
   dem HTML - sie soll es aendern koennen, ohne jemanden zu fragen. */
.flipbook-banner .beschreibung{
  font-family:'Space Grotesk', sans-serif; font-size:.86rem; line-height:1.7;
  color:var(--text-dim); max-width:44rem;
}

/* Steht IMMER da und nicht erst beim Darueberfahren: Auf einem
   Telefon gibt es kein Darueberfahren. */
.flipbook-banner .aufforderung{
  /* Ans rechte Ende. Ohne das stand alles links und die rechte Haelfte
     des Banners war leer - es sah aus wie ein zu grosser Rahmen. */
  margin-left:auto; flex:none; padding-right:.6rem;
  font-family:'JetBrains Mono', monospace; font-size:.76rem;
  color:var(--brand-light);
}

/* ---- Die Ebene ----
   Genau wie die Werk-Ebene aufgebaut, damit sie sich anfuehlt wie
   ein weiteres Fenster derselben Seite und nicht wie ein fremder
   Kasten. z-index ueber der Bildschau: Sie oeffnet sich aus dem
   Raster heraus und liegt deshalb obenauf. */
.flipbook-lage{
  position:fixed; inset:0; z-index:220;
  display:flex; align-items:center; justify-content:center;
  padding:4vh 4vw;                /* wie die Werk-Ebene */
  background:rgba(4,4,6,0.97);
  opacity:0; transition:opacity .22s ease;
}
.flipbook-lage[hidden]{ display:none; }
.flipbook-lage.offen{ opacity:1; }

.flipbook-fenster{
  width:min(1180px, 100%); height:92vh;
  display:flex; flex-direction:column;
  background:var(--bg-2); border:2px solid var(--badge-border);
  transform:translateY(10px);
  transition:transform .22s ease;
}
.flipbook-lage.offen .flipbook-fenster{ transform:translateY(0); }

/* Der Rahmen fuellt, was uebrig bleibt. Ihr Schnipsel brachte
   width:100% und height:400px als style-Attribut mit - 400px waeren
   fuer ein A4-Dokument zu wenig, um darin zu lesen. Hier bekommt es
   die ganze Hoehe des Fensters.

   Der schwarze Grund ist kein Schmuck: Bis der Anbieter geladen hat,
   stuende dort sonst eine weisse Flaeche. */
.flipbook-koerper{
  flex:1; min-height:0; display:flex;
  background:var(--bg);
}
.flipbook-koerper iframe{
  flex:1; width:100%; height:100%;
  border:0;                 /* stand bei ihr im style-Attribut */
  display:block;
}

/* Der Hinweis, wo das Dokument herkommt. Ein eingebetteter Rahmen
   sieht aus wie ein Teil der Seite - er ist aber ein fremder Dienst,
   und das gehoert sichtbar dazugesagt. */
#flipbookQuelle{ font-size:.68rem; flex:none; }

/* ---- DAMIT DER CLOSE-KNOPF NIE AUS DEM BILD FAELLT ----
   Ein Flex-Element hat min-width:auto und wird nie schmaler als sein
   Inhalt. Der Titel gab nichts her und schob den Knopf ueber den Rand -
   gemessen ab etwa 440px Fensterbreite.

   Auf dem Handy fuellt die Ebene den ganzen Bildschirm. Es gibt dort
   kein "daneben" zum Wegtippen und keine Escape-Taste. Der Knopf ist
   die einzige Ausfahrt, also muss er unter allen Umstaenden erreichbar
   bleiben - lieber ein abgeschnittener Titel als ein Dokument, aus dem
   man nicht mehr herauskommt.

   min-width:0 an BEIDEN Stellen: am Fenster, damit es schmaler werden
   darf als sein Inhalt, und am Titel, damit er selbst nachgibt statt
   den Rest zu schieben. */
.flipbook-fenster{ min-width:0; }
.flipbook-fenster .fenster-titel{
  flex:0 1 auto; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

@media (max-width:700px){
  .flipbook-lage{ padding:0; }
  .flipbook-fenster{ width:100%; height:100%; }
  /* Die Leiste enger: 2.2rem Polster links und rechts sind auf einem
     320px-Bildschirm ein Fuenftel der Breite. */
  .flipbook-fenster .fenster-leiste{ gap:.6rem; padding:.7rem .9rem; }
  /* Auf dem Handy wird das Banner enger, bleibt aber quer: Untereinander
     waere es wieder eine hohe Kachel, und genau davon soll es sich
     unterscheiden. */
  /* Auf schmalen Fenstern ist rechts kein Platz mehr - die Aufforderung
     rutscht unter beides. Sie bleibt sichtbar, und das ist das
     Entscheidende: Auf einem Telefon gibt es kein Darueberfahren. */
  .flipbook-banner{ gap:1rem; padding:.8rem; flex-wrap:wrap; }
  .flipbook-banner .aufforderung{
    margin-left:0; flex-basis:100%; padding-right:0;
  }
  .flipbook-banner .titel{ font-size:.95rem; }
  .flipbook-banner .aufforderung{ font-size:.7rem; }
  /* Nur das Mass wird kleiner. Die Schleife selbst rechnet in Anteilen
     und muss deshalb nicht noch einmal geschrieben werden - das war sie
     bis zum 2026-08-30, mit eigenen Pixelwerten, die beim naechsten
     Aendern vergessen worden waeren. */
  :root{ --mass-flip-ecke: 34px; }
}
@media (prefers-reduced-motion:reduce){
  .flipbook-lage, .flipbook-fenster{ transition:none; }
  /* NUR die Bewegung faellt weg, nicht die Groesse. Das Mass steht in
     --mass-flip-ecke und wird hier bewusst nicht angefasst - sonst
     schluege diese Regel die schmalere Fassung fuer Telefone. Genau das
     hatte tools/pruefe_css.py schon einmal gemeldet.
     Das Eselsohr bleibt sichtbar, es hebt sich nur nicht mehr. */
  .flipbook-banner .ecke{ animation:none; scale:.70; transform:scale(1); }
  .flipbook-banner{ transition:none; }
}
