/* ------------------------------------------------------------------------
   Omerta - Prohibition, 1925
   Handgeschrieben, kein Framework. Dunkles Pergament, Messing, Blutrot.
   ------------------------------------------------------------------------ */

:root {
    /* Die Obergrenze der Seitenbreite.

       1180 war zu eng: auf einem 1920er Schirm blieben 741 px leer.

       1720 ist nachgerechnet und nicht geschaetzt. Abzueglich der
       32 px Innenabstand bleiben 1688 px Inhalt, und damit bekommt
       .grid-2 (minmax 320) seine fuenfte und .grid-3 (minmax 240) seine
       sechste Spalte - 5*320 + 4*20 = 1680 passt gerade hinein. Bei
       1680 waeren es 1648 und damit nur vier.

       Der naechste Sprung laege erst bei rund 2060, und dort hoert der
       Gewinn auf: eine Tabellenzeile ueber 2000 px liest sich
       schlechter, weil das Auge beim Ruecksprung die Zeile verliert.
       Deshalb eine feste Grenze und kein Prozentsatz des Schirms - auf
       einem sehr breiten Schirm bleibt bewusst Rand. */
    --wrap-max: 1720px;

    /* Abstandsskala.

       Vorher standen hier 23 verschiedene Pixelwerte nebeneinander - für
       margin, padding und gap zusammengezaehlt. Keiner davon war falsch,
       aber zusammen ergaben sie kein Raster, und das sieht man einer
       Seite an, auch wenn man nicht sagen kann, woran es liegt.

       Acht Stufen, auf Vielfachen von vier. Die alten Werte liegen alle
       hoechstens zwei Pixel daneben, die Umstellung aendert also nichts
       Sichtbares an einer einzelnen Stelle - nur am Zusammenklang. */
    --s-1: 4px;
    --s-2: 8px;
    --s-3: 12px;
    --s-4: 16px;
    --s-5: 20px;
    --s-6: 24px;
    --s-7: 32px;
    --s-8: 48px;
    --bg:          #14100d;
    --bg-panel:    #1e1813;
    --bg-panel-2:  #251d17;
    --bg-input:    #110d0a;
    --line:        #3a2e24;
    --line-soft:   #2c231b;

    --ink:         #e8dcc8;
    --ink-dim:     #a79781;
    --ink-faint:   #9c8b71;

    --brass:       #c8a456;
    --brass-dim:   #8f7439;
    --blood:       #9b2226;
    --blood-light: #c0392b;
    --green:       #5e8c4a;
    --amber:       #cf8a2e;

    /* Abgeleitete Farben. Sie stehen hier, weil sie sich zwischen hell
       und dunkel UMDREHEN muessen: auf dunklem Grund ist der lesbare
       Messington heller als das Messing, auf hellem dunkler. Ein
       color-mix koennte das nicht wissen. */
    --on-brass:  #e9cd84;
    --on-blood:  #e8c9c0;
    --on-green:  #a6c795;
    --on-amber:  #e6bd84;
    --link-hover: #e2c272;

    --on-primary:        #f3e2d4;
    --on-primary-strong: #ffffff;

    /* Flaechen und Schatten. */
    --shade:        rgba(255, 255, 255, .03);
    --shade-soft:   rgba(255, 255, 255, .02);
    --sunken:       rgba(0, 0, 0, .25);
    --shadow:       rgba(0, 0, 0, .35);
    --shadow-strong: rgba(0, 0, 0, .5);

    --bg-raised-a: #221b15;
    --bg-raised-b: #1a1510;

    --btn-a:       #2a211a;
    --btn-b:       #201a14;
    --btn-hover-a: #32281f;
    --btn-hover-b: #251e17;

    --primary-a:       #8c2b22;
    --primary-b:       #6d201a;
    --primary-hover-a: #a33428;
    --primary-hover-b: #7d2620;

    /* Papier: die Textur des Hintergrunds. */
    --paper-a:      #1a1511;
    --paper-b:      #171310;
    --paper-veil-a: rgba(20, 16, 13, 0.92);
    --paper-veil-b: rgba(20, 16, 13, 0.97);

    /* Karte. */
    --hex-stroke: #0d0a08;
    --hex-empty:  #3a2e24;

    --serif: Georgia, "Times New Roman", serif;
    --sans:  system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --mono:  "Cascadia Mono", Consolas, "Courier New", monospace;

    --radius: 2px;
}


/* --------------------------------------------------------------- Hell ----
   Dunkel ist die Grundlage; hell kommt dazu, wenn das System es wuenscht
   oder der Spieler es waehlt. Die Wahl schlaegt den Systemwunsch - sonst
   koennte man sie an einem Rechner, der dunkel eingestellt ist, nicht
   treffen.

   Gleiche Rollen, andere Werte: Papier statt Pergament, Sepiatinte statt
   Elfenbein, und ein dunkleres Messing, das auf hellem Grund noch
   Kontrast hat. Die Toenungen (color-mix) rechnen sich daraus von selbst. */

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) {
        color-scheme: light;

        --bg:          #e7dfd1;
        --bg-panel:    #f4efe4;
        --bg-panel-2:  #ebe4d5;
        --bg-input:    #fcf9f2;
        --line:        #b5a488;
        --line-soft:   #d6cab4;

        --ink:         #241c14;
        --ink-dim:     #574835;
        --ink-faint:   #6d5c40;

        --brass:       #7a5c16;
        --brass-dim:   #a8893c;
        --blood:       #8d1f23;
        --blood-light: #a8302c;
        --green:       #3f6b2c;
        --amber:       #8f5c0d;

        --on-brass:  #6b4f11;
        --on-blood:  #7a1a1e;
        --on-green:  #2f5220;
        --on-amber:  #74490a;
        --link-hover: #6b4f11;

        --on-primary:        #fdf6ee;
        --on-primary-strong: #ffffff;

        --shade:        rgba(0, 0, 0, .035);
        --shade-soft:   rgba(0, 0, 0, .022);
        --sunken:       rgba(0, 0, 0, .05);
        --shadow:       rgba(76, 58, 32, .16);
        --shadow-strong: rgba(76, 58, 32, .24);

        --bg-raised-a: #f6f1e7;
        --bg-raised-b: #ece5d7;

        --btn-a:       #f3ece0;
        --btn-b:       #e7dfcf;
        --btn-hover-a: #faf5ea;
        --btn-hover-b: #ece4d4;

        --primary-a:       #9b2226;
        --primary-b:       #80191d;
        --primary-hover-a: #ad2a2a;
        --primary-hover-b: #8d1f23;

        --paper-a:      #efe8da;
        --paper-b:      #e9e1d1;
        --paper-veil-a: rgba(238, 231, 218, 0.88);
        --paper-veil-b: rgba(233, 225, 211, 0.95);

        --hex-stroke: #9d8b6d;
        --hex-empty:  #cfc3ac;
    }
}

:root[data-theme="light"] {
    color-scheme: light;

    --bg:          #e7dfd1;
    --bg-panel:    #f4efe4;
    --bg-panel-2:  #ebe4d5;
    --bg-input:    #fcf9f2;
    --line:        #b5a488;
    --line-soft:   #d6cab4;

    --ink:         #241c14;
    --ink-dim:     #574835;
    --ink-faint:   #6d5c40;

    --brass:       #7a5c16;
    --brass-dim:   #a8893c;
    --blood:       #8d1f23;
    --blood-light: #a8302c;
    --green:       #3f6b2c;
    --amber:       #8f5c0d;

    --on-brass:  #6b4f11;
    --on-blood:  #7a1a1e;
    --on-green:  #2f5220;
    --on-amber:  #74490a;
    --link-hover: #6b4f11;

    --on-primary:        #fdf6ee;
    --on-primary-strong: #ffffff;

    --shade:        rgba(0, 0, 0, .035);
    --shade-soft:   rgba(0, 0, 0, .022);
    --sunken:       rgba(0, 0, 0, .05);
    --shadow:       rgba(76, 58, 32, .16);
    --shadow-strong: rgba(76, 58, 32, .24);

    --bg-raised-a: #f6f1e7;
    --bg-raised-b: #ece5d7;

    --btn-a:       #f3ece0;
    --btn-b:       #e7dfcf;
    --btn-hover-a: #faf5ea;
    --btn-hover-b: #ece4d4;

    --primary-a:       #9b2226;
    --primary-b:       #80191d;
    --primary-hover-a: #ad2a2a;
    --primary-hover-b: #8d1f23;

    --paper-a:      #efe8da;
    --paper-b:      #e9e1d1;
    --paper-veil-a: rgba(238, 231, 218, 0.88);
    --paper-veil-b: rgba(233, 225, 211, 0.95);

    --hex-stroke: #9d8b6d;
    --hex-empty:  #cfc3ac;
}

* { box-sizing: border-box; }

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

body {
    margin: 0;
    background:
        linear-gradient(var(--paper-veil-a), var(--paper-veil-b)),
        repeating-linear-gradient(135deg, var(--paper-a) 0 2px, var(--paper-b) 2px 4px);
    color: var(--ink);
    font: 15px/1.6 var(--sans);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Die Breite der Seite.

   1180 px war EINE Zahl fuer jede Seite und liess auf einem 1920er
   Schirm 741 px leer - 39 Prozent, nachgemessen. Breiter heisst hier
   ausdruecklich NICHT laengere Textzeilen: .lede und die Fliesstexte
   haben ihre eigene Grenze in Zeichen (62ch bzw. 78ch). Es heisst mehr
   Panels nebeneinander, weil .grid-2 und .grid-3 mit auto-fit von selbst mehr
   Spalten bildet, sobald es Platz gibt. Die Breite zu aendern, bringt
   deshalb an genau den Stellen etwas, an denen Platz nuetzt, und
   nirgends dort, wo er schadet. */
.wrap { width: 100%; max-width: var(--wrap-max); margin: 0 auto; padding: 0 var(--s-4); }

main.wrap { flex: 1; padding-bottom: var(--s-8); }

a { color: var(--brass); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; line-height: 1.25; margin: 0 0 .5em; }
h1 { font-size: 1.85rem; letter-spacing: .01em; }
h2 { font-size: 1.3rem; color: var(--brass); }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1em; }
.muted  { color: var(--ink-dim); }
.faint  { color: var(--ink-faint); }
.small  { font-size: .86rem; }
.mono   { font-family: var(--mono); }
.center { text-align: center; }
.right  { text-align: right; }
.nowrap { white-space: nowrap; }

hr { border: 0; border-top: 1px solid var(--line-soft); margin: 1.5rem 0; }

/* ----------------------------------------------------------- Kopfleiste -- */

.topbar {
    background: linear-gradient(var(--bg-raised-a), var(--bg-raised-b));
    border-bottom: 1px solid var(--line);
    box-shadow: 0 2px 12px var(--shadow-strong);
    margin-bottom: var(--s-6);
}

.topbar-inner {
    display: flex;
    align-items: center;
    gap: var(--s-5);
    flex-wrap: wrap;
    padding-top: 10px;
    padding-bottom: 10px;
}

.brand {
    font-family: var(--serif);
    font-size: 1.5rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--brass);
    border: 1px solid var(--brass-dim);
    padding: 2px var(--s-3);
}
.brand:hover { text-decoration: none; background: color-mix(in srgb, var(--brass) 8%, transparent); }

.stats { display: flex; gap: var(--s-5); flex-wrap: wrap; margin-left: auto; }

.stat { display: flex; flex-direction: column; line-height: 1.2; }
.stat-label {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--ink-faint);
}
.stat strong { font-family: var(--serif); font-size: 1.05rem; color: var(--ink); }

.topbar-right { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.boss-name { font-family: var(--serif); }

.pill {
    border: 1px solid var(--line);
    padding: 3px 10px;
    font-size: .82rem;
    border-radius: 999px;
    color: var(--ink-dim);
}
.pill:hover { text-decoration: none; border-color: var(--brass-dim); color: var(--ink); }
.pill-alert {
    border-color: var(--blood);
    color: var(--on-blood);
    background: color-mix(in srgb, var(--blood) 18%, transparent);
}

.tag {
    font-family: var(--mono);
    font-size: .74rem;
    letter-spacing: .06em;
    padding: 2px 6px;
    border: 1px solid var(--tag, var(--blood));
    color: var(--tag, var(--blood));
    background: color-mix(in srgb, var(--tag, var(--blood)) 14%, transparent);
}

/* Das Menue.
   ---------------------------------------------------------------------
   Vorher war die Leiste ein waagerecht scrollender Streifen: bei 375 px
   waren 576 px der 951 px breiten Leiste nur durch Ziehen erreichbar,
   ohne jeden Hinweis darauf, dass da noch etwas ist. Fuenf von zwoelf
   Punkten sah man nie.

   Jetzt ist sie ein <details>. Kein JavaScript und trotzdem beides:
   ein Kind mit display:flex bleibt auch im geschlossenen Zustand
   sichtbar (nachgemessen), also zeigt die breite Ansicht die Leiste und
   nur die schmale den Knopf. Den Zustand fuehrt der Browser - ohne
   Skript bleibt das Menue bedienbar, und es gibt nichts, was beim Laden
   kurz falsch aussieht. */
.mainnav { border-top: 1px solid var(--line-soft); background: var(--sunken); }

/* Breit: kein Knopf. Das Skript macht ihn sichtbar, indem es [hidden]
   entfernt - ohne Skript bleibt er weg und die Leiste offen. */
.navtoggle { display: none; }

/* Umbrechen statt scrollen: zwischen Telefon und grossem Schirm steht
   die Leiste lieber zweizeilig da, als Punkte zu verstecken. */
.navlinks { display: flex; flex-wrap: wrap; gap: 2px; align-items: center; }

.navidentity {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    padding-left: 14px;
    font-size: .9rem;
}

.mainnav a {
    padding: 9px var(--s-4);
    font-size: .9rem;
    color: var(--ink-dim);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
}
.mainnav a:hover { color: var(--ink); text-decoration: none; background: var(--shade); }
.mainnav a.active { color: var(--brass); border-bottom-color: var(--brass); }

/* Der Knopf, der das Menue oeffnet. Drei Striche aus einem Kasten und
   zwei Pseudoelementen; aufgeklappt werden daraus zwei gekreuzte, damit
   der Zustand ohne Text abzulesen ist. */
.navtoggle-bars {
    position: relative;
    display: inline-block;
    width: 18px;
    height: 2px;
    background: currentColor;
}
.navtoggle-bars::before,
.navtoggle-bars::after {
    content: '';
    position: absolute;
    left: 0;
    width: 18px;
    height: 2px;
    background: currentColor;
}
.navtoggle-bars::before { top: -6px; }
.navtoggle-bars::after  { top: 6px; }

[data-nav="open"] .navtoggle-bars { background: transparent; }
[data-nav="open"] .navtoggle-bars::before { top: 0; transform: rotate(45deg); }
[data-nav="open"] .navtoggle-bars::after  { top: 0; transform: rotate(-45deg); }

/* --- Schmale Schirme -------------------------------------------------

   Gemessen auf 375x812: die Kopfleiste war 233 px hoch, also 29 Prozent
   des Schirms, bevor etwas Eigenes kam. Vier Zeilen, weil Marke,
   Kennzahlen, Schalter und Kennung alle nebeneinander standen und
   umbrachen.

   Jetzt zwei Zeilen: Marke, Thema und Meldungen oben, die vier
   Kennzahlen darunter. Name, Kuerzel und Abmelden stecken im Menue -
   man braucht sie selten, und im Kopf kosteten sie eine ganze Zeile. */
@media (max-width: 760px) {
    .topbar-inner { gap: var(--s-2) 10px; padding-top: var(--s-2); padding-bottom: var(--s-2); }

    /* Ohne Rahmen und eine Spur kleiner. Gemessen passten Marke und
       Schalter zusammen auf 354 px, verfuegbar waren 343 - fuer elf
       Pixel brach eine ganze Zeile um. Der Rahmen ist Zierde; die Zeile
       ist Platz. */
    .brand {
        font-size: 1rem;
        letter-spacing: .08em;
        border: 0;
        padding: 0;
    }
    .brand:hover { background: none; }

    .pill { padding: 3px var(--s-2); font-size: .75rem; }

    /* Die Kennzahlen sind auf dem Telefon das Wichtigste im Kopf. Sie
       bekommen die ganze Zeile und verteilen sich darauf, statt rechts
       zu kleben. */
    .stats {
        order: 3;
        width: 100%;
        margin-left: 0;
        justify-content: space-between;
        gap: 6px;
    }
    .stat-label { font-size: .58rem; letter-spacing: .05em; }
    .stat strong { font-size: .92rem; }

    .topbar-right { margin-left: auto; gap: var(--s-2); }

    /* :not([hidden]), damit der Knopf ohne Skript verborgen bleibt -
       display:flex wuerde die Vorgabe des Browsers sonst aushebeln. */
    .navtoggle:not([hidden]) {
        display: flex;
        align-items: center;
        gap: 10px;
        width: 100%;
        padding: var(--s-3) var(--s-4);
        border: 0;
        border-top: 1px solid var(--line-soft);
        background: var(--sunken);
        color: var(--ink-dim);
        font: inherit;
        font-size: .92rem;
        text-align: left;
        cursor: pointer;
    }
    [data-nav="open"] .navtoggle { color: var(--ink); }
    [data-nav="closed"] .mainnav { display: none; }

    /* Zugeklappt ist sonst nicht zu sehen, wo man gerade ist. */
    .navtoggle-here {
        margin-left: auto;
        color: var(--brass);
        font-family: var(--serif);
    }

    /* Zwei Spalten: zwoelf Punkte untereinander waeren ueber 500 px und
       damit wieder eine Liste, durch die man scrollt. */
    .navlinks {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0 var(--s-3);
        padding-top: 6px;
        padding-bottom: 10px;
    }
    .navlinks a {
        padding: 10px 6px;
        border-bottom: 1px solid var(--line-soft);
        border-left: 2px solid transparent;
    }
    .navlinks a.active { border-left-color: var(--brass); padding-left: 10px; }

    .mainnav a.nav-admin { margin-left: 0; border-left: 2px solid transparent; }
    .navlinks .nav-admin,
    .navlinks .navidentity { grid-column: 1 / -1; }

    .navidentity {
        margin-left: 0;
        padding-left: 0;
        padding-top: var(--s-3);
        flex-wrap: wrap;
    }
}

/* ---------------------------------------------------------------- Flash -- */

.flashes { margin-bottom: var(--s-5); }
.flash {
    margin: 0 0 var(--s-2);
    padding: 10px 14px;
    border-left: 3px solid var(--line);
    background: var(--bg-panel);
    font-size: .93rem;
}
.flash-success { border-left-color: var(--green);  background: color-mix(in srgb, var(--green) 12%, transparent); }
.flash-error   { border-left-color: var(--blood);  background: color-mix(in srgb, var(--blood) 14%, transparent); }
.flash-warning { border-left-color: var(--amber);  background: color-mix(in srgb, var(--amber) 12%, transparent); }
.flash-info    { border-left-color: var(--brass-dim); }

/* ---------------------------------------------------------------- Panels - */

.panel {
    background: var(--bg-panel);
    border: 1px solid var(--line-soft);
    padding: var(--s-5);
    margin-bottom: var(--s-5);
}
.panel > :last-child { margin-bottom: 0; }

.panel-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
    margin-bottom: var(--s-3);
    padding-bottom: var(--s-2);
    border-bottom: 1px solid var(--line-soft);
}
.panel-head h2, .panel-head h3 { margin: 0; }

.grid { display: grid; gap: var(--s-5); }

/* Rasterkinder haben von sich aus min-width: auto und schrumpfen deshalb
   NICHT unter die Breite ihres breitesten Inhalts. Eine Tabelle oder ein
   langes Wort in einer Spalte zieht damit die ganze Spalte auf - und auf
   dem Telefon die ganze Seite, die dann seitlich schiebt. Das ist die
   haeufigste Ursache fuer waagerechtes Scrollen und von aussen nicht zu
   sehen, weil das Raster selbst richtig aussieht. */
.grid > * { min-width: 0; }
/* min(…, 100%) statt der nackten Mindestbreite: ein Raster mit
   minmax(320px, 1fr) zwingt die Spalte auf 320 Pixel, auch wenn nur 288
   da sind - dann ragt das Panel aus dem Bildschirm. Auf einem 320er
   Telefon waren das genau die 16 Pixel Rand, die die Seite schieben
   liessen. */
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); }
/* Bei 1560 px haette eine 1fr-Spalte rund 500 px - das ist keine
   Seitenleiste mehr, sondern eine zweite Hauptspalte. Darum oben eine
   feste Obergrenze: die Hauptspalte nimmt den gewonnenen Platz. */
.grid-sidebar { grid-template-columns: minmax(0, 1fr) minmax(min(260px, 100%), 360px); }

@media (max-width: 860px) {
    .grid-sidebar { grid-template-columns: 1fr; }
}

/* Eine Tabelle, die breiter ist als ihr Platz, scrollt IN SICH, statt die
   ganze Seite seitlich zu schieben.

   Das gilt bei jeder Breite, nicht erst auf dem Telefon: zwei Tabellen
   nebeneinander sprengen schon ein Tablet. Nachgemessen kostet es auf dem
   Desktop nichts - die Tabelle fuellt ihr Panel weiterhin auf den Pixel
   genau, weil width: 100% auch fuer einen Blockkasten gilt.

   Umbrechen statt scrollen waere die Alternative, ist aber schlechter:
   eine Tabelle mit acht Spalten - der Maschinenraum der gemachten Maenner
   etwa - wird gestapelt unlesbar, weil man ohne Kopfzeile nicht mehr
   weiss, welche Zahl welche ist.

   Schmal zusaetzlich: die erste Spalte darf umbrechen, sonst bestimmt der
   laengste Name die Breite der ganzen Tabelle; die uebrigen bleiben
   einzeilig, damit Zahlenspalten schmal bleiben. */
main table,
.install-shell table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
}

@media (max-width: 720px) {
    main table th,
    main table td,
    .install-shell table th,
    .install-shell table td { white-space: nowrap; }

    main table th:first-child,
    main table td:first-child,
    .install-shell table th:first-child,
    .install-shell table td:first-child {
        white-space: normal;
        min-width: 8em;
    }
}

/* --------------------------------------------------------------- Tabellen */

table { width: 100%; border-collapse: collapse; font-size: .92rem; }

/* vertical-align: top statt middle.

   Bei einzeiligen Zeilen ist beides gleich. Sobald eine Zelle umbricht -
   ein Auftragsname mit Beschreibung, eine Anforderungsliste - schwimmen
   die kurzen Nachbarzellen bei "middle" in der Mitte und haben mit der
   ersten Zeile nichts mehr zu tun. Oben ausgerichtet liest sich eine
   Zeile als Zeile. */
th, td {
    padding: var(--s-2) var(--s-3);
    text-align: left;
    border-bottom: 1px solid var(--line-soft);
    vertical-align: top;
}
th {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--ink-faint);
    font-weight: 600;
}
tbody tr:hover { background: var(--shade-soft); }
/* Eine Zahl ist ein Wort.

   Gesehen auf der Auftragsseite: "24.000" und "$" standen untereinander,
   "2h" und "00m" ebenso. Bisher galt nowrap nur unter 720 px, also
   ausgerechnet dort, wo am wenigsten Platz ist - und nicht dort, wo die
   Spalte zufaellig zu schmal geraten war. */
td.num, th.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.table-compact th, .table-compact td { padding: var(--s-1) var(--s-2); }

/* "Nimm, was uebrig ist."

   width: 100% auf EINE Spalte heisst in einer Tabelle nicht "so breit
   wie die Tabelle", sondern dass dieser Spalte der freie Platz zufaellt.
   Ohne das blieb die Namensspalte der Rangliste bei 163 px - bei 980 px
   Fenster wie bei 1720 -, weil die Zahlenspalten mit nowrap ihre Breite
   fordern und eine umbrechbare Spalte eine kleine Wunschbreite hat. */
.col-grow { width: 100%; }

/* Die eigene Zeile in einer Rangliste. Vorher ein style-Attribut mit
   rgba(200,164,86,.08) - Messing mit 8 Prozent, aber hart und damit
   blind gegen das Thema. */
tbody tr.row-self { background: color-mix(in srgb, var(--brass) 8%, transparent); }

/* Die aeussersten Spalten bekommen keinen eigenen Rand: sonst beginnt
   die erste Tabellenspalte 12 px weiter innen als die Ueberschrift
   darueber, und das Panel hat zwei linke Kanten. */
.panel > table th:first-child,
.panel > table td:first-child { padding-left: 0; }
.panel > table th:last-child,
.panel > table td:last-child { padding-right: 0; }

/* Was ein Auftrag an Stand einbringt - Ruf, Einfluss, Rueckhalt,
   Abkuehlung. Messing, weil es derselbe Gewinn ist wie das Geld darueber,
   nur nicht in Dollar. Vorher stand er nirgends, und sechs Auftraege
   sahen deshalb aus, als braechten sie nichts. */
.job-gains { color: var(--brass); white-space: normal; }

/* Eine Warenangabe ist ein Satzteil, keine Zahl - sie darf umbrechen,
   auch wenn sie in einer .num-Spalte steht. */
.job-goods { white-space: normal; }

/* Eine Zwischenzeile, die eine Tabelle in Abschnitte teilt, ohne sie in
   mehrere Tabellen zu zerlegen. Die Spalten bleiben damit ueberall gleich
   breit - das war der ganze Grund. */
tr.row-group th {
    padding-top: var(--s-5);
    padding-bottom: var(--s-2);
    border-bottom: 1px solid var(--line);
    font-family: var(--serif);
    font-size: .95rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    color: var(--brass);
}
tbody tr.row-group:first-child th { padding-top: var(--s-1); }
tr.row-group:hover { background: none; }

/* ------------------------------------------------------------- Zeitung -- */

/* Ein abgesetzter Block IN einem Panel - drei Druckvarianten
   untereinander, jede ein eigenes Formular. Ohne die Absetzung laesen
   sie sich als ein langes Formular mit drei Knoepfen, und man waehlte
   aus Versehen die falsche Ausgabe. */
.panel-inset {
    border: 1px solid var(--line-soft);
    background: var(--sunken);
    padding: var(--s-3);
    margin-bottom: var(--s-3);
}
.panel-inset:last-child { margin-bottom: 0; }
.panel-inset h3 { margin-bottom: var(--s-1); }
.panel-inset p { margin-bottom: var(--s-3); max-width: 60ch; }

.press-run {
    padding: var(--s-2) 0;
    border-bottom: 1px solid var(--line-soft);
}
.press-run:last-child { border-bottom: 0; padding-bottom: 0; }

/* Eine Schlagzeile ist eine Schlagzeile: Serifen, etwas groesser, und
   sie darf umbrechen. */
.press-headline {
    font-family: var(--serif);
    font-size: 1.02rem;
    line-height: 1.3;
    color: var(--ink);
    margin-bottom: 2px;
}

/* --------------------------------------------------------------- Buttons - */

button, .btn {
    font: inherit;
    font-size: .9rem;
    padding: 7px var(--s-4);
    border: 1px solid var(--brass-dim);
    background: linear-gradient(var(--btn-a), var(--btn-b));
    color: var(--brass);
    cursor: pointer;
    border-radius: var(--radius);
    display: inline-block;
}
button:hover, .btn:hover {
    border-color: var(--brass);
    color: var(--on-brass);
    text-decoration: none;
    background: linear-gradient(var(--btn-hover-a), var(--btn-hover-b));
}
button:disabled, .btn.disabled {
    opacity: .45;
    cursor: not-allowed;
    border-color: var(--line);
    color: var(--ink-faint);
}

.btn-primary {
    background: linear-gradient(var(--primary-a), var(--primary-b));
    border-color: var(--blood-light);
    color: var(--on-primary);
}
.btn-primary:hover {
    background: linear-gradient(var(--primary-hover-a), var(--primary-hover-b));
    color: var(--on-primary-strong);
}

.btn-ghost { background: transparent; border-color: var(--line); color: var(--ink-dim); }
.btn-ghost:hover { background: var(--shade); }

.btn-small { font-size: .8rem; padding: var(--s-1) 10px; }
.btn-danger { border-color: var(--blood); color: var(--on-blood); }
.btn-danger:hover {
    border-color: var(--blood-light);
    color: var(--on-primary-strong);
    background: color-mix(in srgb, var(--blood) 25%, transparent);
}

button.link {
    background: none; border: 0; padding: 0;
    color: var(--ink-dim);
    font-size: .85rem;
    text-decoration: underline;
}
button.link:hover { color: var(--brass); }

form.inline { display: inline; }

/* Menge und Knopf gehoeren nebeneinander.

   Als display:inline in einer schmalen Spalte brachen sie um, und jede
   Zeile der Tabelle wurde dadurch doppelt so hoch wie noetig. Als Flex
   bleiben sie zusammen und die Spalte bekommt die Breite, die sie
   braucht. */
.buy-form {
    display: flex;
    gap: var(--s-1);
    align-items: center;
    justify-content: flex-end;
}
.buy-form input[type="number"] { width: 4em; }
.actions { display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }

/* --------------------------------------------------------------- Formular */

label { display: block; margin-bottom: var(--s-1); font-size: .82rem; color: var(--ink-dim); }

input[type=text], input[type=email], input[type=password], input[type=number],
input[type=color], select, textarea {
    font: inherit;
    width: 100%;
    padding: var(--s-2) 10px;
    background: var(--bg-input);
    border: 1px solid var(--line);
    color: var(--ink);
    border-radius: var(--radius);
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brass-dim);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--brass) 20%, transparent);
}
input[type=color] { padding: 2px; height: 38px; }
textarea { min-height: 80px; resize: vertical; }

/* Ein Feld fuer eine Zahl braucht die Breite einer Zahl.

   width:100% gilt fuer alle Eingaben, und das ist bei einem Namen oder
   einem Betrag richtig. Bei "Hoechstens je Tag: 2" entstand daraus ein
   350 px breiter Kasten fuer ein Zeichen - die Seite sah aus, als fehle
   dort etwas. Die Obergrenze laesst das Feld weiterhin mitwachsen, wenn
   die Spalte schmal ist. */
input[type=number] { max-width: 9em; }

/* Ausgenommen, wo die Zahl selbst lang wird. */
input[type=number].wide { max-width: none; }

.field { margin-bottom: 14px; }
.field-row { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.field-row > .field { flex: 1 1 160px; margin-bottom: 0; }

.check { display: flex; align-items: flex-start; gap: var(--s-2); margin-bottom: 6px; }
.check input { margin-top: var(--s-1); width: auto; }
.check label { margin: 0; color: var(--ink); font-size: .9rem; cursor: pointer; }
.check .hint { display: block; color: var(--ink-faint); font-size: .78rem; }

.errors {
    border-left: 3px solid var(--blood);
    background: color-mix(in srgb, var(--blood) 14%, transparent);
    padding: 10px 14px;
    margin-bottom: var(--s-4);
}
.errors ul { margin: 0; padding-left: var(--s-5); }

/* ------------------------------------------------------------- Anzeigen -- */

.bar {
    display: inline-block;
    width: 100%;
    max-width: 120px;
    height: 7px;
    background: var(--bg-input);
    border: 1px solid var(--line);
    vertical-align: middle;
    overflow: hidden;
}
.bar-fill { display: block; height: 100%; background: var(--brass-dim); }
.bar.good .bar-fill { background: var(--green); }
.bar.mid  .bar-fill { background: var(--brass); }
.bar.warn .bar-fill { background: var(--amber); }
.bar.bad  .bar-fill { background: var(--blood-light); }

.badge {
    display: inline-block;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    padding: 2px 7px;
    border: 1px solid var(--line);
    color: var(--ink-dim);
}
.badge-good { border-color: var(--green);  color: var(--on-green); }
.badge-bad  { border-color: var(--blood);  color: var(--on-blood); }
.badge-warn { border-color: var(--amber);  color: var(--on-amber); }
.badge-info { border-color: var(--brass-dim); color: var(--brass); }

.status-idle    { color: var(--green); }
.status-busy    { color: var(--brass); }
.status-wounded { color: var(--amber); }
.status-jailed  { color: var(--blood-light); }
.status-dead    { color: var(--ink-faint); text-decoration: line-through; }

.countdown { font-family: var(--mono); font-size: .88rem; color: var(--brass); }

.stat-row { display: flex; gap: 14px; flex-wrap: wrap; font-size: .86rem; }
.stat-row span { color: var(--ink-dim); }
.stat-row strong { color: var(--ink); }

.empty {
    padding: 28px var(--s-5);
    text-align: center;
    color: var(--ink-faint);
    border: 1px dashed var(--line);
    font-style: italic;
}

/* --------------------------------------------------------- Mannschaftsliste */

.man {
    display: flex;
    gap: var(--s-3);
    align-items: flex-start;
    padding: 10px 0;
    border-bottom: 1px solid var(--line-soft);
}
.man:last-child { border-bottom: 0; }
.man-main { flex: 1 1 auto; min-width: 0; }
.man-name { font-family: var(--serif); font-size: 1rem; }
.man-meta { font-size: .8rem; color: var(--ink-dim); }
.man-side { text-align: right; font-size: .82rem; white-space: nowrap; }

.traits { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 5px; }
.trait {
    font-size: .74rem;
    padding: 1px 6px;
    border: 1px solid var(--line);
    color: var(--ink-dim);
    cursor: help;
}
.trait-good { border-color: var(--brass-dim); color: var(--brass); }
.trait-bad  { border-color: color-mix(in srgb, var(--blood) 60%, var(--line)); color: var(--on-blood); }
.trait-hidden { border-style: dashed; color: var(--ink-faint); }

.statline { display: flex; gap: 10px; font-family: var(--mono); font-size: .8rem; color: var(--ink-dim); }
.statline b { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------- Hex-Karte - */

.map-shell { overflow-x: auto; padding: var(--s-2) 0 var(--s-4); }
.hexmap { display: block; margin: 0 auto; max-width: 100%; height: auto; }

.hex { cursor: pointer; transition: filter .12s; }
.hex:hover { filter: brightness(1.35); }
.hex-shape { stroke: var(--hex-stroke); stroke-width: 1.5; }
.hex-label {
    font-family: var(--serif);
    font-size: 10px;
    fill: var(--ink);
    text-anchor: middle;
    pointer-events: none;
}
.hex-sub {
    font-family: var(--sans);
    font-size: 8.5px;
    fill: var(--ink-faint);
    text-anchor: middle;
    pointer-events: none;
}

/* Bei 50 Revieren wird die Karte breiter als der Container - waagerecht
   scrollen statt alles unlesbar zu schrumpfen. */
.map-shell { max-width: 100%; }
.hexmap { min-width: 540px; }
.hex-contested { stroke: var(--amber); stroke-width: 2; stroke-dasharray: 3 2; }

.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: .82rem; margin-top: var(--s-3); }
.legend-item { display: flex; align-items: center; gap: 6px; }
.swatch { width: 13px; height: 13px; border: 1px solid var(--hex-stroke); display: inline-block; }

/* ------------------------------------------------------- Einflussleisten - */

.influence-row {
    display: grid;
    grid-template-columns: 90px 1fr 110px;
    gap: 10px;
    align-items: center;
    padding: 5px 0;
    font-size: .88rem;
}
.influence-track {
    height: 14px;
    background: var(--bg-input);
    border: 1px solid var(--line);
    position: relative;
    overflow: hidden;
}
.influence-fill { height: 100%; opacity: .85; }
.influence-target {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: var(--ink);
    opacity: .6;
}
.influence-num { font-variant-numeric: tabular-nums; text-align: right; }
.influence-rate { font-size: .78rem; }
.rate-up   { color: var(--green); }
.rate-down { color: var(--blood-light); }

/* ------------------------------------------------------------- Berichte -- */

.report-lines { border-left: 2px solid var(--brass-dim); padding-left: 14px; margin: 0 0 var(--s-4); }
.report-lines p { margin: 0 0 .4em; font-family: var(--serif); font-size: 1.02rem; }

.rounds { list-style: none; margin: 0; padding: 0; font-size: .9rem; }
.rounds li { padding: 5px 0 5px var(--s-3); border-left: 2px solid var(--line); }
.rounds li.fatal { border-left-color: var(--blood); }
.rounds li.attacker { border-left-color: var(--brass-dim); }

.fate-unversehrt { color: var(--green); }
.fate-verwundet  { color: var(--amber); }
.fate-verhaftet  { color: var(--blood-light); }
.fate-gefallen   { color: var(--blood-light); font-weight: 600; }

/* --------------------------------------------------------------- Auswahl - */

.picker { border: 1px solid var(--line); background: var(--bg-input); max-height: 340px; overflow-y: auto; }
.picker-item {
    display: flex;
    gap: 10px;
    align-items: center;
    padding: 7px 10px;
    border-bottom: 1px solid var(--line-soft);
    cursor: pointer;
}
.picker-item:last-child { border-bottom: 0; }
.picker-item:hover { background: var(--shade); }
.picker-item input { width: auto; margin: 0; }
.picker-item.selected { background: color-mix(in srgb, var(--brass) 14%, transparent); }
.picker-main { flex: 1; min-width: 0; }
.picker-tools {
    display: flex;
    gap: var(--s-2);
    align-items: center;
    padding: 7px 10px;
    border-bottom: 1px solid var(--line);
    background: var(--bg-panel-2);
    font-size: .82rem;
    flex-wrap: wrap;
}

.odds {
    font-family: var(--serif);
    font-size: 1.1rem;
    padding: 10px 14px;
    border: 1px solid var(--line);
    background: var(--bg-panel-2);
}
.odds-good { border-color: var(--green); }
.odds-mid  { border-color: var(--amber); }
.odds-bad  { border-color: var(--blood); }

/* ---------------------------------------------------------------- Diverse */

.site-footer {
    display: flex;
    justify-content: space-between;
    gap: var(--s-3);
    flex-wrap: wrap;
    padding: var(--s-4);
    border-top: 1px solid var(--line-soft);
    font-size: .8rem;
    color: var(--ink-faint);
}

.kv { display: grid; grid-template-columns: auto 1fr; gap: var(--s-1) 14px; font-size: .9rem; }
.kv dt { color: var(--ink-dim); }
.kv dd { margin: 0; }

.lede { font-family: var(--serif); font-size: 1.08rem; color: var(--ink-dim); max-width: 62ch; }

/* Erklaerender Fliesstext bekommt eine Zeilengrenze.

   Ohne sie waere die breitere Seite eine Verschlechterung: eine Zeile
   ueber 85 Zeichen liest sich schlechter, weil das Auge beim
   Ruecksprung die Zeile verliert. Nachgemessen standen nach der
   Verbreiterung acht Absaetze zwischen 102 und 169 Zeichen.

   Vorher stand hier ".panel > p" - das traf nur direkte Kinder und
   damit die wenigsten. Jetzt jeder Absatz und jeder Listenpunkt im
   Inhalt; ausgenommen ist, was den Platz braucht: zentrierte Saetze
   (deren Rand waere sonst einseitig) und alles in einer Tabellenzelle,
   wo die Spalte die Breite bestimmt. */
main p,
main li { max-width: 78ch; }

main p.center,
main td p,
main td li,
main th p { max-width: none; }

.auth-shell { max-width: 420px; margin: 8vh auto; }
.auth-shell .brand { display: inline-block; margin-bottom: var(--s-5); }

.rank-card { border: 1px solid var(--line-soft); background: var(--bg-panel-2); padding: 14px; margin-bottom: var(--s-3); }
.rank-card.is-leader { border-color: var(--brass-dim); }
.rank-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rank-name { font-family: var(--serif); font-size: 1.1rem; }
.rank-perms { display: flex; gap: 6px; flex-wrap: wrap; margin-top: var(--s-2); }

details.editor { margin-top: 10px; }
details.editor > summary { cursor: pointer; color: var(--ink-dim); font-size: .85rem; }
details.editor > summary:hover { color: var(--brass); }
details.editor[open] > summary { margin-bottom: 10px; }

@media (max-width: 640px) {
    .topbar-inner { gap: var(--s-3); }
    .stats { width: 100%; margin-left: 0; gap: 14px; }
    h1 { font-size: 1.45rem; }
    .influence-row { grid-template-columns: 70px 1fr; }
    .influence-num { grid-column: 2; text-align: left; }
}

/* ------------------------------------------------------------ Einrichtung */

.install-body { background: linear-gradient(var(--paper-veil-a), var(--paper-veil-b)), var(--paper-b); }

.install-shell { width: 100%; max-width: 760px; margin: 0 auto; padding: 5vh var(--s-4) var(--s-8); }

.install-head { text-align: center; margin-bottom: var(--s-6); }

.install-foot { text-align: center; margin-top: var(--s-6); }

.stepper {
    display: flex;
    gap: var(--s-1);
    list-style: none;
    margin: 0 0 var(--s-6);
    padding: 0;
    flex-wrap: wrap;
    justify-content: center;
}

.step {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 6px var(--s-3);
    font-size: .84rem;
    border: 1px solid var(--line-soft);
    background: var(--bg-panel);
    color: var(--ink-faint);
}

.step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 1px solid currentColor;
    font-size: .74rem;
    flex: 0 0 auto;
}

.step-done    { color: var(--green); border-color: color-mix(in srgb, var(--green) 50%, transparent); }
.step-current { color: var(--brass); border-color: var(--brass-dim); background: var(--bg-panel-2); }
.step-current .step-label { font-weight: 600; }

.check-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    font-size: .8rem;
    border: 1px solid currentColor;
}
.check-mark.ok   { color: var(--green); }
.check-mark.bad  { color: var(--blood-light); }
.check-mark.warn { color: var(--amber); }

.install-shell textarea.mono {
    font-family: var(--mono);
    font-size: .8rem;
    line-height: 1.5;
    white-space: pre;
    overflow-wrap: normal;
    overflow-x: auto;
}

.install-shell code {
    font-family: var(--mono);
    font-size: .88em;
    background: var(--bg-input);
    border: 1px solid var(--line-soft);
    padding: 1px var(--s-1);
}

.install-shell h3 { color: var(--brass); margin-top: var(--s-5); }

@media (max-width: 560px) {
    .step-label { display: none; }
    .step { padding: 6px 9px; }
}

/* ------------------------------------------------------------- Verwaltung */

.mainnav a.nav-admin {
    margin-left: var(--s-2);
    color: var(--amber);
    border-left: 1px solid var(--line-soft);
}
.mainnav a.nav-admin.active { color: var(--brass); border-bottom-color: var(--amber); }

.subnav {
    display: flex;
    gap: 2px;
    margin-bottom: var(--s-5);
    border-bottom: 1px solid var(--line-soft);
    overflow-x: auto;
}
.subnav a {
    padding: 7px 14px;
    font-size: .88rem;
    color: var(--ink-dim);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
}
.subnav a:hover { color: var(--ink); text-decoration: none; background: var(--shade); }
.subnav a.active { color: var(--brass); border-bottom-color: var(--brass); }

.config-table td { padding: 5px 10px 5px 0; vertical-align: middle; }
.config-table input { font-family: var(--mono); font-size: .85rem; padding: 5px var(--s-2); }
.config-table tr:hover { background: var(--shade-soft); }

/* Ein Link, der nicht wie einer aussieht: Meldungen ohne Ziel sind
   anklickbar, damit sie sich als gelesen vermerken lassen - aber sie
   versprechen kein Ziel. */
a.plain,
a.plain:hover {
    color: inherit;
    text-decoration: none;
    border-bottom: 0;
    cursor: default;
}

/* Aufbau einer Familie -----------------------------------------------------
   Eine Pyramide von oben nach unten: jede Stufe ein Rang, die Linie links
   haelt sie zusammen. Der Einzug macht die Nachordnung sichtbar, ohne dass
   dafuer Zahlen noetig sind. */
.hierarchy {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}

.hierarchy .tier,
.tier-loose {
    position: relative;
    padding: 0 0 14px var(--s-5);
    border-left: 1px solid var(--line);
    margin-left: 10px;
}

.hierarchy .tier:last-child { border-left-color: transparent; padding-bottom: 0; }
.tier-loose { border-left-style: dashed; margin-top: 10px; }

.tier-head {
    display: flex;
    align-items: baseline;
    gap: var(--s-2);
    flex-wrap: wrap;
    margin-bottom: var(--s-2);
}

.tier-step {
    position: absolute;
    left: -10px;
    top: 0;
    width: 19px;
    height: 19px;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: var(--bg-panel);
    color: var(--ink-faint);
    font: 600 11px/17px var(--mono);
    text-align: center;
}

.tier-top .tier-step { border-color: var(--brass-dim); color: var(--brass); }

.tier-name {
    font: 600 1rem var(--serif);
    color: var(--ink);
}

.tier-top .tier-name { color: var(--brass); }
.tier-count { margin-left: auto; }

.tier-members {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 6px;
}

.member-chip {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 7px 10px;
    background: var(--bg-panel-2);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
}

.member-chip-away { opacity: .62; }

.member-chip-name {
    display: flex;
    align-items: center;
    gap: 6px;
}

.dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--line);
    flex: 0 0 auto;
}

.dot-on { background: var(--green); }

@media (max-width: 560px) {
    .tier-count { margin-left: 0; width: 100%; }
    .tier-members { grid-template-columns: 1fr; }
}

/* Gleichrangige auf einer Ebene: jede Gruppe bekommt ihren eigenen Block,
   damit sichtbar bleibt, dass sie nebeneinander und nicht untereinander
   stehen. */
.tier-group + .tier-group {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dotted var(--line-soft);
}

.tier-group-head {
    display: flex;
    gap: var(--s-2);
    align-items: baseline;
    margin-bottom: 6px;
}

/* Ebenen in der Rangverwaltung: die Beschriftung trennt die Gruppen, damit
   Gleichrangige als Gruppe lesbar sind und nicht als Reihenfolge. */
.level-head {
    display: flex;
    gap: 10px;
    align-items: baseline;
    margin: var(--s-5) 0 var(--s-2);
}

.level-head:first-child { margin-top: 0; }

.level-mark {
    font: 600 11px/1 var(--mono);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--brass-dim);
    padding: var(--s-1) 7px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

/* Organigramm ------------------------------------------------------------
   Ein echter Baum: senkrechte Verbinder vom Elternknoten zur Reihe der
   Kinder, waagerechte zwischen Geschwistern. Reines CSS ueber Rahmen, ohne
   Zeichenflaeche - damit bleibt der Inhalt Text, kopierbar und lesbar fuer
   Vorleseprogramme. */
.chart,
.chart-children {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    gap: 14px;
}

.chart { padding: var(--s-1) 0 2px; overflow-x: auto; }

.chart-node {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-top: var(--s-5);
}

/* Der Stummel nach oben zum Elternknoten. */
.chart-node::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 1px;
    height: 18px;
    background: var(--line);
}

/* Die waagerechte Linie, die Geschwister verbindet - am ersten und
   letzten Kind jeweils nur die halbe Strecke. */
.chart-children > .chart-node::after {
    content: "";
    position: absolute;
    top: 0;
    left: -7px;
    right: -7px;
    height: 1px;
    background: var(--line);
}

.chart-children > .chart-node:first-child::after { left: 50%; }
.chart-children > .chart-node:last-child::after  { right: 50%; }
.chart-children > .chart-node:only-child::after  { display: none; }

/* Die Wurzel hat nichts, woran sie haengt. */
.chart > .chart-node { padding-top: 0; }
.chart > .chart-node::before,
.chart > .chart-node::after { display: none; }

.chart-children { padding-top: var(--s-5); position: relative; }

/* Senkrechte vom Elternkasten hinunter zur Geschwisterlinie. */
.chart-children::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 1px;
    height: 18px;
    background: var(--line);
}

.chart-box {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 136px;
    max-width: 210px;
    padding: var(--s-2) var(--s-3);
    background: var(--bg-panel-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    text-align: center;
}

.chart-box-top { border-color: var(--brass-dim); }
.chart-box-own { border-color: var(--brass); box-shadow: 0 0 0 1px var(--brass-dim) inset; }

.chart-rank {
    font: 600 .95rem var(--serif);
    color: var(--ink);
}

.chart-box-top .chart-rank { color: var(--brass); }

.chart-holders {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin-top: var(--s-1);
    padding-top: var(--s-1);
    border-top: 1px dotted var(--line-soft);
    font-size: .82rem;
}

.chart-holder {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    color: var(--ink-dim);
}

.chart-holder-away { opacity: .6; }

@media (max-width: 720px) {
    /* Auf dem Telefon kippt der Baum in eine Einrueckung - nebeneinander
       waere er nicht mehr lesbar. */
    .chart, .chart-children { flex-direction: column; align-items: stretch; gap: var(--s-1); }
    .chart-children { padding-left: var(--s-5); padding-top: var(--s-1); border-left: 1px solid var(--line); }
    .chart-children::before { display: none; }
    .chart-node { align-items: stretch; padding-top: var(--s-1); }
    .chart-node::before, .chart-children > .chart-node::after { display: none; }
    .chart-box { max-width: none; text-align: left; }
    .chart-holder { justify-content: flex-start; }
}

/* Version und Rechtehinweis stehen am Ende der Zeile, nicht im Weg. */
.footer-legal {
    margin-left: auto;
    font-size: .82rem;
}

@media (max-width: 560px) {
    .footer-legal { margin-left: 0; width: 100%; }
}

/* Eine Zeile aus Auswahlfeldern, die zusammen ein Formular bilden -
   Strecke und Ware waehlen, bevor der Konvoi zusammengestellt wird. */
.row-form {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-end;
    margin-bottom: 14px;
}

.row-form .field { margin-bottom: 0; flex: 1 1 130px; }

/* ---------------------------------------------------------- Disposition --
   Der ganze Kader auf einer Seite: je Revier eine Auswahlliste, eine
   Befehlsleiste darueber. Die bleibt beim Blaettern stehen, weil die
   Auswahl ganz unten getroffen und der Befehl ganz oben gegeben wird -
   bei dreissig Maennern liegen dazwischen zwei Bildschirme. */
.order-bar {
    position: sticky;
    top: 0;
    z-index: 20;
    border-color: var(--line);
    box-shadow: 0 6px 18px var(--shadow);
}

.order-bar-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
    align-items: flex-end;
}

.order-bar-target {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 0 1 220px;
}

.order-bar-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}

.order-bar [data-picker-summary] { margin-left: auto; }

@media (max-width: 560px) {
    .order-bar { position: static; box-shadow: none; }
    .order-bar [data-picker-summary] { margin-left: 0; }
}

/* Anhakbare Kurzwahl: ganze Trupps, ganze Reviere. */
.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-bottom: var(--s-3);
}

.pick-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px var(--s-3);
    background: var(--bg-panel-2);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    cursor: pointer;
}

.pick-chip:hover { border-color: var(--line); }
.pick-chip input { margin: 0; }
.pick-chip-empty { opacity: .5; cursor: default; }

/* Was eine Familie selbst ueber sich schreibt. Laufender Text braucht
   eine Zeilenlaenge, bei der man die naechste Zeile noch findet - eine
   Breite ueber die ganze Seite liest niemand zweimal. */
.family-text {
    max-width: 62ch;
    margin: 0 0 var(--s-4);
    line-height: 1.62;
}

.family-text:last-child { margin-bottom: 0; }

/* Besondere Merkmale einer Familie. Wie das Familienkuerzel bekommt jedes
   seine Farbe ueber eine Variable mitgegeben - eine Grafik je Merkmal
   waere eine Dateiverwaltung fuer sieben Bilder. */
/* Besondere Merkmale als gepraegte Plakette.
 
   Der ganze Glanz kommt aus EINER Farbe (--mark): color-mix mischt daraus
   Licht und Schatten. Damit sieht jedes Merkmal nach Metall aus, ohne
   eine Bilddatei je Art - und es stimmt in beiden Themen, weil sich die
   Mischpartner (weiss, schwarz) nicht aendern, die Grundfarbe aber
   dieselbe bleibt.
 
   Vorher war das eine Textplakette, nicht zu unterscheiden von jedem
   anderen Hinweis. Eine Auszeichnung, die aussieht wie ein Etikett, ist
   keine. */
.emblem {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    vertical-align: middle;
}

.emblem-disc {
    position: relative;
    flex: 0 0 auto;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: grid;
    place-items: center;

    /* Licht von links oben, Schatten nach rechts unten - eine gepraegte
       Scheibe, keine Flaeche. */
    background:
        radial-gradient(circle at 34% 26%,
            color-mix(in srgb, var(--mark, var(--brass)) 45%, #fff) 0%,
            var(--mark, var(--brass)) 48%,
            color-mix(in srgb, var(--mark, var(--brass)) 62%, #000) 100%);

    border: 1px solid color-mix(in srgb, var(--mark, var(--brass)) 55%, #000);

    box-shadow:
        inset 0 1px 1px color-mix(in srgb, var(--mark, var(--brass)) 35%, #fff),
        inset 0 -2px 3px color-mix(in srgb, var(--mark, var(--brass)) 55%, #000),
        0 1px 3px var(--shadow);
}

/* Der eingestochene Rand - eine zweite Linie innen, wie bei einer
   geschlagenen Muenze. */
.emblem-disc::after {
    content: "";
    position: absolute;
    inset: 4px;
    border-radius: 50%;
    border: 1px solid color-mix(in srgb, var(--mark, var(--brass)) 40%, #000);
    opacity: .55;
    pointer-events: none;
}

.emblem-glyph {
    position: relative;
    width: 24px;
    height: 24px;
    fill: none;
    stroke: color-mix(in srgb, var(--mark, var(--brass)) 18%, #000);
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;

    /* Ein Hauch Licht unter der Gravur, damit sie eingestochen wirkt und
       nicht aufgedruckt. */
    filter: drop-shadow(0 1px 0 color-mix(in srgb, var(--mark, var(--brass)) 55%, #fff));
}

.emblem-text { display: flex; flex-direction: column; line-height: 1.25; }

.emblem-label {
    font-family: var(--serif);
    font-size: 1rem;
    letter-spacing: .02em;
    color: var(--ink);
}

.emblem-note {
    font-size: .78rem;
    color: var(--ink-faint);
    max-width: 30ch;
}

/* Klein: nur die Scheibe, fuer Listen und Tabellen. */
.emblem-sm { gap: 0; }
.emblem-sm .emblem-disc { width: 22px; height: 22px; }
.emblem-sm .emblem-disc::after { inset: 2px; }
.emblem-sm .emblem-glyph { width: 13px; height: 13px; stroke-width: 2.1; }

.mark-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-5);
    align-items: center;
}

.mark-row-sm { gap: var(--s-1); }

/* Nur fuer Vorleseprogramme: die Scheibe allein sagt nichts. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Der Umschalter fuer hell und dunkel. Er sitzt in der Kopfzeile und im
   Fuss, damit er auch erreichbar ist, wenn niemand angemeldet ist - die
   Kopfzeile gibt es dann nicht. */
.theme-toggle {
    background: none;
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
    color: var(--ink-dim);
}

.theme-toggle:hover {
    border-color: var(--brass-dim);
    color: var(--ink);
}

.site-footer .theme-toggle { margin-left: auto; }
.site-footer .footer-legal { margin-left: 0; }

@media (max-width: 560px) {
    .site-footer .theme-toggle { margin-left: 0; }
}
