/* ==========================================================================
   Das Blatt: Bildschirmvorschau und Druck

   Die Vorschau zeigt dieselben Seiten, die auch aus dem Drucker kommen. Dafuer
   sorgen zwei Dinge:

   1. Die Seitengeometrie steht genau einmal, naemlich in den Eigenschaften
      unter :root. @page im Druck, das Blatt am Bildschirm und die Vorschau
      rechnen alle damit. Wer einen Rand aendert, aendert ihn ueberall.

   2. Die Vorschau zerlegt den Text nicht selbst, sondern laesst den Browser
      das tun: der Satz laeuft in einem mehrspaltigen Kasten, dessen Spalten
      genau Seitenmass haben. Chromium nutzt fuer Spalten und fuer Seiten
      dieselbe Umbruchmechanik, also fallen die Umbrueche identisch aus. Jede
      Vorschauseite ist ein Fenster auf eine dieser Spalten. Nachgemessen am
      Einsatzkonzept ueber acht Seiten: jede Abschnittsueberschrift liegt in
      derselben Spalte wie auf der zugehoerigen Druckseite.

   Erzeugt wird die Vorschau von /assets/js/seitenvorschau.js. Ohne Skript
   bleibt das Blatt als eine durchgehende Flaeche stehen; gedruckt wird in
   beiden Faellen gleich.
   ========================================================================== */

:root {
    --blatt-breite: 210mm;   /* A4 */
    --blatt-hoehe: 297mm;

    /* Seitenraender. Die Briefvorlage ueberschreibt sie in brief-druck.css. */
    --rand-oben: 16mm;
    --rand-rechts: 15mm;
    --rand-unten: 16mm;
    --rand-links: 15mm;
    /* Oberer Rand der ersten Seite, falls sie mehr Platz braucht als die
       Folgeseiten, etwa fuer einen Briefkopf. */
    --rand-oben-erste: 16mm;

    /* Abgeleitet: Satzspiegel und die Spaltenmasse der Vorschau. */
    --satz-breite: calc(var(--blatt-breite) - var(--rand-links) - var(--rand-rechts));
    /* Der Zwischenraum ist breiter als die seitlichen Raender zusammen, damit
       im Fenster einer Vorschauseite nie ein Stueck der Nachbarspalte auftaucht. */
    --spalten-luecke: calc(var(--rand-links) + var(--rand-rechts) + 20mm);
    --spalten-schritt: calc(var(--satz-breite) + var(--spalten-luecke));
}

/* -- Bildschirm: Blatt wie eine Seite darstellen ------------------------- */
.sheet {
    width: var(--blatt-breite);
    min-height: var(--blatt-hoehe);
    margin: 24px auto;
    padding: var(--rand-oben-erste) var(--rand-rechts) var(--rand-unten) var(--rand-links);
    background: #fff;
    box-shadow: var(--shadow);
    color: #000;
    font-family: var(--font-body);
    font-size: 11pt;
    line-height: 1.5;
    box-sizing: border-box;
}

.sheet__kopf {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12mm;
    margin-bottom: 10mm;
}
.sheet__logo { height: 55px; width: auto; }
.sheet__org { text-align: left; font-family: var(--font-body); font-size: 10.5pt; line-height: 1.4; color: #000; }
.sheet__org-line { color: #000; }

.sheet__titel { font-family: var(--font-head); font-weight: 900; color: var(--drk-red); font-size: 20pt; margin: 0 0 2mm; }
.sheet__meta { color: #333; font-size: 10pt; margin: 0 0 8mm; }

.sheet__section { margin: 0 0 6mm; }
.sheet__h2 {
    font-family: var(--font-head); font-weight: 700; color: var(--drk-red); font-size: 12.5pt;
    border-bottom: 1px solid #ddd; padding-bottom: 1.5mm; margin: 0 0 3mm;
}
.sheet__dl { display: grid; grid-template-columns: 52mm 1fr; gap: 2mm 6mm; margin: 0; }
.sheet__dl dt { color: #555; font-weight: 600; }
.sheet__dl dd { margin: 0; color: #000; }
/* Mehrzeilige Felder stehen in echten Absaetzen statt in einem Block mit
   Zeilenschaltungen: nur so kann der Browser orphans und widows beachten. */
.sheet__abs { margin: 0 0 1em; }
.sheet__abs:last-child { margin-bottom: 0; }

.sheet__fuss { margin-top: 10mm; padding-top: 4mm; border-top: 1px solid #ddd; font-size: 8.5pt; color: #555; }
.sheet__fuss .mono { word-break: break-all; }

.konzept-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-3); }

/* ==========================================================================
   Zusammenhalt der Bloecke

   Diese Regeln stehen bewusst ausserhalb von @media print: sie wirken nur
   dort, wo ueberhaupt umbrochen wird, also im Druck und im mehrspaltigen
   Satz der Vorschau. Stuenden sie nur im Druckblock, braeche die Vorschau
   anders um als das Papier.

   Ein Abschnitt, der laenger als eine Seite ist, muss umbrechen duerfen. Ein
   pauschales break-inside: avoid kann der Browser dann nicht einhalten: er
   schiebt den Abschnitt auf eine neue Seite, laesst die vorige fast leer und
   trennt ihn anschliessend trotzdem. Zusammengehalten wird deshalb nur, was
   auch auf eine Seite passt.
   ========================================================================== */
.sheet__section { break-inside: auto; }
.sheet__titel, .sheet__h2 { break-after: avoid; }
/* Bezeichnung und Wert liegen im .sheet__dl in derselben Rasterzeile und
   koennen gar nicht auseinandergerissen werden. Ein zusaetzliches
   break-after: avoid am dt hat das Gegenteil bewirkt: weil jede Zeile mit
   einem dt beginnt, gab es im ganzen Raster keine erlaubte Trennstelle mehr,
   und der erste Abschnitt wanderte samt der halbleeren ersten Seite auf
   Seite zwei. */
.sheet__fuss { break-inside: avoid; }
.sheet p, .sheet dd, .sheet li { orphans: 2; widows: 2; }
.sheet figure, .sheet img { break-inside: avoid; }

/* Tabellen: Kopfzeile auf jeder Seite, keine Zeile in der Mitte trennen. */
.sheet thead { display: table-header-group; }
.sheet tr { break-inside: avoid; }

/* Erzwungener Blattanfang, etwa fuer jede Lagekarte als Anlage.
   Anders als die Regeln oben heisst dieser Umbruch je nach Umgebung
   verschieden. Im Mehrspaltensatz ist die Bruchstelle eine Spalte;
   "break-before: page" uebergeht der Spaltensatz. Nachgemessen an einem
   Konzept mit drei Anlagen: mit "page" allein zeigte die Vorschau sechs
   Seiten, das Papier sieben.

   Massgeblich ist nicht das Medium, sondern wo das Element steht. Im Satz
   der Vorschau ist die Bruchstelle immer eine Spalte, auch im Druck: dort
   werden die fertigen Blaetter gedruckt, in denen derselbe Spaltensatz noch
   einmal umbrochen wird. Nur die Quelle, die ohne Skript gedruckt wird,
   bricht auf Seiten um.

   Die Unterscheidung darf nicht an der Klasse hat-vorschau haengen: die
   setzt das Skript erst, nachdem es die Seiten gezaehlt hat. Zaehlung und
   Darstellung liefen dann unter verschiedenen Regeln, und die letzten
   Seiten fehlten. */
   Die beiden Eigenschaften page-break-before und break-before sind
   dieselbe Eigenschaft unter zwei Namen. Ein zusaetzliches
   "page-break-before: auto" neben "break-before: column" hat den Umbruch
   deshalb wieder aufgehoben; es darf je Regel nur einer von beiden
   Namen vorkommen. */
.sheet__anlage { page-break-before: always; }
.vorschau__satz .sheet__anlage { break-before: column; }

/* -- Druck ----------------------------------------------------------------
   Gedruckt werden die Blaetter der Vorschau, nicht die Quelle. Jedes Blatt
   ist genau eine A4-Seite gross und bringt seinen eigenen Kopf, seine
   eigene Fusszeile und seine Seitenzahl mit. Deshalb hat @page hier keinen
   Rand: die Raender stecken schon im Blatt.

   Der Weg ueber die Vorschau ist nicht Geschmackssache. Der Browser
   schreibt beim Drucken counter(page) nicht fort, eine Seitenzahl aus CSS
   gibt es also nicht; und ein Seitenkopf liesse sich nur ueber eine
   Satztabelle wiederholen, die am Bildschirm stoert. Beides loest sich,
   sobald die Seiten schon vor dem Druck feststehen.

   Faellt das Skript aus, fehlt die Klasse hat-vorschau. Dann wird wie
   bisher die Quelle gedruckt; sie traegt ihre Raender dann selbst.
   -------------------------------------------------------------------------- */
@media print {
    /* Raender fuer den Notbetrieb ohne Vorschau. Steht die Vorschau, schaltet
       das Skript druck-blatt.css frei und setzt den Rand auf null; die
       Blaetter bringen ihn dann selbst mit. */
    @page {
        size: A4;
        margin: var(--rand-oben) var(--rand-rechts) var(--rand-unten) var(--rand-links);
    }
    /* Die erste Seite kann oben mehr Platz brauchen, etwa fuer den Briefkopf. */
    @page :first { margin-top: var(--rand-oben-erste); }

    /* Alles, was zwischen Papierkante und Blatt liegt, muss weg. Der
       Vorgaberand des body betraegt 8 px; er allein hat ein 297 mm hohes
       Blatt ueber die Seite hinausgeschoben und nach jedem Blatt eine leere
       Seite erzeugt. */
    html, body { background: #fff !important; margin: 0 !important; padding: 0 !important; }
    .app-header, .app-footer, .app-nav, .app-sidebar, .nav-backdrop, .no-print, .skip-link { display: none !important; }
    .app-body, .app-content { display: block !important; }
    .app-shell, .app-body, .app-content { margin: 0 !important; padding: 0 !important; }
    .app-main { padding: 0 !important; margin: 0 !important; }
    .container { max-width: none !important; margin: 0 !important; padding: 0 !important; }

    /* Mit Vorschau: die Blaetter drucken, die Quelle zuruecktreten lassen.
       Die Blattmasse fuer den Druck stehen weiter unten, unmittelbar hinter
       den Bildschirmmassen -- sonst wuerden sie von diesen ueberschrieben,
       weil beide Regeln gleich stark sind und die spaetere gewinnt. */
    .hat-vorschau .sheet--quelle { display: none !important; }
    .hat-vorschau .vorschau { display: block !important; }

    /* Ohne Vorschau: die Raender kommen aus @page, nicht aus dem Blatt.
       padding-top wirkt nur auf das erste Teilstueck eines umbrechenden
       Blocks, padding-bottom nur auf das letzte; als Seitenrand taugt es
       deshalb nicht, und Folgeseiten begannen damit an der Blattkante. */
    html:not(.hat-vorschau) .sheet {
        width: auto; min-height: auto; margin: 0; padding: 0; box-shadow: none;
    }

    a[href]::after { content: ""; }
}

/* ==========================================================================
   Bildschirmvorschau: eine Seite je Spalte
   ========================================================================== */
@media screen {
    /* Sobald die Vorschau steht, tritt das durchgehende Blatt zurueck. Ohne
       Skript bleibt es sichtbar, dann sieht man wie bisher eine lange Bahn. */
    .sheet--quelle { display: none; }
}

.vorschau { display: flex; flex-direction: column; align-items: center; }

/* Messhilfe: so breit wie eine Spalte samt Zwischenraum. Das Skript liest
   daran ab, wie weit eine Seite zur naechsten versetzt ist. */
.vorschau__schritt { position: absolute; visibility: hidden; height: 0; width: var(--spalten-schritt); }

.vorschau__nummer {
    margin: 0 0 6px; align-self: flex-start;
    font-size: var(--fs-100); color: var(--gray-600);
}
.vorschau__blatt {
    position: relative; overflow: hidden;
    width: var(--blatt-breite); height: var(--blatt-hoehe);
    margin: 0 0 24px;
    background: #fff; box-shadow: var(--shadow);
}

/* Im Druck ist jedes Blatt eine Seite. Knapp unter 297 mm: ein Blatt in
   voller Seitenhoehe ragt durch die Rundung auf ganze Bildpunkte um
   Bruchteile ueber die Seite hinaus, und hinter jedem Blatt stand eine leere
   Seite. Die fehlenden 0,2 mm liegen unterhalb des Satzspiegels und sind
   nicht zu sehen. */
@media print {
    .vorschau__blatt {
        height: 296.8mm;
        margin: 0; box-shadow: none;
        break-after: page; page-break-after: always;
    }
    .vorschau__blatt:last-child { break-after: auto; page-break-after: auto; }
}

/* Der Satzkasten liegt deckungsgleich auf dem Blatt und ist um so viele
   Spaltenschritte nach links geschoben, wie die Seitennummer angibt. Was
   links oder rechts daneben liegt, schneidet das Blatt ab. */
.sheet.vorschau__satz {
    position: absolute; top: 0; left: 0;
    width: var(--blatt-breite); height: var(--blatt-hoehe); min-height: 0;
    margin: 0; box-shadow: none;
    padding: var(--rand-oben) var(--rand-rechts) var(--rand-unten) var(--rand-links);
    column-width: var(--satz-breite);
    column-gap: var(--spalten-luecke);
    column-fill: auto;
    transform: translateX(calc(-1 * var(--seite, 0) * var(--spalten-schritt)));
}
/* Die erste Seite kann oben mehr Rand brauchen als die folgenden. Im Druck
   leistet das @page :first, hier ein Vorlauf im Satz. */
.vorschau__ersterand { height: calc(var(--rand-oben-erste) - var(--rand-oben)); }

/* Ein Kasten mit eigenem Rollbalken laesst sich nicht auf Spalten verteilen;
   die Tabelle bliebe als ein Stueck stehen. Im Druck gilt dasselbe. */
.vorschau__satz .table-scroll { overflow: visible; }

/* -- Kassenbuch-Druck: schmale Tabelle, passt auf A4 -------------------- */
.sheet .kassenbuch { width: 100%; font-size: 8.5pt; border-collapse: collapse; }
.sheet .kassenbuch th, .sheet .kassenbuch td { padding: 1mm 1.5mm; border-bottom: .2mm solid #ddd; }
.sheet .kassenbuch thead th { color: #555; text-transform: uppercase; letter-spacing: .02em; font-size: 7.5pt; border-bottom: .4mm solid #999; }
.sheet .kassenbuch .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sheet .kassenbuch tfoot td { border-top: .4mm solid #999; }

/* Stammdaten als Tabelle mit Beschriftungsspalte: die Zeilenkoepfe stehen
   nicht im thead, sondern als th in der Zeile. Ohne feste Breite rutschten
   die Werte je Zeile unterschiedlich weit nach rechts. */
.sheet .kassenbuch--felder tbody th {
    width: 32mm; color: #555; font-weight: 600; text-align: left; vertical-align: top;
}
.sheet .kassenbuch--felder tbody td { vertical-align: top; }
/* Die Summenzeile steht einmal am Schluss. Ein <tfoot> wiederholt der Browser
   von sich aus auf jeder Seite, und dort stuende dann die Jahressumme unter
   einem Seitenausschnitt, als waere sie dessen Summe. Eine Seitensumme kann
   CSS nicht berechnen. */
.sheet .kassenbuch tfoot { display: table-row-group; }
/* Nachweis und Unterschriftenfeld bleiben beieinander. */
.druck-fuss { break-after: avoid; break-inside: avoid; }
.druck-unterschrift { break-inside: avoid; }
@media print { .table-scroll { overflow: visible; } }

/* -- Rechnung ----------------------------------------------------------- */
.sheet .rg__pos thead th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.sheet .rg__titel { font-size: 20pt; }
.sheet .rg__pos tbody td, .sheet .rg__pos thead th { padding: 2mm 3mm; }
/* Was inhaltlich zusammengehoert, bleibt beisammen: Rechnungskopf und Anrede
   nicht allein am Seitenfuss, Summenblock, Bankverbindung und Grussformel
   jeweils ungeteilt. Der Zahlungssatz behaelt seine Bankverbindung bei sich. */
.sheet .rg__kopfzeile, .sheet .rg__betreff, .sheet .rg__anrede { break-after: avoid; }
.sheet .rg__summe, .sheet .rg__bank, .sheet .rg__gruss { break-inside: avoid; }
.sheet .rg__zahlung { break-inside: avoid; break-after: avoid; }
.sheet .rg__summe { break-before: avoid; }