/* ==========================================================================
   Druckbild – Zwahlen's Rapport
   --------------------------------------------------------------------------
   Wird NACH styles.css geladen und ergaenzt deren Druckregeln.
   Einbinden in index.html direkt unter der Zeile fuer styles.css:

       <link rel="stylesheet" href="/druck.css" media="print">

   Auf Papier ist ein Rapport ein Beweisdokument und kein Bildschirmabzug.
   Alles hier folgt daraus: fester Satzspiegel mit Lochrand, echte
   Seitenzahlen, Umbrueche, die nichts zerreissen, und Schwarz auf Weiss
   statt Oberflaeche.

   Alle Regeln stehen in einem @media-print-Block, damit die Datei auch
   dann nichts am Bildschirm veraendert, wenn sie einmal ohne das
   media-Attribut eingebunden wird.
   ========================================================================== */

@media print {

  /* ---------------------------------------------------------- 1. Seite */

  @page {
    size: A4;
    /* 25 mm links: Platz fuer die Lochung. Ohne den verschwindet im
       Ordner die erste Spalte des Textes hinter dem Ringmechanismus. */
    margin: 15mm 15mm 15mm 25mm;

    @top-left {
      /* Rapportnummer als laufender Kopf. Zwei Stufen, weil kein Browser
         beide Wege kann: Setzt die App --druck-ref am <html>, steht die
         Nummer oben. Wo string() unterstuetzt wird, gewinnt die zweite
         Zeile und holt sie direkt aus dem Rapportkopf. Kennt der Browser
         string() nicht, faellt die Zeile weg und Stufe eins bleibt. */
      content: var(--druck-ref, "");
      content: string(druck-ref);
      font-family: ui-sans-serif, system-ui, "Segoe UI", Arial, sans-serif;
      font-size: 8pt;
      color: #333;
    }

    @bottom-right {
      /* counter(pages) koennen Chrome ab 131 und Safari. Firefox laesst den
         Randbereich leer – das ist ein sauberer Ausfall und kein Fehlbild:
         lieber keine Seitenzahl als eine falsche auf einem Beweisdokument. */
      content: "Seite " counter(page) " von " counter(pages);
      font-family: ui-sans-serif, system-ui, "Segoe UI", Arial, sans-serif;
      font-size: 8pt;
      color: #333;
    }
  }

  /* Quelle fuer den laufenden Kopf. Greift nur in Browsern mit string(),
     stoert aber nirgends: string-set ohne Abnehmer bleibt folgenlos. */
  .sheet-head .muted,
  .print-report h2 { string-set: druck-ref content(text); }

  /* ------------------------------------------------- 2. Farben aufs Papier */

  /* Die Oberflaeche kennt ein helles und ein dunkles Erscheinungsbild.
     Papier kennt nur eines. Ohne diese Umschreibung druckt ein Nutzer mit
     dunklem Thema graue Schrift auf grauem Grund. Die Werte stehen darum
     hier nochmals fest verdrahtet – genau wie in karte.css. */
  :root,
  :root[data-theme="dark"] {
    --surface-0: #ffffff;
    --surface-1: #ffffff;
    --surface-2: #ffffff;
    --surface-sunken: #ffffff;
    --border: #999999;
    --border-strong: #000000;
    --text-primary: #000000;
    --text-secondary: #1a1a1a;
    --text-muted: #333333;
    --accent: #000000;
    --accent-fg: #000000;
    --accent-ink: #000000;
    --accent-soft: transparent;
    --good: #000000;
    --warning: #000000;
    --serious: #000000;
    --critical: #000000;
    --shadow: none;
    /* Die einzige Farbe, die bleibt: der duenne Balken ueber dem Dokumentkopf. */
    --druck-akzent: #6d28d9;
  }

  /* Keine Farbflaechen. Browser lassen Hintergruende beim Drucken zwar
     meist weg – "meist" ist fuer ein Beweisdokument zu wenig. */
  body *,
  body *::before,
  body *::after { background-image: none !important; }

  .card, .ritem, .chip, .kpi, .chart-card, .siegel, .entries,
  .badge-on, .badge-off, .shift, .cal-item, .pw-result,
  .herkunft-roh, .seg { background: transparent !important; }

  /* Filter erzwingen eine Rasterung: Der Browser rechnet den betroffenen
     Bereich in ein Pixelbild um und druckt es in Bildschirmaufloesung.
     Das ist die haeufigste Ursache fuer unscharfe Karten und Siegel. */
  *, *::before, *::after {
    box-shadow: none !important;
    text-shadow: none !important;
    filter: none !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }

  /* ---------------------------------------------------- 3. Typografie */

  /* Der Bezugspunkt zuerst: Fast alle Groessen im Projekt sind in rem
     angegeben. Bleibt die Wurzel bei 16px, waechst jede rem-Angabe im
     Ausdruck ueber den 10.5pt-Fliesstext hinaus – die Metadaten waeren
     dann groesser als der Text, zu dem sie gehoeren. */
  html { font-size: 10.5pt; }

  body {
    font-size: 10.5pt;
    line-height: 1.35;
    color: #000;
    /* Flattersatz: Blocksatz reisst in der schmalen Spalte Loecher auf.
       Trennung nach Sprache, das lang="de" am <html> liefert sie. */
    text-align: left;
    hyphens: auto;
  }

  h1, .print-cover h1 { font-size: 16pt; line-height: 1.2; }
  h2, .print-report h2, .sheet-head h2 { font-size: 12pt; line-height: 1.25; }
  h3 { font-size: 10.5pt; line-height: 1.3; }

  .prose, .entry-text, .herkunft-roh { line-height: 1.35; }

  /* Metadaten auf 8pt – aber benannt statt ueber .muted pauschal:
     .muted traegt an manchen Stellen Fliesstext, etwa den erklaerenden
     Satz im Herkunftsblock. Der bliebe sonst unnoetig klein. */
  /* .siegel-summe code steht bewusst NICHT in dieser Liste: Die Groesse der
     Pruefsumme entscheidet Abschnitt 10, zusammen mit ihrem Umbruchraster.
     Zwei Stellen, die dieselbe Groesse setzen, laufen sonst auseinander. */
  .dl dt, .print-note, .print-firma .muted, .entry-time, .entry-status,
  .ritem-meta, .thumb .cap, .shift-meta, .siegel-summe .muted,
  .protokoll code, .chain-hint { font-size: 8pt; }

  .dl { grid-template-columns: 38mm 1fr; gap: 2mm 5mm; font-size: 10.5pt; }
  .dl dt { color: #333; }

  /* Zahlen und Pruefsummen im gleichen Schnitt: Wer zwei Summen auf
     Papier vergleicht, muss Ziffern uebereinander legen koennen. */
  code, .siegel-summe code, .protokoll code {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    background: none;
  }

  /* Der eine Akzent: ein duenner Balken ueber dem Dokumentkopf. Kein
     Farbfeld, nur eine Linie – die druckt jeder Treiber ohne Rasterung. */
  .print-cover, .print-head, .sheet-head,
  body.printing-record .rec-head {
    border-top: 2pt solid var(--druck-akzent);
    padding-top: 4mm;
  }

  /* ------------------------------------------- 4. Bedienbares verschwindet */

  /* Auf Papier laesst sich nichts druecken, nichts auswaehlen, nichts
     aufklappen. Was danach aussieht, kostet nur Platz und verwirrt. */
  button, .btn, .navbtn, .chipbtn, .chipbtns, .fab, .seg, .pick,
  nav, .sidebar, .topbar, .filters, .sel-bar, .offline-bar, .lic-bar,
  .toast, .sheet-foot, .quick, .entry-add, .entry-del, .disclose,
  .thumb .del, .karte-steuerung, .protokoll-auf, .no-print,
  [role="button"], [role="tablist"] { display: none !important; }

  /* Aufklapper: Das Bedienelement geht, der Inhalt bleibt. Ohne das
     fehlt im Ausdruck der Verlauf – also genau der Teil, wegen dem
     ein Rapport ueberhaupt ausgedruckt wird. */
  details { display: block; }
  details:not([open]) > *:not(summary) { display: revert; }

  /* Eigene Regel, nicht in die Liste darueber gefaltet: Kennt ein Browser
     ::details-content nicht, verwirft er den ganzen Regelsatz. */
  details::details-content { content-visibility: visible !important; }

  /* Die Zusammenfassung bleibt als Beschriftung stehen, sonst steht der
     Inhalt ohne Ueberschrift im Dokument. Nur der Aufklapp-Pfeil geht. */
  summary { list-style: none; cursor: default; font-weight: 650; }
  summary::marker { content: ""; }
  summary::-webkit-details-marker { display: none; }

  /* --------------------------------------------------- 5. Umbruchregeln */

  /* Was zusammen gelesen werden muss, wird nicht getrennt. Eine
     Unterschrift ohne die Zeile darueber beweist nichts, ein Foto ohne
     seine Bildunterschrift auch nicht. */
  .rec-sign, .rec-sign > div,
  .thumb,
  .entry,
  .herkunft,
  .siegel, .rec-seal,
  .protokoll li,
  .print-firma,
  .chart-card, .kpi {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Eine Ueberschrift allein am Seitenfuss ist ein Versprechen, das die
     Seite nicht mehr einloest. */
  h1, h2, h3, .block h3, .print-report h3, .shift-day h3 {
    break-after: avoid;
    page-break-after: avoid;
    break-inside: avoid;
  }

  /* Mindestens drei Zeilen Zusammenhalt. Firefox kennt das nicht und
     ignoriert es still – der Rest wird dadurch nicht schlechter. */
  p, li, dd, .prose, .entry-text, .rec-oath, .lp-lead {
    orphans: 3;
    widows: 3;
  }

  /* Tabellenkoepfe wiederholen sich auf jeder Folgeseite, sonst steht ab
     Seite zwei eine Zahlenkolonne ohne Beschriftung. */
  thead { display: table-header-group; }
  tfoot { display: table-footer-group; }
  tr, th, td { break-inside: avoid; page-break-inside: avoid; }
  .lic-table th { border-bottom: .75pt solid #000; }
  .lic-table td { border-bottom: .5pt solid #999; }

  /* ------------------------------------------------ 6. Beweisteil rahmen */

  /* Siegel und Herkunft sind die Teile, auf die es im Streitfall ankommt.
     Ein Rahmen in reinem Schwarz zeigt, wo sie anfangen und aufhoeren –
     auch auf einer Fotokopie einer Fotokopie. */
  .siegel,
  .rec-seal,
  body.printing-record .rec-seal {
    border: 1pt solid #000;
    border-radius: 0;
    padding: 4mm;
  }
  .siegel-kopf { border-bottom: .5pt solid #000; padding-bottom: 2mm; margin-bottom: 3mm; }
  .siegel-summe { border-top: .5pt solid #000; padding-top: 2.5mm; margin-top: 3mm; }

  .herkunft {
    border: 1pt solid #000;
    border-radius: 0;
    padding: 4mm;
    margin-top: 5mm;
  }
  .herkunft-roh { border-left: .5pt solid #000; border-radius: 0; padding: 2mm 3mm; }

  /* Unterschriftenfeld: Linien in Schwarz, damit sie eine Unterschrift
     tragen und nicht nur andeuten, wo eine hingehoerte. */
  .rec-sign { grid-template-columns: 1fr 1fr; gap: 0 20mm; margin-top: 18mm; }
  .rec-sign span { border-bottom: .75pt solid #000; height: 12mm; margin-bottom: 1.5mm; }
  .rec-sign div { font-size: 8pt; color: #000; }

  /* ------------------------------------------------------- 7. Anhaenge */

  /* Aus der Reihe wird eine Spalte: Ein Flex-Kasten bricht ueber
     Seitengrenzen unzuverlaessig um, ein Block nicht. */
  .thumbs { display: block; margin-top: 3mm; }
  .thumb { position: static; width: auto; max-width: 70mm; margin: 0 0 5mm; }
  .thumb img {
    width: 70mm; height: auto; max-height: 90mm;
    /* contain statt cover: Ein beschnittenes Beweisfoto ist kein Beweis. */
    object-fit: contain;
    border: .5pt solid #666; border-radius: 0; background: none;
  }
  .thumb .pdf { width: 18mm; height: 18mm; border: .5pt solid #666; border-radius: 0; background: none; }
  /* Am Bildschirm wird der Dateiname gekuerzt, weil daneben das Bild
     steht. Auf Papier ist er die Bezeichnung des Beweisstuecks. */
  .thumb .cap {
    white-space: normal; overflow: visible; text-overflow: clip;
    color: #333; margin-top: 1.5mm;
  }

  /* -------------------------------------------------------- 8. Verweise */

  a { color: #000; text-decoration: underline; }

  /* Ein Link auf Papier ist wertlos, solange die Adresse fehlt. */
  .prose a[href]::after,
  .print-report a[href]::after,
  .sheet-body a[href]::after,
  .doc-body a[href]::after,
  .chain-hint a[href]::after,
  .lp-main p a[href]::after {
    content: " (" attr(href) ")";
    font-size: 8pt;
    font-weight: 400;
    text-decoration: none;
    word-break: break-all;
  }

  /* Nicht bei Bedienwegen und nicht bei Adressen, die ohne die laufende
     Sitzung nichts bedeuten – die waeren nur Rauschen im Satzbild. */
  nav a[href]::after,
  .lp-nav a[href]::after,
  .lp-foot-links a[href]::after,
  .mehr-links a[href]::after,
  .sidebar a[href]::after,
  .navbtn[href]::after,
  .thumb a[href]::after,
  a[href^="#"]::after,
  a[href^="/api/"]::after,
  a[href^="javascript:"]::after { content: "" !important; }

  /* ------------------------------------------------------ 9. Feinschliff */

  /* Zustaende als Umriss statt als Farbfeld: Der Text traegt die Aussage,
     die Farbe hat sie am Bildschirm nur begleitet. */
  .chip, .badge-on, .badge-off {
    border: .5pt solid #000; border-radius: 0; color: #000;
  }

  /* Der Nachtragsstrang bleibt sichtbar, aber ohne Einzug ins Nichts. */
  .entries { margin-left: 0; padding-left: 4mm; border-left: .5pt solid #666; }
  .entry { padding: 1.5mm 0; }
  .entry + .entry { border-top: .5pt solid #ccc; }

  .block { margin-top: 5mm; }
  .sheet-body { padding: 4mm 0 0; }
  .print-report { padding-top: 0; }


  /* ------------------------------------------ 10. Pruefsumme – eine Form */

  /* Auf dem gedruckten Leistungsnachweis stand dieselbe Summe bisher zweimal
     auf einem Blatt in zwei unvereinbaren Schreibweisen, und im Tagessiegel in
     einer dritten:

       A  64 Zeichen klein, Vierergruppen   (public/app.js:4219, Tagessiegel)
       B  16 Zeichen mit Auslassungszeichen (public/app.js:4134, Dokumentfuss)
       C  32 Zeichen GROSS mit Bindestrich  (public/app.js:3475, Pruefsiegel)

     Nur A kommt durch die Pruefstelle: public/pruefen.js:160 verlangt nach dem
     Normalisieren genau 64 Zeichen, src/routes/nachweis-oeffentlich.js:190
     antwortet sonst mit 400. Gross und Bindestrich waeren dabei unschaedlich –
     pruefen.js:29 macht klein, :30 entfernt Bindestriche. Toedlich ist allein
     die Kuerzung. Bei B kommt hinzu, dass das Auslassungszeichen U+2026 in der
     Streichklasse von :30 fehlt und die Normalisierung ueberlebt: aus 16
     Zeichen werden 17, und die Fehlermeldung zaehlt dem Nutzer eine Zahl vor,
     die er nie getippt hat.

     Gueltig ist ab hier genau die Form, die public/siegelblock.js:10-22 schon
     beschreibt: alle 64 Zeichen, klein, in Vierergruppen, festes Raster; die
     Kurzform sei „ein Erkennungszeichen, kein Beweismittel“.

     WAS DIESE DATEI DAVON LEISTEN KANN und was nicht – ohne diese Grenze
     waere der Abschnitt eine Behauptung:

       kann:  Kleinschreibung erzwingen (loest C als eigene Schreibweise auf),
              eine Schrift, eine Groesse, ein Umbruchraster fuer alle drei
              Orte, kein Zerreissen ueber den Seitenwechsel.
       kann NICHT: aus 16 oder 32 Zeichen 64 machen. Die Kuerzung entsteht in
              public/app.js (summeLesbar bei :4134, siegelKurz bei :3475) und
              in src/routes/audit.js:304 – fremde Spur. Die Bitte dazu steht
              in AUSTAUSCH/log-sithrom.md.

     Solange dort gekuerzt wird, ist das Raster zugleich die Anzeige des
     Mangels: Eine vollstaendige Summe steht in VIER Zeilen zu vier Gruppen.
     Steht sie in einer oder zwei, ist sie nicht vollstaendig – das sieht man
     ihr dann an, statt es erst an der Pruefstelle zu erfahren.

     Warum 22ch: Vier Gruppen sind 19 Zeichen, eine fuenfte braucht 24. Jede
     Breite dazwischen ergibt vier Zeilen zu vier Gruppen. Gemessen statt
     geschaetzt – im installierten Chrome und im installierten Edge, ueber 40
     Kombinationen aus vier Schriftstapeln, fuenf Schriftgroessen und zwei
     Wortabstaenden: 20ch bis 23ch halten das Raster ausnahmslos, 19ch und
     24ch nicht. 22ch liegt in der Mitte, mit der Reserve auf der Seite, auf
     der ein spaeter ergaenzter word-spacing- oder letter-spacing-Wert
     zuerst draengt. */
  .dokfuss-summe code,
  .siegel-summe code,
  .rec-seal .dl code {
    /* code ist inline – ohne eigene Zeile greift keine Breite. Die
       Beschriftung davor ruecht dadurch ueber die Summe, was sie ohnehin
       sein sollte: eine Ueberschrift, kein Zeilenanfang. */
    display: block;
    width: 22ch;
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 8pt;
    line-height: 1.5;

    /* Aus styles.css:833 traegt .rec-seal code font-size: var(--fs-xl),
       font-weight: 700 und letter-spacing: .04em. Alle drei muessen hier
       fallen: Die Sperrung verschiebt die Rechnung, auf der die 22ch
       stehen, und ein fetter Grossbuchstabensatz macht ausgerechnet den
       gekuerzten Wert zum auffaelligsten Zeichen des Blattes. */
    font-weight: 400;
    letter-spacing: normal;
    word-spacing: normal;

    /* Kleinschreibung erzwungen. Die Pruefstelle rechnet ohnehin klein
       (pruefen.js:29); hier geht es um das Blatt: Zwei Schreibweisen
       derselben Zahl auf einer Seite liest niemand als eine Zahl. */
    text-transform: lowercase;

    /* Umbruch an den Gruppengrenzen. Bewusst „anywhere“ statt „break-all“:
       break-all bricht auch dann mitten in eine Vierergruppe, wenn daneben
       eine Leerstelle frei waere – und die zerrissene Gruppe ist genau die
       Stelle, an der beim Abtippen ein Zeichen verloren geht. „anywhere“
       greift erst, wenn eine Gruppe allein nicht mehr passt. */
    white-space: normal;
    word-break: normal;
    overflow-wrap: anywhere;

    /* Ligaturen aus: Cascadia Code und Fira Code ziehen „ff“ zu einem
       Zeichen zusammen. In einer Hexadezimalsumme kommt „ff“ haeufig vor,
       und wer Zeichen fuer Zeichen vergleicht – wozu public/pruefen.html:54
       ausdruecklich auffordert –, zaehlt dann falsch. */
    font-variant-ligatures: none;
    font-feature-settings: "calt" 0, "liga" 0;

    /* Wo die Schrift sie anbietet, die durchgestrichene Null. Wo nicht,
       bleibt die Zeile folgenlos. */
    font-variant-numeric: slashed-zero;
  }

  /* Eine Summe, die ein Seitenwechsel teilt, ist beim Vergleichen wertlos:
     Zeile drei stuende auf einem anderen Blatt als Zeile zwei. */
  .dokfuss-summe,
  .siegel-summe,
  .rec-seal .dl dd { break-inside: avoid; page-break-inside: avoid; }

  /* Die Beschriftung steht ueber der Summe, nicht davor. */
  .dokfuss-summe { margin-top: 1.5mm; }

  /* ------------------------------------------------ 11. Dokumentfuss (QR) */

  /* Der Fuss ist der Weg vom Papier zurueck in die App. Er steht immer am
     Ende eines Dokuments und darf nie umbrochen werden: ein QR-Code, den
     ein Seitenwechsel halbiert, ist kein QR-Code mehr. */
  .dokfuss {
    display: flex;
    gap: 5mm;
    align-items: flex-start;
    margin-top: 8mm;
    padding-top: 3mm;
    border-top: .5pt solid #000;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* 24 mm Kantenlaenge. Darunter wird die Ruhezone auf handelsueblichen
     Druckern schmaler als ein Modul und Lesegeraete verfehlen den Code;
     darueber frisst er Platz, den der Rapport braucht. */
  /* Rahmen, Polster und Rundung stammen aus der Bildschirmfassung. Auf
     Papier muessen sie weg: Ein Polster schiebt den Code in die Ruhezone
     hinein und macht ihn kleiner, als hier steht. */
  .dokfuss-qr {
    flex: 0 0 24mm;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
  }
  .dokfuss-qr svg { display: block; width: 24mm; height: 24mm; }

  .dokfuss-text { font-size: 7.5pt; line-height: 1.45; color: #000; }
  .dokfuss-titel { font-weight: 700; }

  /* Die Adresse steht ausgeschrieben daneben. Wer kein Handy zur Hand hat
     oder wessen Kamera streikt, kann sie abtippen - ein Code ohne
     lesbare Entsprechung ist eine Sackgasse. */
  .dokfuss-url {
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 7pt;
    word-break: break-all;
  }
  .dokfuss-hinweis { color: #333; }
  /* .dokfuss-summe code hat hier bewusst keine eigene Regel mehr: Schrift,
     Groesse und Umbruchraster der Summe stehen in Abschnitt 10 und gelten
     dort fuer alle drei Orte gemeinsam. Sie war zuvor 7pt und damit einen
     Punkt kleiner als dieselbe Summe im Siegelblock – auf einem Blatt, auf
     dem beide vorkommen koennen. */
  .dokfuss-zeit { color: #444; }

  /* Die allgemeine Regel haengt hinter jede Adresse die Zieladresse in
     Klammern. Hier stuende sie doppelt. */
  .dokfuss a[href]::after { content: "" !important; }

}
