/* ============================================================
   Mittelfranken Informatik — Eichschein-Archiv
   DESIGNSYSTEM. Die EINZIGE Datei mit festen Farben, Abständen und
   Schriftgrößen.

   Wer anderswo `#004E7C`, `12px` oder `1.25rem` hinschreibt, wird von
   `test-design.js` gestellt. Das ist keine Formsache: ein zweiter Ort
   für dieselbe Farbe ist ein Ort, der beim Ändern stehen bleibt — und
   bei einer Hausfarbe fällt das erst auf, wenn ein Kunde es sieht.

   Alle Kontraste sind GERECHNET, nicht geschätzt (WCAG 2.1, Verhältnis
   der relativen Leuchtdichten). Die Zahl steht jeweils daneben. Die
   Vorgabe lautet 4,5:1 — für Text, in beiden Erscheinungsbildern.
   `test-design.js` rechnet sie bei jedem Lauf neu nach.
   ============================================================ */

:root {
  /* ==========================================================
     MARKE
     ========================================================== */

  /* ---- Primär: RAL 5010 Enzianblau ----
     Die Hausfarbe von FH-Eichservice, wie im Auftrag festgelegt.
     Das Logo selbst trägt gemessen #005282 — ein Unterschied, den
     man nebeneinander kaum sieht (ΔE ≈ 2). Maßgeblich ist die
     Hausfarbe, nicht die PNG-Kompression eines Logos. */
  --mfi-primaer:         #004E7C;   /* 8.82:1 auf der Fläche, 8.14:1 auf dem Grund */
  --mfi-primaer-dunkel:  #003A5C;   /* 11.93:1 — Hover, gedrückte Zustände */
  --mfi-primaer-hell:    #E6EFF5;   /* Fläche, hinterlegte Bereiche */
  --mfi-primaer-rand:    #B8D0E0;   /* Rand auf hinterlegter Fläche */

  /* ---- Akzent: das Rot aus dem Logo ----
     NUR im Kopfbereich neben dem Logo. Sonst nirgends.

     Der Auftrag nennt "etwa #B0121A"; aus der Logodatei gemessen sind
     es #C10731. Da der Akzent unmittelbar NEBEN dem Logo steht, wäre
     eine Abweichung genau dort sichtbar, wo sie am meisten stört —
     deshalb gilt der gemessene Wert. Wer den geschätzten will, ändert
     diese eine Zeile.

     Warum die Beschränkung auf den Kopf: wird dieses Rot dekorativ
     gestreut, ist es nach der dritten Fläche kein Signal mehr. Dann
     liest niemand mehr das Rot eines abgelaufenen Scheins als Warnung,
     sondern als Hausfarbe. Die Trennung ist der eigentliche Inhalt
     dieses Abschnitts. */
  --mfi-akzent:          #C10731;   /* 6.28:1 auf der Fläche, 5.80:1 auf dem Grund */

  /* ---- Aktionsfarbe (Phase 9) ----
     Der Entwurf hat einen Befund geliefert, der beim Bauen nicht
     auffällt: Blau ist in dieser Anwendung gleichzeitig Navigation,
     Primäraktion, Rahmen für Sekundärknöpfe, Fokusring und Infofläche.
     Wenn alles blau ist, heißt Blau nichts mehr.

     Deshalb ein eigener NAME für die Aktion — auch wenn der Wert heute
     derselbe ist. Der Name trennt die Aufgaben: Navigation und Verweise
     nehmen `--mfi-primaer`, der eine gefüllte Knopf je Ansicht nimmt
     `--mfi-aktion`. Kein zweiter Ort für dieselbe Farbe, sondern ein
     Verweis: wer die Aktionsfarbe je ändern will, ändert genau hier und
     nirgends sonst. */
  --mfi-aktion:          var(--mfi-primaer);
  --mfi-aktion-text:     var(--mfi-weiss);

  /* ==========================================================
     NEUTRALTÖNE
     Kein reines Schwarz: #000 auf #FFF ist ein härterer Kontrast als
     jedes Druckerzeugnis und ermüdet beim langen Lesen.
     ========================================================== */
  --mfi-weiss:           #FFFFFF;

  /* ---- Grund und Fläche sind seit Phase 9 vertauscht ----
     Vorher: weißer Seitengrund, graue Karten. Karten sanken damit in
     die Seite ein, statt auf ihr zu liegen — und eine Tabelle ohne
     eigene Fläche steht frei im Nichts (so sah die Warteschlange aus).

     Im DUNKELMODUS war es von Anfang an andersherum: `--mfi-grund`
     (#14181B) ist dort dunkler als `--mfi-flaeche` (#1E2428), Flächen
     heben sich also ab. Die beiden Erscheinungsbilder folgten
     gegensätzlichen Regeln, und nur das helle war falsch herum.

     Die Werte selbst sind dieselben wie vorher, nur an der anderen
     Stelle. Alle Kontraste sind neu gerechnet; der schlechteste Wert
     im hellen Satz liegt bei 5.19:1 (`--ampel-bald` auf dem Grund),
     die Vorgabe bei 4,5. `test-design.js` rechnet es bei jedem Lauf
     nach. */
  --mfi-grund:           #F4F6F8;   /* Seitenhintergrund */
  --mfi-flaeche:         #FFFFFF;   /* Karten, Tabellen, Kopfleiste */
  --mfi-flaeche-tief:    #E9EDF1;   /* eine Stufe tiefer, z. B. Bildrahmen */
  --mfi-linie:           #D5DBE0;   /* Trennlinien, Ränder */
  --mfi-linie-kraeftig:  #C2CAD1;   /* Ränder, die tragen sollen */
  --mfi-text-leise:      #5C666E;   /* 5.41:1 auf dem Grund, 5.86:1 auf der Fläche */
  --mfi-text:            #1F262B;   /* 14.15:1 auf dem Grund, 15.32:1 auf der Fläche */

  /* ==========================================================
     AMPEL — strikt getrennt von den Markenfarben

     Vier Zustände. Die Farbe ist immer nur die Zugabe: jeder Zustand
     trägt zusätzlich Klartext (aus lib/ablauf.js) und ein Symbol.

     Rot-Grün-Sehschwäche betrifft etwa jeden zwölften Mann, und ein
     Eichbeamter liest das eventuell im Halbdunkel einer Werkhalle.
     Wer nur die Farbe setzt, hat für diese Leser nichts gesetzt.
     ========================================================== */
  --ampel-gueltig:        #186B34;  /* 6.58:1 auf der Fläche, 6.07:1 auf dem Grund */
  --ampel-gueltig-flaeche:#E7F4EC;
  /* Amber, kein Gelb: Gelb auf Weiß trägt keinen Text. Stand zuerst auf
     #9A6400 — das ergab auf der eigenen Fläche nur 4.47:1 und fiel im
     Prüfsatz durch. Eine Farbe gegen Weiß zu prüfen und dann auf einer
     getönten Fläche zu verwenden, ist der übliche Weg, wie 4,5:1 auf
     dem Papier stimmt und auf dem Schirm nicht. */
  --ampel-bald:           #8F5D00;  /* 5.62:1 auf der Fläche, 5.19:1 auf dem Grund,
                                       5.02:1 auf der eigenen Fläche — der schlechteste
                                       Wert des hellen Satzes und damit der Prüfstein */
  --ampel-bald-flaeche:   #FBF1DF;
  --ampel-abgelaufen:     #B3261E;  /* 6.54:1 auf der Fläche, 6.03:1 auf dem Grund */
  --ampel-abgelaufen-flaeche:#FBE9E7;
  --ampel-unbestimmt:     #5C666E;  /* 5.86:1 auf der Fläche, 5.41:1 auf dem Grund */
  --ampel-unbestimmt-flaeche:#EFF1F3;

  /* ==========================================================
     GEFAHR UND ERFOLG — eigene Farben mit eigener Bedeutung (Phase 14)

     Die Ampelfarben stehen AUSSCHLIESSLICH für die Gültigkeit eines
     Gewichts. Bis Phase 14 borgten sich zerstörende Knöpfe,
     Fehlermeldungen, Konflikte und Erfolgsmeldungen das Ampelrot und
     -grün. Dann hätte eine spätere Änderung am Ampelrot jeden
     "Deaktivieren"-Knopf umgefärbt — und umgekehrt.

     Deshalb eigene Variablen. Rot und Grün dürfen sie sein, aber mit
     eigenen WERTEN, nah an den bisherigen, damit sich nichts sichtbar
     verschiebt, und doch nicht dieselben: sonst könnte der Prüflauf im
     Browser eine Gefahrenfarbe nicht von einer Ampelfarbe
     unterscheiden (test-handy.js vergleicht Werte, test-design.js
     Variablen).

     --gefahr   zerstörende Aktionen und Fehlermeldungen
     --erfolg   "gespeichert", "angelegt", ein gelungener Upload
     ========================================================== */
  --gefahr:               #A51C24;  /* 7.52:1 auf der Fläche, 6.94:1 auf dem Grund */
  --gefahr-flaeche:       #FCEAEB;  /* 6.49:1 für --gefahr darauf */
  --gefahr-text:          var(--mfi-weiss);  /* auf gefülltem Gefahrknopf: 7.52:1 */
  --erfolg:               #176B3F;  /* 6.54:1 auf der Fläche, 6.04:1 auf dem Grund */
  --erfolg-flaeche:       #E5F3EA;  /* 5.71:1 für --erfolg darauf */

  /* Der Schleier hinter einer Rückfrage (<dialog>). */
  --schleier:             rgba(16, 24, 32, .45);

  /* ==========================================================
     SCHRIFT
     Systemschriftstapel — KEINE Einbindung von Google Fonts oder einem
     anderen fremden Server. Ein solcher Aufruf überträgt bei jedem
     Seitenaufruf die IP-Adresse des Nutzers an Dritte; für ein Archiv,
     das Eichbeamte benutzen, ist das ein Problem, das man sich nicht
     einfängt. Der Stapel kostet außerdem keinen einzigen Ladevorgang.
     ========================================================== */
  --schriftfamilie: system-ui, -apple-system, "Segoe UI", Roboto,
                    "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --schriftfamilie-fest: ui-monospace, SFMono-Regular, "SF Mono", Menlo,
                    Consolas, "Liberation Mono", monospace;

  --schrift-xs:   0.75rem;   /* 12px — Fußnoten, Merker */
  --schrift-sm:   0.875rem;  /* 14px — Beschriftungen */
  --schrift-md:   1rem;      /* 16px — Fließtext */
  --schrift-lg:   1.125rem;  /* 18px */
  --schrift-xl:   1.375rem;  /* 22px — Abschnittsüberschrift */
  --schrift-2xl:  1.75rem;   /* 28px — Seitenüberschrift */
  --schrift-3xl:  2.25rem;   /* 36px — die Nummer in der Detailansicht */
  --schrift-suche:1.5rem;    /* 24px — das Suchfeld, bewusst eigener Wert */

  --gewicht-normal: 400;
  --gewicht-halbfett: 600;
  --gewicht-fett: 700;

  --zeilenhoehe-eng: 1.25;
  --zeilenhoehe: 1.55;

  /* ==========================================================
     ABSTÄNDE — feste Stufenleiter, nichts dazwischen
     Basis 4px. Frei gewählte Abstände ergeben nach zwanzig Stellen
     zwanzig Abstände, die alle „ungefähr gleich" aussehen sollen.
     ========================================================== */
  --abstand-0:  0;
  --abstand-1:  0.25rem;   /*  4px */
  --abstand-2:  0.5rem;    /*  8px */
  --abstand-3:  0.75rem;   /* 12px */
  --abstand-4:  1rem;      /* 16px */
  --abstand-5:  1.5rem;    /* 24px */
  --abstand-6:  2rem;      /* 32px */
  --abstand-7:  3rem;      /* 48px */
  --abstand-8:  4rem;      /* 64px */

  /* ==========================================================
     FORM
     ========================================================== */
  /* Aus dem Entwurf übernommen (Phase 9): 6/10 statt 4/8. Weichere
     Ecken, damit weiße Flächen auf grauem Grund als Karten lesbar sind
     und nicht als Ausschnitt. `--radius-gross` und `--radius-rund`
     bleiben, wie sie waren. */
  --radius-klein:  6px;
  --radius:        10px;
  --radius-gross:  14px;
  --radius-rund:   999px;

  --linie-duenn:   1px;
  --linie-dick:    2px;

  --schatten-leicht: 0 1px 2px rgba(16, 24, 32, .08);
  --schatten:        0 2px 8px rgba(16, 24, 32, .10);
  /* Der Schatten am Rand einer Tabelle, die weiterrollt (Phase 12).
     Nur die FARBE steht hier; die Form setzt stil.css. */
  --schatten-rand:   rgba(16, 24, 32, .22);

  /* ---- Antippflächen ----
     44px ist die kleinste Fläche, die sich mit dem Daumen zuverlässig
     treffen lässt. Die Detailansicht wird am Gewicht stehend bedient,
     unter Umständen mit Handschuhen. */
  --tippflaeche: 44px;
  /* Das Suchfeld und sein Knopf: größer als die Norm, weil sie das
     einzige sind, was auf der Startseite bedient wird. */
  --tippflaeche-gross: 56px;

  /* ---- Logo ----
     Nicht unter 40px hoch (Vorgabe): darunter werden die Mammuts und
     der Schriftzug zu Grafik ohne Aussage. Die Datei ist 215×137 px —
     bei 48px Höhe also 75px breit und noch über der eigenen Auflösung,
     bei 72px auf der Anmeldeseite immer noch darunter. */
  --logo-hoehe:        48px;
  --logo-hoehe-gross:  72px;

  /* ---- Breiten ---- */
  /* Die Seitenleiste aus dem Entwurf (236 px). Unterhalb von 56rem
     gibt es sie nicht — dort steht die Navigation wieder waagerecht
     unter der Marke, siehe stil.css. Eine Leiste, die auf 375 px
     stehen bliebe, nähme zwei Drittel der Breite. */
  --breite-seitenleiste: 14.75rem;
  --breite-inhalt:   64rem;
  --breite-schmal:   26rem;
  --breite-suche:    46rem;
  --breite-formular: 30rem;
  /* Die linke Spalte der Anlegen-Formulare: Beschriftung und Hilfetext
     (Entwurf, Phase 9). Rechts daneben steht das Feld. */
  --breite-beschriftung: 18rem;
  /* Eine Tabelle mit festen Spalten wird nicht schmaler als das. Auf
     375px wären sechs Spalten je 55px breit — Eingabefelder, in die
     kein Name passt. Darunter rollt der Rahmen waagerecht, die Seite
     bleibt stehen (Phase 10, Punkt 2).

     Der erste Wert (44rem) war zu knapp: bei 375px nachgemessen passten
     "Anmeldename", "ansbach", ein Anmeldezeitpunkt und "Gewichte" nicht
     in ihre Spalte und brachen mitten im Wort um ("ansbac / h"). Bei
     50rem passt jedes dieser Wörter. */
  --breite-tabelle: 50rem;
  /* Die Rollennamen über der Nutzertabelle stehen bündig untereinander. */
  --breite-rolle: 4rem;
  --breite-karte:    20rem;   /* kleinste Kartenbreite im Raster */
  --breite-vorschau: 5.5rem;  /* Foto auf der Trefferkarte */
  --breite-bild:     20rem;   /* Foto in der Detailansicht */
  --breite-knopf:    12rem;   /* Mindestbreite, bevor Knöpfe umbrechen */
  --breite-qr:       12rem;
  --breite-feld:     10rem;   /* kleinste Feldbreite im Korrekturraster */
  --kasten-groesse:  1.15rem; /* Ankreuzfeld */

  /* ---- Symbole der Ampel ----
     Eine FORM je Zustand, kein eingefärbter Punkt: ein Punkt trüge
     dieselbe Information wie die Farbe und keine eigene. */
  --symbol-groesse:       1.1em;
  --symbol-groesse-gross: 1.3em;

  /* ---- Sonstiges, das sonst irgendwo hart stünde ---- */
  --linie-kante:     4px;     /* farbige Kante links an Karten und Meldungen */
  --sperrung-weit:   0.08em;  /* Versalien im Logo-Schriftzug */
  --deckkraft-still: 0.55;    /* deaktivierte Knöpfe, archivierte Zeilen */

  /* ==========================================================
     BEWEGUNG
     Nur kurze Übergänge bei Hover und Zustandswechsel, sonst nichts.
     ========================================================== */
  --uebergang: 120ms ease-out;

  /* ---- Fokus ----
     Sichtbar auf ALLEM, was bedienbar ist, und nirgends weggestylt.
     Zwei Ringe: der farbige zeigt die Stelle, der weiße darunter hält
     ihn auch auf farbigem Grund sichtbar. */
  --fokus-staerke: 3px;
  --fokus-farbe:   #004E7C;
  --fokus-kontur:  #FFFFFF;
}

/* ============================================================
   DUNKELMODUS
   Nicht Zierde: die Detailansicht wird in einer Werkhalle gelesen, oft
   im Halbdunkel und auf einem Telefon mit heruntergedrehter Helligkeit.
   Alle Werte hier sind genauso gerechnet wie oben.
   ============================================================ */
@media (prefers-color-scheme: dark) {
  :root {
    --mfi-primaer:         #6FB2E6;  /* 7.81:1 auf dunklem Grund */
    --mfi-primaer-dunkel:  #8AC2F0;  /* heller = "aktiver", Hover dreht sich um */
    --mfi-primaer-hell:    #16303F;
    --mfi-primaer-rand:    #24506B;

    --mfi-akzent:          #F0737C;  /* 6.33:1 */

    --mfi-weiss:           #FFFFFF;
    --mfi-grund:           #14181B;
    --mfi-flaeche:         #1E2428;
    --mfi-flaeche-tief:    #272E33;
    --mfi-linie:           #333C42;
    --mfi-linie-kraeftig:  #46525A;
    --mfi-text-leise:      #A6B0B8;  /* 8.10:1 */
    --mfi-text:            #E8ECEF;  /* 15.03:1 */

    --ampel-gueltig:        #4FC97E;  /* 8.49:1 */
    --ampel-gueltig-flaeche:#132A1D;
    --ampel-bald:           #E0A63A;  /* 8.23:1 */
    --ampel-bald-flaeche:   #2E2415;
    --ampel-abgelaufen:     #F07A72;  /* 6.57:1 */
    --ampel-abgelaufen-flaeche:#301A19;
    --ampel-unbestimmt:     #A6B0B8;  /* 8.10:1 */
    --ampel-unbestimmt-flaeche:#22282C;

    --gefahr:               #FF8A84;  /* 7.84:1 auf dem Grund, 6.89:1 auf der Fläche */
    --gefahr-flaeche:       #3A1B1C;  /* 6.81:1 */
    /* Auf dem hellen Gefahrrot im Dunkelmodus trägt nur DUNKLE Schrift:
       weiss darauf hätte 2.28:1. */
    --gefahr-text:          #14181B;  /* 7.84:1 */
    --erfolg:               #5CD08B;  /* 9.22:1 auf dem Grund, 8.11:1 auf der Fläche */
    --erfolg-flaeche:       #14301F;  /* 7.37:1 */
    --schleier:             rgba(0, 0, 0, .65);

    /* ---- Schrift auf gefüllten Knöpfen (Phase 14 gefunden) ----
       Hier stand nichts, also galt der helle Wert: WEISS auf dem hellen
       Blau des Dunkelmodus (#6FB2E6) — 2.29:1, auf jedem "Suchen",
       "Anmelden" und "Anlegen" seit Phase 4. Der Prüflauf rechnete die
       Knopfschrift nur für den hellen Satz nach. Jetzt: dunkle Schrift,
       7.74:1, und test-design.js rechnet beide Sätze. */
    --mfi-aktion-text:      #0B1A24;

    --schatten-leicht: 0 1px 2px rgba(0, 0, 0, .40);
    --schatten:        0 2px 8px rgba(0, 0, 0, .50);
    --schatten-rand:   rgba(0, 0, 0, .70);

    --fokus-farbe:   #8AC2F0;
    --fokus-kontur:  #14181B;
  }
}

/* ============================================================
   GRUNDLAGEN — die Regeln, die überall gelten
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }

/* ---- `hidden` muss gewinnen ----
   Die Voreinstellung des Browsers ist `[hidden] { display: none }` — eine
   Regel mit der Spezifität eines Attributs. Jedes `#kopf { display: flex }`
   hat die eines Bezeichners und schlägt sie.

   Das ist hier ZWEIMAL passiert: in Phase 3 stand die Kopfleiste samt
   "Abmelden" auf der Anmeldeseite, die Regel wurde ergänzt — und beim
   Neuschreiben von stil.css in Phase 4 ging sie wieder verloren.

   Deshalb steht sie jetzt im Designsystem und nicht in der Gestaltung:
   sie ist eine Grundlage, keine Eigenschaft einer Seite. `test-design.js`
   prüft, dass es sie gibt; ohne diesen Wächter kommt sie ein drittes Mal
   abhanden. */
[hidden] { display: none !important; }

html {
  /* Das Suchfeld bekommt beim Laden den Fokus. Springt die Seite
     danach, hat man die Stelle verloren, bevor man sie gesehen hat. */
  scroll-behavior: auto;
}

body {
  margin: var(--abstand-0);
  font-family: var(--schriftfamilie);
  font-size: var(--schrift-md);
  line-height: var(--zeilenhoehe);
  color: var(--mfi-text);
  background: var(--mfi-grund);
  /* ---- Ziffern tabellarisch, überall ----
     Gewichtsnummern und Messwerte stehen in Listen untereinander. Mit
     proportionalen Ziffern ist die 1 schmaler als die 8, und dann
     fluchtet 14008 nicht mit 14000 — genau die Verwechslung, gegen die
     dieses Archiv gebaut ist. */
  font-variant-numeric: tabular-nums;
  -webkit-text-size-adjust: 100%;
}

/* ---- Fokus: sichtbar, und zwar auf allem ----
   `:focus-visible` und nicht `:focus`: mit der Maus geklickte Knöpfe
   bekommen keinen Ring, mit der Tastatur angesteuerte schon. Wer hier
   `outline: none` schreibt, nimmt der Tastaturbedienung ihre einzige
   Ortsangabe. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--fokus-staerke) solid var(--fokus-farbe);
  outline-offset: var(--linie-dick);
  border-radius: var(--radius-klein);
}

/* Für Browser ohne :focus-visible bleibt der normale Fokusring stehen —
   hier wird nichts entfernt, nur ersetzt, wo es besser geht. */

img, svg { max-width: 100%; height: auto; }

/* ---- Bewegung nur, wenn erwünscht ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }
}
