/*
 * Gemeinsame Gestaltung für App und Backend (K4).
 *
 * Ein Blatt für beide, weil sie dieselbe Anwendung sind. Die Unterschiede
 * hängen an body.bereich-app beziehungsweise .bereich-admin: die App ist für
 * den Daumen am Messestand gebaut - große Ziele, eine Spalte -, das Backend für
 * Maus und breiten Schirm.
 *
 * Die Farben kommen von campconcept.eu:
 *   #01aa74  Grün, die Hauptfarbe
 *   #00a0ab  Petrol, die zweite
 *   #a0b453  Oliv, der Akzent
 *   #0077b3  Blau, für Verweise
 *   #555     Text
 *
 * Die Schrift NICHT: die Homepage benutzt urw-din von Adobe Fonts, und deren
 * Lizenz deckt die Auslieferung ausschließlich über Adobes eigenen Host - eine
 * Kopie selbst auszuliefern wäre ein Lizenzverstoß, auch bei einer internen
 * Anwendung.
 *
 * Hier steht deshalb Barlow: eine DIN-nahe Grotesk unter der SIL Open Font
 * License, die ausdrücklich zum Selbst-Hosten freigegeben ist. Sie liegt unter
 * assets/schrift, samt Lizenztext, wie die OFL es verlangt. Damit hängt die App
 * an keinem fremden Host - in einer Messehalle ein Vorteil, nicht nur eine
 * Formsache.
 *
 * Die Ersatzkette bleibt trotzdem vollständig (K5): fällt die Schriftdatei aus,
 * trägt die Systemschrift, und die Oberfläche darf dadurch nicht springen.
 */

/* Nur die Schnitte, die das Blatt unten wirklich benutzt: 400 für Fließtext,
   600 für Beschriftungen und Überschriften, 700 für die Abschnittsnummern.
   Jeder weitere kostet eine Datei, die am Stand über Mobilfunk geladen wird.

   font-display: swap - der Text erscheint sofort in der Systemschrift und
   wechselt, sobald Barlow da ist. Die Alternative wäre eine Sekunde leere
   Fläche, und am Stand wartet niemand. */
@font-face {
    font-family: "Barlow";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/assets/schrift/barlow-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;
}

/* Latin Extended: Namen auf Visitenkarten tragen Zeichen, die der
   Grundvorrat nicht hat - tschechische, polnische, ungarische. Ohne diesen
   Block fiele genau dort die Ersatzschrift ein, mitten im Wort. */
@font-face {
    font-family: "Barlow";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/assets/schrift/barlow-400-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, 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: "Barlow";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/assets/schrift/barlow-600-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: "Barlow";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/assets/schrift/barlow-600-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, 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: "Barlow";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/assets/schrift/barlow-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: "Barlow";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/assets/schrift/barlow-700-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
        U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    --grund: #f7f7f7;
    --flaeche: #ffffff;
    --flaeche-still: #fbfbfb;
    --linie: #e7e7e7;
    --linie-stark: #d7d7d7;
    --schrift: #3e3e3e;
    --schrift-still: #767676;
    --akzent: #01aa74;
    --akzent-tief: #098e63;
    --akzent-flaeche: #e8f7f1;
    --zweit: #00a0ab;
    --zweit-tief: #09777f;
    --dritt: #a0b453;
    --verweis: #0077b3;
    --warnung: #8a5a00;
    --warnung-flaeche: #fdf4e3;
    --fehler: #a02020;
    --fehler-flaeche: #fbeaea;
    --erfolg: #07714f;
    --erfolg-flaeche: #e8f7f1;
    /* Der Verlauf der Homepage-Abschnitte: #00A0AB nach #075156. */
    --verlauf-hell: #00a0ab;
    --verlauf-dunkel: #075156;
    --radius: 8px;
    --radius-gross: 12px;
    --schatten: 0 1px 2px rgba(62, 62, 62, .06), 0 8px 24px -16px rgba(62, 62, 62, .3);
    --schrift-familie: "Barlow", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

@media (prefers-color-scheme: dark) {
    :root {
        --grund: #14181a;
        --flaeche: #1d2326;
        --flaeche-still: #232a2e;
        --linie: #2f383d;
        --linie-stark: #3d4850;
        --schrift: #e8edf0;
        --schrift-still: #9aa8ae;
        /* Das CI-Grün ist auf dunklem Grund zu satt, um lesbar zu bleiben -
           hier eine aufgehellte Fassung derselben Farbe. */
        --akzent: #2fcb97;
        --akzent-tief: #17b081;
        --akzent-flaeche: #16302a;
        --zweit: #34c3cd;
        --zweit-tief: #1aa3ad;
        --dritt: #b6c96c;
        --verweis: #4fb0e6;
        --warnung: #e0b256;
        --warnung-flaeche: #2a2314;
        --fehler: #f08a8a;
        --fehler-flaeche: #2b1717;
        --erfolg: #5fd3ab;
        --erfolg-flaeche: #16302a;
        --schatten: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px -16px rgba(0, 0, 0, .8);
        /* Derselbe Verlauf, nur so weit abgedunkelt, dass weiße Schrift
           darauf nicht blendet - am Abend auf dem Messestand ist ein helles
           Petrol über die ganze Fläche zu viel. */
        --verlauf-hell: #0a3a3e;
        --verlauf-dunkel: #062023;
    }
}

* { box-sizing: border-box; }

/* Das hidden-Attribut muss stärker sein als jede eigene display-Angabe. Der
   Browser setzt [hidden] { display: none } nur in seinem Grundblatt, und das
   verliert gegen jede Regel von hier: .knopf ist inline-flex, .kacheln ist
   grid - ohne das stünden verborgene Teile sichtbar da. */
[hidden] { display: none !important; }

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

/* Der Hintergrund der Homepage: ein Verlauf von Petrol nach Dunkelpetrol, mit
   der hauseigenen Textur darüber. Dort trägt er die Abschnitte, die sich vom
   Weiß abheben sollen.
'
   Hier liegt er hinter der ganzen Seite, und die Blöcke stehen weiß darauf -
   das ergibt dieselbe Anmutung und bleibt lesbar. Ein Formular direkt auf dem
   Verlauf wäre am Stand im Streiflicht nicht zu entziffern.

   `fixed`, damit die Textur beim Scrollen steht und nicht mitwandert - so hält
   es die Homepage auch. */
body {
    margin: 0;
    background: linear-gradient(160deg, var(--verlauf-hell) 0%, var(--verlauf-dunkel) 100%);
    background-attachment: fixed;
    color: var(--schrift);
    font-family: var(--schrift-familie);
    font-size: 16px;
    line-height: 1.5;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
}

/* Die Textur als eigene Ebene: als zweites background-image ließe sie sich
   nicht getrennt abdunkeln, und auf der Homepage liegt sie ebenfalls als
   eigene Schicht mit drei Prozent Deckkraft darüber. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background: url("/assets/textur.svg") repeat center;
    background-size: cover;
    opacity: .05;
    pointer-events: none;
}

/* Das Backend bleibt schlicht: dort wird gelesen und geprüft, oft stundenlang,
   und ein Farbverlauf unter einer Tabelle ermüdet. */
body.bereich-admin {
    background: var(--grund);
}

body.bereich-admin::before { display: none; }

h1, h2, h3 { margin: 0 0 .5rem; line-height: 1.25; text-wrap: balance; font-weight: 600; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.1rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75rem; }
a { color: var(--verweis); }
code, pre { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: .85em; }

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

/* Die Kopfleiste folgt der Homepage: weiße Fläche über dem farbigen Grund,
   unten abgerundet, das Logo links, die Navigation in Großbuchstaben.

   Dort ist sie fest am oberen Rand; hier klebt sie beim Scrollen (sticky) -
   dasselbe Verhalten, aber ohne dass der Inhalt darunter rutscht. */
.kopfleiste {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    row-gap: .4rem;
    padding: .6rem 1rem;
    /* K6: unter der Statusleiste des Geräts beginnt der Inhalt, nicht darin. */
    padding-top: max(.6rem, env(safe-area-inset-top));
    background: var(--flaeche);
    border-bottom-left-radius: .4rem;
    border-bottom-right-radius: .4rem;
    box-shadow: 0 2px 12px rgba(0, 0, 0, .12);
    position: sticky;
    top: 0;
    z-index: 10;
}

.marke {
    display: flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    color: inherit;
    min-width: 0;
}

/* Das Logo kommt als Bild, nicht als eingebettetes SVG: so liegt es einmal im
   Zwischenspeicher statt auf jeder Seite im Quelltext. */
.marke-logo {
    display: block;
    height: 1.15rem;
    width: auto;
}

/* Im dunklen Modus ist das Logo auf weißem Grund - die Leiste bleibt hell, wie
   auf der Homepage. Nur die Schrift daneben wechselt. */
.marke-zusatz {
    font-size: .72rem;
    color: var(--schrift-still);
    text-transform: uppercase;
    letter-spacing: .06em;
    white-space: nowrap;
}

@media (prefers-color-scheme: dark) {
    .kopfleiste { background: #f7f7f7; }
    .kopfleiste .marke-zusatz,
    .kopfleiste .kopf-messe { color: #666; }
    .kopfleiste .kopf-messe-name { color: #2a2a2a; }
}

/* Die Navigation der App: dieselbe Anmutung wie auf der Homepage -
   Großbuchstaben, zurückgenommenes Grau, ein Strich unter dem aktiven
   Eintrag. */
.appnav {
    display: flex;
    gap: .25rem;
    flex-wrap: wrap;
}

.appnav a {
    position: relative;
    padding: .45rem .55rem;
    font-size: .78rem;
    font-weight: 500;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-decoration: none;
    color: #666;
    border-radius: 6px;
}

.appnav a::after {
    content: "";
    position: absolute;
    left: .55rem;
    right: .55rem;
    bottom: .2rem;
    height: 2px;
    background: var(--akzent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .25s ease;
}

.appnav a.ist-aktiv { color: #2a2a2a; }
.appnav a.ist-aktiv::after { transform: scaleX(1); }

/* Die laufende Messe, mittig zwischen Marke und Menü. Sie ist der
   Zusammenhang, in dem alles auf der Seite zu lesen ist (B8) - und sie darf
   schrumpfen, damit ein langer Messename das Menü nicht vom Rand schiebt. */
.kopf-messe {
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
    font-size: .85rem;
    color: var(--schrift-still);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kopf-messe-name { font-weight: 600; color: var(--schrift); }

.kopf-rechts { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

/* --- Das Erfassermenü (A1) ----------------------------------------------- */

/* Im Ruhezustand stehen hier die Initialen. Ein <details> statt eines Skripts:
   aufklappen, zuklappen und die Bedienung mit der Tastatur kann der Browser
   selbst - und ohne Skript bleibt es benutzbar. */
.erfassermenue { position: relative; }

.erfasser-knopf {
    display: flex;
    align-items: center;
    justify-content: center;
    /* 44 Punkt, das Mindestmaß für einen Finger (K3). */
    min-width: 2.75rem;
    height: 2.75rem;
    padding: 0 .5rem;
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: #fff;
    background: var(--akzent);
    border: 1px solid var(--akzent-tief);
    border-radius: var(--radius);
    cursor: pointer;
    list-style: none;
}

/* Ein <summary> bringt von sich aus ein Dreieck mit. Es verschwindet nur, wenn
   alle drei Wege zu sind: die Listenmarkierung, ::marker und das eigene von
   WebKit. */
.erfasser-knopf::-webkit-details-marker { display: none; }
.erfasser-knopf::marker { content: ""; }

/* Niemand gewählt: die Farbe nimmt sich zurück und der Platzhalter sagt, dass
   hier eine Entscheidung fehlt. */
.erfasser-knopf.ist-leer {
    color: var(--warnung);
    background: var(--warnung-flaeche);
    border-color: var(--warnung);
}

.menue-liste {
    position: absolute;
    right: 0;
    top: calc(100% + .4rem);
    min-width: 14rem;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--flaeche);
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    box-shadow: var(--schatten);
    z-index: 20;
    padding: .3rem;
}

.menue-eintrag {
    display: block;
    width: 100%;
    text-align: left;
    padding: .7rem .75rem;
    font: inherit;
    color: inherit;
    text-decoration: none;
    background: none;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
}

.menue-eintrag:hover, .menue-eintrag:focus-visible { background: var(--flaeche-still); }
.menue-eintrag.ist-aktiv { background: var(--akzent-flaeche); color: var(--akzent-tief); font-weight: 600; }
.menue-strich { border: 0; border-top: 1px solid var(--linie); margin: .3rem 0; }
.menue-kopf { padding: .4rem .75rem; font-size: .75rem; color: var(--schrift-still); text-transform: uppercase; letter-spacing: .04em; }

/* --- Der Fortschritt der Übertragung (F7) -------------------------------- */

/* Ein Ring neben den Initialen: in der Mitte steht, wie viele Kontakte noch
   warten, und der Ring schließt sich mit dem Anteil, der schon übertragen ist.
   Steht hier etwas, ist noch nichts verloren, aber auch nichts fertig - wer
   das iPad weglegt, soll das sehen, ohne es zu suchen.

   Warum ein Ring und keine Zahl allein: die Zahl zählt herunter, aber bei
   zwanzig wartenden Kontakten sagt "19" nichts darüber, ob es vorangeht. Der
   geschlossene Anteil tut es. */
.fortschritt {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    flex: 0 0 auto;
}

.fortschritt.ist-leer { display: none; }

.fortschritt-ring {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* Der Kreis beginnt oben, nicht rechts. */
    transform: rotate(-90deg);
}

.fortschritt-bahn {
    fill: none;
    stroke: var(--linie-stark);
    stroke-width: 3;
}

.fortschritt-strich {
    fill: none;
    stroke: var(--akzent);
    stroke-width: 3;
    stroke-linecap: round;
    transition: stroke-dashoffset .4s ease;
}

.fortschritt-zahl {
    position: relative;
    font-size: .85rem;
    font-weight: 700;
    color: var(--akzent-tief);
    line-height: 1;
}

/* Während übertragen wird, dreht sich ein kurzer Bogen über dem Ring. Ohne
   ihn sähe eine stehende Warteschlange genauso aus wie eine, die gerade
   abgearbeitet wird. */
.fortschritt-spinner {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
}

.fortschritt.laeuft .fortschritt-spinner {
    opacity: 1;
    animation: kreisel 1.1s linear infinite;
}

.fortschritt-spinner circle {
    fill: none;
    stroke: var(--zweit);
    stroke-width: 3;
    stroke-linecap: round;
    /* Ein Viertel des Umfangs: 2·π·20 ≈ 125,6. */
    stroke-dasharray: 31 95;
}

@keyframes kreisel {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .fortschritt.laeuft .fortschritt-spinner { animation: none; }
}

@media (prefers-color-scheme: dark) {
    .kopfleiste .fortschritt-zahl { color: #07714f; }
    .kopfleiste .fortschritt-bahn { stroke: #d7d7d7; }
}

/* --- Die Sperre während des Ablegens ------------------------------------- */

/* Normalerweise sieht das niemand: der Kontakt liegt in Millisekunden im
   Gerät, und die Übertragung läuft danach im Hintergrund weiter. Hängt aber
   etwas, erscheint nach einem kurzen Moment diese Fläche - dann ist klar, dass
   die App arbeitet und nicht, dass der Tipp nicht angekommen ist.

   Die Verzögerung steckt im Skript, nicht hier: eine Fläche, die bei jedem
   Speichern kurz aufblitzt, wirkt wie ein Fehler. */
.sperre {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    background: rgba(255, 255, 255, .82);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

@media (prefers-color-scheme: dark) {
    .sperre { background: rgba(10, 16, 18, .82); }
}

.sperre-kreisel {
    width: 3rem;
    height: 3rem;
    border: 3px solid var(--linie-stark);
    border-top-color: var(--akzent);
    border-radius: 50%;
    animation: kreisel .9s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .sperre-kreisel { animation-duration: 3s; }
}

.sperre-text { font-size: .95rem; color: var(--schrift-still); text-align: center; padding: 0 1.5rem; }

/* --- Inhalt --------------------------------------------------------------- */

.inhalt {
    padding: 1rem;
    /* K6: Platz für die Home-Leiste, plus Luft für die feste Fußleiste. */
    padding-bottom: calc(1rem + env(safe-area-inset-bottom));
}

.bereich-app .inhalt {
    /* Eine Spalte. Auf dem iPad mini sind 744 Punkt die Breite im Hochformat -
       720 passt dort ohne Rand, und im Querformat steht der Bogen mittig
       statt über die ganze Breite gezogen. */
    max-width: 720px;
    margin: 0 auto;
    padding-bottom: 6rem;
}

.bereich-admin .inhalt { max-width: 1280px; margin: 0 auto; }

.seite-schlicht .inhalt { max-width: none; padding: 0; }

/* --- Abschnitte und Karten ----------------------------------------------- */

.block {
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--radius-gross);
    padding: 1rem;
    margin-bottom: 1rem;
    box-shadow: var(--schatten);
}

.block-kopf {
    display: flex;
    align-items: baseline;
    gap: .6rem;
    flex-wrap: wrap;
    margin-bottom: .75rem;
}

.block-kopf h2 { margin: 0; }

/* Die Nummer des Abschnitts im Erfassungsbogen. Drei Abschnitte, und in
   welcher Reihenfolge sie gemeint sind, soll man sehen, ohne es zu lesen. */
.block-zahl {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    flex: 0 0 auto;
    font-size: .8rem;
    font-weight: 700;
    color: #fff;
    background: var(--zweit);
    border-radius: 50%;
}

.block-still { color: var(--schrift-still); font-size: .85rem; }

/* --- Felder --------------------------------------------------------------- */

.felder { display: grid; gap: .75rem; }

/* Zwei Spalten, wo es sich lohnt: PLZ und Ort, Telefon und Mobil. Auf dem
   iPad mini im Hochformat ist das noch bequem zu treffen; darunter bricht es
   auf eine Spalte um. */
.felder-paar { display: grid; gap: .75rem; grid-template-columns: 1fr; }

@media (min-width: 560px) {
    .felder-paar { grid-template-columns: 1fr 1fr; }
    .felder-paar.paar-schmal { grid-template-columns: 8rem 1fr; }
}

.feld { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }

.feld-beschriftung {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .8rem;
    font-weight: 600;
    color: var(--schrift-still);
}

.feld-pflicht { color: var(--fehler); }

input[type="text"], input[type="tel"], input[type="email"], input[type="url"],
input[type="date"], input[type="password"], input[type="search"], input[type="number"],
select, textarea {
    width: 100%;
    /* 16 Punkt und nicht kleiner: Safari auf iOS zoomt in jedes Feld hinein,
       dessen Schrift darunter liegt - und kommt danach nicht von selbst
       zurück. Die halbe Oberfläche stand dann verschoben da. */
    font-size: 1rem;
    font-family: inherit;
    color: var(--schrift);
    background: var(--flaeche);
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    /* 44 Punkt Höhe (K3). */
    min-height: 2.75rem;
    padding: .55rem .7rem;
}

textarea { min-height: 6rem; resize: vertical; line-height: 1.45; }

input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, summary:focus-visible, a:focus-visible, label:focus-visible {
    outline: 2px solid var(--zweit);
    outline-offset: 1px;
}

input[readonly], input:disabled, select:disabled, textarea:disabled {
    background: var(--flaeche-still);
    color: var(--schrift-still);
}

.feld-fehler { font-size: .8rem; color: var(--fehler); }
.feld-hinweis { font-size: .8rem; color: var(--schrift-still); }

.feld.hat-fehler input, .feld.hat-fehler select, .feld.hat-fehler textarea {
    border-color: var(--fehler);
}

/* --- Herkunft je Feld (D4) ----------------------------------------------- */

/* Ein Zeichen neben der Beschriftung, kein Wort: fünfzehnmal "von der
   Visitenkarte gelesen" verdoppelte den Bogen. Der volle Text hängt am
   title und am Vorlesetext. */
.herkunft {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    font-size: .75rem;
    font-weight: 400;
    padding: .05rem .35rem;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
}

.herkunft-karte { color: var(--zweit-tief); background: #e6f6f7; border-color: #bfe6e9; }
.herkunft-recherche { color: var(--warnung); background: var(--warnung-flaeche); border-color: #e6d3a8; }
.herkunft-crm { color: var(--verweis); background: #e6f2fa; border-color: #c2dff0; }
.herkunft-eingabe { display: none; }

@media (prefers-color-scheme: dark) {
    .herkunft-karte { background: #14312f; border-color: #255c5c; }
    .herkunft-crm { background: #152836; border-color: #2a4d66; }
}

/* Das Vertrauen, wenn es niedrig ist. Bei hohen Werten steht nichts - eine
   Zahl an jedem Feld wäre Rauschen; gebraucht wird der Hinweis, wo genauer
   hinzusehen ist (C5). */
.vertrauen-niedrig { color: var(--fehler); font-weight: 600; }

/* --- Themenkacheln (B4) --------------------------------------------------- */

.themengruppe { margin-bottom: 1rem; }
.themengruppe:last-child { margin-bottom: 0; }

.themengruppe-name {
    font-size: .8rem;
    font-weight: 600;
    color: var(--schrift-still);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-bottom: .5rem;
}

.kacheln {
    display: grid;
    gap: .5rem;
    /* Mindestens 10rem je Kachel: so stehen auf dem iPad drei in einer Reihe,
       auf dem mini im Hochformat zwei - und ein langer Themenname bricht
       innerhalb der Kachel um, statt sie zu sprengen. */
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}

/* Das Kästchen bleibt für Vorlesegeräte und Tastatur erhalten und wird nur
   unsichtbar gemacht - display: none nähme es aus der Bedienreihenfolge. */
.kachel { position: relative; }

.kachel input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
}

.kachel-flaeche {
    display: flex;
    align-items: center;
    min-height: 3.25rem;
    height: 100%;
    padding: .6rem .75rem;
    font-size: .92rem;
    line-height: 1.3;
    color: var(--schrift);
    background: var(--flaeche);
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    cursor: pointer;
    /* Ein Tipp daneben soll nicht den Text markieren - am Stand wird schnell
       getippt, und eine blaue Markierung sieht nach Fehler aus. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.kachel input:checked + .kachel-flaeche {
    color: var(--akzent-tief);
    background: var(--akzent-flaeche);
    border-color: var(--akzent);
    /* Der Rahmen allein reicht nicht: auf dem iPad in der Halle sieht man ihn
       gegen das Streiflicht kaum. */
    box-shadow: inset 0 0 0 1px var(--akzent);
    font-weight: 600;
}

.kachel input:focus-visible + .kachel-flaeche {
    outline: 2px solid var(--zweit);
    outline-offset: 1px;
}

/* --- Abschnitte zum Auf- und Zuklappen (B1) ------------------------------ */

/* Der Bogen ist länger als der Schirm. Alles gleichzeitig offen heißt scrollen
   und suchen; eingeklappt heißt: man sieht, woran man ist und was noch kommt.

   Abschnitt 1 ist offen, die folgenden sind zu und gesperrt, bis die
   Kontaktdaten stehen - vorher gibt es nichts zu wählen, wofür ein Kontakt
   nötig wäre. Sobald der Nachname da ist, öffnen sie sich. */
.abschnitt { padding: 0; overflow: hidden; }

.abschnitt-kopf {
    display: flex;
    align-items: center;
    gap: .6rem;
    width: 100%;
    /* 44 Punkt, auch hier - der Kopf ist eine Bedienfläche. */
    min-height: 3.25rem;
    padding: .75rem 1rem;
    font: inherit;
    text-align: left;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

.abschnitt-kopf h2 { margin: 0; flex: 0 1 auto; }

.abschnitt-stand {
    flex: 1 1 auto;
    min-width: 0;
    font-size: .82rem;
    color: var(--schrift-still);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.abschnitt-pfeil {
    flex: 0 0 auto;
    font-size: .9rem;
    color: var(--schrift-still);
    transition: transform .2s ease;
}

.abschnitt[data-offen] .abschnitt-pfeil { transform: rotate(180deg); }

.abschnitt-inhalt { padding: 0 1rem 1rem; }
.abschnitt:not([data-offen]) .abschnitt-inhalt { display: none; }

/* Gesperrt heißt: noch nicht dran. Zurückgenommen statt unsichtbar - so ist zu
   sehen, was noch kommt. */
.abschnitt[data-gesperrt] { opacity: .5; }
.abschnitt[data-gesperrt] .abschnitt-kopf { cursor: default; }
.abschnitt[data-gesperrt] .block-zahl { background: var(--linie-stark); }

/* Ein Abschnitt, in dem schon etwas gewählt ist, trägt einen Haken - beim
   Durchsehen vor dem Speichern zählt das. */
.abschnitt-haken { color: var(--erfolg); font-weight: 700; }

/* --- Der Einstieg: zwei Wege (B1) ---------------------------------------- */

/* Statt Kamera und fünfzehn Felder gleichzeitig: zwei große Flächen, und erst
   die Wahl öffnet den passenden Weg. Das hält den Bogen aufgeräumt - am Stand
   sieht man zuerst, was zu tun ist, nicht alles, was möglich wäre. */
.einstieg {
    display: grid;
    gap: .75rem;
    grid-template-columns: 1fr;
}

@media (min-width: 520px) {
    .einstieg { grid-template-columns: 1fr 1fr; }
}

.einstieg-knopf {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    /* Groß genug, dass man im Stehen nicht zielen muss. */
    min-height: 9rem;
    padding: 1.5rem 1rem;
    font: inherit;
    text-align: center;
    color: var(--schrift);
    background: var(--flaeche);
    border: 2px solid var(--linie-stark);
    border-radius: var(--radius-gross);
    cursor: pointer;
}

.einstieg-knopf:hover,
.einstieg-knopf:focus-visible {
    border-color: var(--akzent);
    background: var(--akzent-flaeche);
}

.einstieg-haupt {
    border-color: var(--akzent);
    background: var(--akzent-flaeche);
}

.einstieg-zeichen { font-size: 2.2rem; line-height: 1; }
.einstieg-name { font-size: 1.05rem; font-weight: 600; }
.einstieg-still { font-size: .82rem; color: var(--schrift-still); line-height: 1.35; }

/* --- Die Erfasserabfrage beim Start (A1) --------------------------------- */

/* Wer erfasst, steht am Anfang fest - sonst hängt der erste Kontakt des Tages
   an niemandem, und das fällt erst in der Nachbearbeitung auf. Deshalb eine
   eigene Seite statt eines Hinweises, den man wegtippen kann. */
.erfasserwahl {
    max-width: 30rem;
    margin: 2rem auto;
}

.erfasserwahl .kacheln {
    grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
}

.erfasser-kachel {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    width: 100%;
    min-height: 6rem;
    padding: 1rem .5rem;
    font: inherit;
    color: var(--schrift);
    background: var(--flaeche);
    border: 2px solid var(--linie-stark);
    border-radius: var(--radius-gross);
    cursor: pointer;
}

.erfasser-kachel:hover,
.erfasser-kachel:focus-visible {
    border-color: var(--akzent);
    background: var(--akzent-flaeche);
}

.erfasser-kuerzel {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--akzent-tief);
}

.erfasser-name { font-size: .85rem; color: var(--schrift-still); line-height: 1.25; }

/* --- Kleine Wahlreihe (Anrede) ------------------------------------------- */

/* Vier Möglichkeiten tippt man nicht, man tippt sie an. Kleiner als die
   Themenkacheln, weil es nur ein Feld unter vielen ist - aber immer noch
   groß genug für einen Daumen. */
.wahlreihe { display: flex; flex-wrap: wrap; gap: .4rem; }

.wahl { position: relative; }

.wahl input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
}

.wahl-flaeche {
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    padding: .4rem .9rem;
    font-size: .92rem;
    color: var(--schrift);
    background: var(--flaeche);
    border: 1px solid var(--linie-stark);
    border-radius: 999px;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.wahl input:checked + .wahl-flaeche {
    color: var(--akzent-tief);
    background: var(--akzent-flaeche);
    border-color: var(--akzent);
    box-shadow: inset 0 0 0 1px var(--akzent);
    font-weight: 600;
}

.wahl input:focus-visible + .wahl-flaeche {
    outline: 2px solid var(--zweit);
    outline-offset: 1px;
}

/* Das Feld für "Sonstige". Ohne Skript steht es immer da - der Bogen bleibt
   abschickbar; mit Skript erscheint es erst bei der Wahl. */
.anrede-frei { margin-top: .4rem; }

/* --- Freie Eingabe an einer Kachel --------------------------------------- */

/* "andere" bei der Verwaltungssoftware: die Kachel allein sagt nur, dass es ein
   anderes System ist - das Feld daneben sagt, welches. Es erscheint erst, wenn
   die Kachel gewählt ist. */
.kachel-freitext {
    grid-column: 1 / -1;
    margin-top: -.2rem;
}

.kachel-freitext input {
    font-size: .95rem;
    min-height: 2.5rem;
}

/* --- Knöpfe --------------------------------------------------------------- */

.knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    min-height: 2.75rem;
    padding: .6rem 1.1rem;
    font: inherit;
    font-weight: 600;
    color: var(--schrift);
    background: var(--flaeche);
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    text-decoration: none;
    cursor: pointer;
}

.knopf:disabled, .knopf[aria-disabled="true"] { opacity: .55; cursor: default; }

.knopf-haupt { color: #fff; background: var(--akzent); border-color: var(--akzent-tief); }
.knopf-zweit { color: #fff; background: var(--zweit); border-color: var(--zweit-tief); }
.knopf-still { color: var(--schrift-still); }
.knopf-gefahr { color: var(--fehler); border-color: var(--fehler); background: var(--fehler-flaeche); }
.knopf-klein { min-height: 2.25rem; padding: .35rem .7rem; font-size: .85rem; }
.knopf-breit { width: 100%; }

.knopfreihe { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }

/* --- Die Fußleiste der Erfassung ----------------------------------------- */

/* Der Speicherknopf bleibt unten stehen, auch beim Scrollen: der Bogen ist
   länger als der Schirm, und sich zum Speichern erst nach unten zu arbeiten
   wäre am Stand ein Ärgernis. */
.fussleiste {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 15;
    display: flex;
    gap: .75rem;
    align-items: center;
    padding: .75rem 1rem;
    padding-bottom: max(.75rem, env(safe-area-inset-bottom));
    background: var(--flaeche);
    border-top: 1px solid var(--linie);
    box-shadow: 0 -8px 24px -20px rgba(0, 0, 0, .5);
}

.fussleiste-inhalt {
    display: flex;
    gap: .75rem;
    align-items: center;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
}

.fussleiste .knopf-haupt { flex: 1 1 auto; }

/* --- Kartenaufnahme (C1) -------------------------------------------------- */

.karten { display: grid; gap: .75rem; grid-template-columns: 1fr 1fr; }

.kartenfeld {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    align-items: stretch;
}

.kartenfeld-name { font-size: .8rem; font-weight: 600; color: var(--schrift-still); }

.kartenflaeche {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Das Seitenverhältnis einer Visitenkarte, 85 zu 55. Die Fläche sieht
       damit aus wie das, was hineingehört - und springt nicht, wenn das Bild
       ankommt. */
    aspect-ratio: 85 / 55;
    overflow: hidden;
    color: var(--schrift-still);
    background: var(--flaeche-still);
    border: 1px dashed var(--linie-stark);
    border-radius: var(--radius);
    cursor: pointer;
    text-align: center;
    font-size: .85rem;
    padding: .5rem;
}

.kartenflaeche img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kartenflaeche.hat-bild { border-style: solid; padding: 0; }

/* Das Dateifeld selbst bleibt unsichtbar, aber bedienbar: die Fläche darüber
   ist sein Etikett. */
.kartenfeld input[type="file"] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.kartenfeld input[type="file"]:focus-visible + .kartenflaeche {
    outline: 2px solid var(--zweit);
    outline-offset: 2px;
}

/* --- Meldungen ------------------------------------------------------------ */

.meldung {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    padding: .7rem .9rem;
    margin-bottom: 1rem;
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    background: var(--flaeche);
    font-size: .92rem;
}

.meldung-erfolg { color: var(--erfolg); background: var(--erfolg-flaeche); border-color: var(--erfolg); }
.meldung-warnung { color: var(--warnung); background: var(--warnung-flaeche); border-color: var(--warnung); }
.meldung-fehler { color: var(--fehler); background: var(--fehler-flaeche); border-color: var(--fehler); }
.meldung p:last-child { margin: 0; }

/* --- Plaketten ------------------------------------------------------------ */

.plakette {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .1rem .5rem;
    font-size: .78rem;
    font-weight: 600;
    border-radius: 999px;
    border: 1px solid var(--linie-stark);
    background: var(--flaeche-still);
    color: var(--schrift-still);
    white-space: nowrap;
}

.plakette-neu { color: var(--verweis); background: #e6f2fa; border-color: #c2dff0; }
.plakette-geprueft { color: var(--zweit-tief); background: #e6f6f7; border-color: #bfe6e9; }
.plakette-freigegeben { color: var(--erfolg); background: var(--erfolg-flaeche); border-color: var(--erfolg); }
.plakette-verworfen { color: var(--schrift-still); text-decoration: line-through; }

@media (prefers-color-scheme: dark) {
    .plakette-neu { background: #152836; border-color: #2a4d66; }
    .plakette-geprueft { background: #14312f; border-color: #255c5c; }
}

/* --- Listen (Backend) ---------------------------------------------------- */

.tabellenrahmen {
    /* Eine breite Tabelle scrollt in ihrem Rahmen, nicht die Seite. */
    overflow-x: auto;
    border: 1px solid var(--linie);
    border-radius: var(--radius);
    background: var(--flaeche);
}

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

table.liste th, table.liste td {
    text-align: left;
    padding: .6rem .75rem;
    border-bottom: 1px solid var(--linie);
    vertical-align: top;
}

table.liste th {
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--schrift-still);
    background: var(--flaeche-still);
    position: sticky;
    top: 0;
}

table.liste tr:last-child td { border-bottom: 0; }
table.liste tbody tr:hover { background: var(--flaeche-still); }
table.liste .spalte-eng { white-space: nowrap; width: 1%; }
table.liste .spalte-rechts { text-align: right; }

/* --- Navigation im Backend ----------------------------------------------- */

.hauptnavigation { display: flex; flex-wrap: wrap; gap: .25rem; }

.nav-eintrag {
    padding: .45rem .7rem;
    font-size: .9rem;
    color: var(--schrift-still);
    text-decoration: none;
    border-radius: 6px;
}

.nav-eintrag:hover { background: var(--flaeche-still); color: var(--schrift); }
.nav-aktiv { color: var(--akzent-tief); background: var(--akzent-flaeche); font-weight: 600; }

/* --- Anmeldung ------------------------------------------------------------ */

.anmeldung { max-width: 24rem; margin: 3rem auto; }
.anmeldung .block { padding: 1.5rem; }

.anmeldung-marke {
    text-align: center;
    margin-bottom: 1.25rem;
}

.anmeldung-marke-name { font-size: 1.3rem; font-weight: 600; }
.anmeldung-marke-zusatz { font-size: .85rem; color: var(--schrift-still); }

/* --- Kleinteile ----------------------------------------------------------- */

.still { color: var(--schrift-still); }
.klein { font-size: .85rem; }
.rechts { text-align: right; }
.mitte { text-align: center; }
.nowrap { white-space: nowrap; }
.abstand-oben { margin-top: 1rem; }
.leerhinweis { padding: 2rem 1rem; text-align: center; color: var(--schrift-still); }

.zahlenreihe { display: flex; flex-wrap: wrap; gap: .5rem; }

.zahl {
    flex: 1 1 7rem;
    padding: .7rem .9rem;
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--radius);
}

.zahl-wert { font-size: 1.5rem; font-weight: 600; line-height: 1.1; }
.zahl-name { font-size: .78rem; color: var(--schrift-still); text-transform: uppercase; letter-spacing: .04em; }

/* Die Vorschau der Übertragung (H2). Monospace, weil es JSON ist und die
   Einrückung die Struktur trägt. */
.vorschau {
    margin: 0;
    padding: .75rem;
    overflow-x: auto;
    background: var(--flaeche-still);
    border: 1px solid var(--linie);
    border-radius: var(--radius);
    font-size: .8rem;
    line-height: 1.45;
    white-space: pre;
}

.vorschau-schritt { margin-bottom: .75rem; }
.vorschau-kopf { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; margin-bottom: .3rem; }
.vorschau-methode { font-weight: 700; color: var(--akzent-tief); }
.vorschau-pfad { font-family: ui-monospace, Consolas, monospace; font-size: .85rem; }

/* Reduzierte Bewegung: hier wird ohnehin nicht animiert, aber ein
   Übergangseffekt am Knopf soll sich abschalten lassen. */
@media (prefers-reduced-motion: no-preference) {
    .knopf, .kachel-flaeche, .menue-eintrag { transition: background-color .12s ease, border-color .12s ease; }
}
