/* Oberfläche des 24/7-Schliessfach-Backends.
   Farbwelt an die LockTec-Terminaloberfläche angelehnt (warmes Rot auf hellem Grau). */

:root {
    --accent: #d4695c;
    --accent-dark: #b8544a;
    --ink: #2f3336;
    --ink-soft: #666c70;   /* #6b7276 ergab auf der Seitenfläche nur 4,28:1 */
    --line: #dfe3e6;
    --surface: #ffffff;
    --surface-alt: #f5f6f7;
    --page: #eef0f2;

    --ok: #4a8f43;
    --warn: #d99a24;
    --danger: #c0392b;
    --info: #3a7ca5;

    --radius: 6px;
    --shadow: 0 1px 3px rgba(0, 0, 0, .08);

    /* Flächen, die im hellen Bild fast weiss sind und im dunklen nicht einfach
       umgekehrt werden dürfen — sonst leuchten Tabellenzeilen und Hinweise. */
    --row-hover: #fafbfb;
    --nav-active: #fdf1ef;
    --choice-selected: #fdf6f5;
    --locker-occupied: #fdf6f5;
    --locker-reserved: #f4f8fb;
    --locker-defective: #fdf0ee;

    --badge-success-bg: #e6f2e5; --badge-success-ink: #2f6b29;
    --badge-danger-bg:  #fbe9e7; --badge-danger-ink:  #a5281c;
    --badge-warning-bg: #fdf3e0; --badge-warning-ink: #8a6114;
    --badge-info-bg:    #e6f0f6; --badge-info-ink:    #275c7c;
    --badge-primary-bg: #eae7f6; --badge-primary-ink: #4a3f8f;
    --badge-secondary-bg: #eceef0; --badge-secondary-ink: #5a6367;
    --badge-dark-bg:    #dfe3e6; --badge-dark-ink:    #33383b;

    --alert-success-bg: #f0f7ef; --alert-success-line: #cde3ca;
    --alert-danger-bg:  #fdf0ee; --alert-danger-line:  #f2ccc7;
    --alert-warning-bg: #fdf7ec; --alert-warning-line: #f0dfbc;
    --alert-info-bg:    #eff5f9; --alert-info-line:    #cbdce7;

    /* --- Getrennt vom Grundton: Flächen und Schriften, die beide Bilder verschieden lösen ---

       ⚠️ Der Anlass war messbar. Die Felder hatten background: #fff fest eingetragen; im
       dunklen Bild stand damit --ink (#e3e6e8) auf Weiss — 1,25:1, also praktisch unlesbar,
       und aufgefallen ist es am Auswahlfeld der Benachrichtigungen. Ebenso war Weiss auf dem
       Akzent im dunklen Bild nur 2,80:1, weil der Akzent dort bewusst heller ist.

       Die Regel dahinter: Wo eine Fläche je Bild anders ist, gehört auch ihre Schriftfarbe zum
       Bild — und nicht in die Regel, die beide teilen. */
    --field-bg: #ffffff;
    --field-line: #dfe3e6;

    --accent-fill: #b8544a;   /* gefüllte Knöpfe: dunkler als der Akzent, sonst 3,5:1 unter Weiss */
    --on-accent: #ffffff;
    --danger-fill: #c0392b;
    --on-danger: #ffffff;

    --accent-text: #a8483e;   /* Akzent als Schrift — nicht als Fläche */
    --danger-text: #c0392b;
    --warn-text: #8a6114;     /* --warn selbst ist auf Weiss nur 2,44:1 */
}

/* --- Dunkles Erscheinungsbild ---

   Die Farben sind einzeln gesetzt und nicht rechnerisch invertiert: Das warme Rot der
   LockTec-Terminals bleibt die Leitfarbe, wird aber etwas heller, weil es sonst auf
   dunklem Grund absäuft. Flächen sind angehoben statt aufgehellt, damit Karten und
   Tabellen ihre Schichtung behalten. */

:root[data-theme="dark"] {
    --accent: #e08074;
    --accent-dark: #c96a5e;
    --ink: #e3e6e8;
    --ink-soft: #9aa3a8;
    --line: #3a4045;
    --surface: #23282c;
    --surface-alt: #2b3135;
    --page: #191d20;

    --ok: #6fb567;
    --warn: #e0ac4a;
    --danger: #e0685a;
    --info: #6aa9cd;

    --shadow: 0 1px 3px rgba(0, 0, 0, .45);

    --row-hover: #2b3135;
    --nav-active: #3a2d2b;
    --choice-selected: #332927;
    --locker-occupied: #332927;
    --locker-reserved: #24313a;
    --locker-defective: #3a2724;

    --badge-success-bg: #24401f; --badge-success-ink: #a7d6a0;
    --badge-danger-bg:  #45231e; --badge-danger-ink:  #eda79c;
    --badge-warning-bg: #423318; --badge-warning-ink: #e6c584;
    --badge-info-bg:    #1e343f; --badge-info-ink:    #9ecae4;
    --badge-primary-bg: #2e2a45; --badge-primary-ink: #b5aee0;
    --badge-secondary-bg: #32383c; --badge-secondary-ink: #b0b8bd;
    --badge-dark-bg:    #3d4348; --badge-dark-ink:    #d2d8dc;

    --alert-success-bg: #1f3419; --alert-success-line: #3c5c34;
    --alert-danger-bg:  #3b201c; --alert-danger-line:  #6b352d;
    --alert-warning-bg: #3a2e15; --alert-warning-line: #64502a;
    --alert-info-bg:    #1b2c36; --alert-info-line:    #33505f;

    --field-bg: #1b1f22;
    --field-line: #6a7278;

    /* Auf dem hellen Akzent steht dunkle Schrift: 5,93:1 statt 2,80:1 mit Weiss. */
    --accent-fill: #e08074;
    --on-accent: #1b1f22;
    --danger-fill: #e0685a;
    --on-danger: #1b1f22;

    --accent-text: #e08074;
    --warn-text: #e6c584;
    --danger-text: #e5776a;   /* --danger selbst ergab auf der Karte 4,46:1 */
}

/* Ohne ausdrückliche Wahl entscheidet das Betriebssystem. Die Bedingung schliesst beide
   gesetzten Werte aus, damit eine bewusste Wahl "Hell" nicht doch dunkel wird. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]):not([data-theme="dark"]) {
        --accent: #e08074;
        --accent-dark: #c96a5e;
        --ink: #e3e6e8;
        --ink-soft: #9aa3a8;
        --line: #3a4045;
        --surface: #23282c;
        --surface-alt: #2b3135;
        --page: #191d20;

        --ok: #6fb567;
        --warn: #e0ac4a;
        --danger: #e0685a;
        --info: #6aa9cd;

        --shadow: 0 1px 3px rgba(0, 0, 0, .45);

        --row-hover: #2b3135;
        --nav-active: #3a2d2b;
        --choice-selected: #332927;
        --locker-occupied: #332927;
        --locker-reserved: #24313a;
        --locker-defective: #3a2724;

        --badge-success-bg: #24401f; --badge-success-ink: #a7d6a0;
        --badge-danger-bg:  #45231e; --badge-danger-ink:  #eda79c;
        --badge-warning-bg: #423318; --badge-warning-ink: #e6c584;
        --badge-info-bg:    #1e343f; --badge-info-ink:    #9ecae4;
        --badge-primary-bg: #2e2a45; --badge-primary-ink: #b5aee0;
        --badge-secondary-bg: #32383c; --badge-secondary-ink: #b0b8bd;
        --badge-dark-bg:    #3d4348; --badge-dark-ink:    #d2d8dc;

        --alert-success-bg: #1f3419; --alert-success-line: #3c5c34;
        --alert-danger-bg:  #3b201c; --alert-danger-line:  #6b352d;
        --alert-warning-bg: #3a2e15; --alert-warning-line: #64502a;
        --alert-info-bg:    #1b2c36; --alert-info-line:    #33505f;

        --field-bg: #1b1f22;
        --field-line: #6a7278;

        /* Auf dem hellen Akzent steht dunkle Schrift: 5,93:1 statt 2,80:1 mit Weiss. */
        --accent-fill: #e08074;
        --on-accent: #1b1f22;
        --danger-fill: #e0685a;
        --on-danger: #1b1f22;

        --accent-text: #e08074;
        --warn-text: #e6c584;
        --danger-text: #e5776a;
    }
}

* { box-sizing: border-box; }

/* Formularfelder und Bildlaufleisten folgen dem gewählten Bild, sonst bleiben sie
   im dunklen Erscheinungsbild weiss. */
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 14px;
    color: var(--ink);
    background: var(--page);
}

h1 { font-size: 1.5rem; font-weight: 600; margin: 0 0 .25rem; }
h2 { font-size: 1.15rem; font-weight: 600; margin: 0 0 .75rem; }
h3 { font-size: 1rem; font-weight: 600; margin: 0 0 .5rem; }

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

/* --- Grundgerüst --- */

.app-shell { display: flex; min-height: 100vh; }

.sidebar {
    width: 240px;
    flex: 0 0 240px;
    background: var(--surface);
    border-right: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.content { flex: 1; padding: 1.5rem 2rem 3rem; min-width: 0; }

.nav-brand { padding: 1.25rem 1rem; border-bottom: 1px solid var(--line); }
.nav-brand a { display: flex; align-items: center; gap: .6rem; color: var(--ink); }
.nav-brand a:hover { text-decoration: none; }
.brand-mark {
    background: var(--accent-fill); color: var(--on-accent); font-weight: 700;
    padding: .3rem .5rem; border-radius: var(--radius); font-size: .85rem; letter-spacing: .02em;
}
.brand-text { font-weight: 600; font-size: .95rem; line-height: 1.2; }

.nav-sections { flex: 1; overflow-y: auto; padding: .75rem 0; }
.nav-group { margin-bottom: 1rem; }
.nav-group-title {
    padding: .35rem 1rem; font-size: .7rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft);
}
.nav-item {
    display: flex; align-items: center; gap: .55rem;
    padding: .5rem 1rem; color: var(--ink); font-size: .9rem;
    border-left: 3px solid transparent;
}
.nav-item:hover { background: var(--surface-alt); text-decoration: none; }
.nav-item.active { background: var(--nav-active); border-left-color: var(--accent); font-weight: 600; color: var(--accent-text); }
.nav-icon { width: 1.1rem; text-align: center; opacity: .75; }
/* Hinweis auf einen neuen Tab — sonst wirkt der Sprung aus dem Panel wie ein Fehler. */
.nav-extern { margin-left: auto; font-size: .75rem; opacity: .55; }

.sidebar-footer { border-top: 1px solid var(--line); padding: .75rem; }

/* --- Statusanzeige --- */

.status-badge { display: flex; align-items: center; gap: .55rem; padding: .5rem; border-radius: var(--radius); color: var(--ink); }
.status-badge:hover { background: var(--surface-alt); text-decoration: none; }
.status-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 9px; background: var(--ink-soft); }
.status-ok .status-dot { background: var(--ok); box-shadow: 0 0 0 3px rgba(74, 143, 67, .18); }
.status-error .status-dot { background: var(--danger); box-shadow: 0 0 0 3px rgba(192, 57, 43, .18); }
.status-unknown .status-dot { background: var(--warn); }
.status-text { display: flex; flex-direction: column; min-width: 0; }
.status-text strong { font-size: .82rem; }
.status-text small { font-size: .7rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- Seitenkopf --- */

.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.page-head .subtitle { color: var(--ink-soft); font-size: .875rem; }
.page-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

/* --- Karten --- */

.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.card + .card { margin-top: 1rem; }
.card-head { padding: .75rem 1rem; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.card-head h2, .card-head h3 { margin: 0; }
.card-body { padding: 1rem; }
.card-body.tight { padding: 0; }

.grid { display: grid; gap: 1rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

/* --- Kennzahlen --- */

.metric { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: .9rem 1rem; box-shadow: var(--shadow); }
.metric .value { font-size: 1.75rem; font-weight: 700; line-height: 1.1; }
.metric .label { font-size: .78rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .05em; margin-top: .2rem; }
.metric .hint { font-size: .75rem; color: var(--ink-soft); margin-top: .35rem; }
.metric.accent { border-left: 3px solid var(--accent); }
.metric.danger .value { color: var(--danger-text); }
.metric.warn .value { color: var(--warn-text); }
.metric.ok .value { color: var(--ok); }

/* --- Tabellen --- */

table.data { width: 100%; border-collapse: collapse; font-size: .875rem; }
table.data th {
    text-align: left; padding: .6rem .75rem; font-weight: 600; font-size: .75rem;
    text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft);
    background: var(--surface-alt); border-bottom: 1px solid var(--line); white-space: nowrap;
}
table.data td { padding: .55rem .75rem; border-bottom: 1px solid var(--line); vertical-align: top; }
table.data tbody tr:hover { background: var(--row-hover); }
table.data tbody tr.clickable { cursor: pointer; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.nowrap { white-space: nowrap; }

.table-scroll { overflow-x: auto; }

.empty { padding: 2rem 1rem; text-align: center; color: var(--ink-soft); }

/* --- Abzeichen --- */

.badge {
    display: inline-block; padding: .15rem .5rem; border-radius: 10px;
    font-size: .72rem; font-weight: 600; white-space: nowrap; line-height: 1.5;
}
.badge-success { background: var(--badge-success-bg); color: var(--badge-success-ink); }
.badge-danger  { background: var(--badge-danger-bg); color: var(--badge-danger-ink); }
.badge-warning { background: var(--badge-warning-bg); color: var(--badge-warning-ink); }
.badge-info    { background: var(--badge-info-bg); color: var(--badge-info-ink); }
.badge-primary { background: var(--badge-primary-bg); color: var(--badge-primary-ink); }
.badge-secondary { background: var(--badge-secondary-bg); color: var(--badge-secondary-ink); }
.badge-dark    { background: var(--badge-dark-bg); color: var(--badge-dark-ink); }

/* --- Schaltflächen --- */

.btn {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .4rem .8rem; border-radius: var(--radius); border: 1px solid var(--line);
    background: var(--surface); color: var(--ink); font-size: .85rem; cursor: pointer;
    font-family: inherit; line-height: 1.4;
}
.btn:hover:not(:disabled) { background: var(--surface-alt); text-decoration: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-accent); }
.btn-primary:hover:not(:disabled) { background: var(--accent-dark); border-color: var(--accent-dark); }
.btn-danger { background: var(--danger-fill); border-color: var(--danger-fill); color: var(--on-danger); }
.btn-danger:hover:not(:disabled) { background: var(--badge-danger-ink); }
.btn-sm { padding: .25rem .55rem; font-size: .78rem; }

/* --- Formulare --- */

.field { margin-bottom: .9rem; }
.field label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .25rem; }
.field .help { font-size: .75rem; color: var(--ink-soft); margin-top: .2rem; }
.field input[type=text], .field input[type=email], .field input[type=tel], .field input[type=number],
.field input[type=search], .field select, .field textarea, .input {
    width: 100%; padding: .45rem .6rem; border: 1px solid var(--field-line);
    border-radius: var(--radius); font-size: .875rem; font-family: inherit;
    background: var(--field-bg); color: var(--ink);
}
/* Ohne eigene Angabe nimmt der Browser sein Grau — im dunklen Bild auf dunklem Grund.

   ⚠️ Die Regel hängt an den Hüllen des Panels (.app-shell für die Seiten, .auth-page für
   Anmeldung und Passwortwechsel) und nicht an .field allein. Das Kundenformular benutzt
   dieselbe Klasse .field; ohne diese Einschränkung änderte sich dort die Farbe der
   Platzhalter mit. Gemessen war es genau das: vier Zeilenbereiche im Formular wichen ab,
   #7d7d7d wurde zu #6f7478 — derselbe Fallstrick wie bei .choice und .code-display. */
.app-shell .field input::placeholder, .app-shell .field textarea::placeholder,
.app-shell .input::placeholder,
.auth-page .input::placeholder { color: var(--ink-soft); opacity: 1; }
.field textarea { min-height: 90px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus, .input:focus {
    outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(212, 105, 92, .15);
}
.validation-message { color: var(--danger-text); font-size: .78rem; margin-top: .2rem; }

.choice { display: flex; gap: .5rem; align-items: flex-start; padding: .6rem .75rem; border: 1px solid var(--line); border-radius: var(--radius); cursor: pointer; background: var(--surface); }
.choice:hover { border-color: var(--accent); }
.choice input { margin-top: .2rem; }
.choice.selected { border-color: var(--accent); background: var(--choice-selected); }
.choice strong { display: block; font-size: .875rem; }
.choice small { color: var(--ink-soft); font-size: .78rem; }

/* --- Auswahlfelder ---

   ⚠️ Nur `select.input`, nicht `.field select`: Dieselbe Regel würde sonst auch das
   Kundenformular treffen, und das hat sein eigenes, an ch.jura.com angelehntes Aussehen.

   `appearance: none` ist hier nicht Geschmack. Auf macOS zeichnet der Browser ein Auswahlfeld
   als Systemschalter und übergeht dabei Hintergrund und Schriftfarbe — im dunklen Bild kam
   dabei ein blasser Text auf hellem Grund heraus, obwohl beides gesetzt war. Genau daran ist
   es aufgefallen. Mit `appearance: none` gilt wieder, was hier steht; dafür muss der Pfeil
   selbst gezeichnet werden.

   Er besteht aus zwei Farbverläufen und nicht aus einer eingebetteten Grafik: Eine Grafik als
   data:-Adresse kann keine CSS-Variable lesen, sie bräuchte also je Bild eine eigene Fassung —
   und die zweite vergisst man beim nächsten Farbwechsel. */
select.input {
    appearance: none;
    padding-right: 1.75rem;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
        linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
    background-position: right 1rem center, right .7rem center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

.toolbar { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.toolbar .input, .toolbar select { width: auto; min-width: 160px; }

/* --- Meldungen --- */

.alert { padding: .7rem .9rem; border-radius: var(--radius); border: 1px solid; font-size: .875rem; margin-bottom: 1rem; }
.alert-success { background: var(--alert-success-bg); border-color: var(--alert-success-line); color: var(--badge-success-ink); }
.alert-danger  { background: var(--alert-danger-bg); border-color: var(--alert-danger-line); color: var(--badge-danger-ink); }
.alert-warning { background: var(--alert-warning-bg); border-color: var(--alert-warning-line); color: var(--badge-warning-ink); }
.alert-info    { background: var(--alert-info-bg); border-color: var(--alert-info-line); color: var(--badge-info-ink); }

/* --- Rohdaten --- */

pre.raw {
    background: #22262a; color: #d7dde2; padding: .75rem; border-radius: var(--radius);
    font-family: "SF Mono", Menlo, Consolas, monospace; font-size: .78rem;
    overflow-x: auto; max-height: 380px; margin: 0; line-height: 1.45;
}
code.inline {
    background: var(--surface-alt); padding: .1rem .35rem; border-radius: 3px;
    font-family: "SF Mono", Menlo, Consolas, monospace; font-size: .82rem;
}

/* --- Zeitleiste --- */

.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li { position: relative; padding: 0 0 1rem 1.5rem; border-left: 2px solid var(--line); }
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
    content: ""; position: absolute; left: -5px; top: .35rem;
    width: 8px; height: 8px; border-radius: 50%; background: var(--ink-soft);
}
.timeline li.status::before { background: var(--accent); }
.timeline .when { font-size: .75rem; color: var(--ink-soft); }
.timeline .what { font-size: .875rem; font-weight: 500; }
.timeline .who { font-size: .75rem; color: var(--ink-soft); }
.timeline .detail { font-size: .8rem; color: var(--ink-soft); margin-top: .15rem; white-space: pre-wrap; }

/* --- Fachraster --- */

.locker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: .5rem; }
.locker {
    border: 1px solid var(--line); border-radius: var(--radius); padding: .5rem;
    background: var(--surface); text-align: center; font-size: .78rem; cursor: pointer;
}
.locker:hover { border-color: var(--accent); }
.locker .name { font-weight: 700; font-size: .9rem; }
.locker .meta { color: var(--ink-soft); font-size: .7rem; margin-top: .15rem; }
.locker.free { border-left: 3px solid var(--ok); }
.locker.occupied { border-left: 3px solid var(--accent); background: var(--locker-occupied); }
.locker.reserved { border-left: 3px solid var(--info); background: var(--locker-reserved); }
.locker.defective { border-left: 3px solid var(--danger); background: var(--locker-defective); }
.locker.inactive { opacity: .5; }

/* --- Reiter --- */

.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line); margin-bottom: 1rem; flex-wrap: wrap; }
.tab {
    padding: .5rem .9rem; border: 1px solid transparent; border-bottom: none;
    border-radius: var(--radius) var(--radius) 0 0; cursor: pointer;
    font-size: .875rem; color: var(--ink-soft); background: none; font-family: inherit;
}
.tab:hover { color: var(--ink); }
.tab.active { background: var(--surface); border-color: var(--line); color: var(--ink); font-weight: 600; margin-bottom: -1px; }

/* --- Definitionslisten --- */

dl.kv { display: grid; grid-template-columns: minmax(140px, auto) 1fr; gap: .35rem .9rem; margin: 0; font-size: .875rem; }
dl.kv dt { color: var(--ink-soft); }
dl.kv dd { margin: 0; word-break: break-word; }
dl.kv dd.missing { color: var(--warn-text); font-style: italic; }

/* Auch im Panel: der Technikercode auf der Auftragsseite. Die Kundenseite hat weiter
   unten eine eigene Fassung — diese hier darf deshalb nicht verschwinden, sonst steht der
   Code auf einer Seite unformatiert, die niemand angefasst hat. */
.code-display {
    font-size: 2rem; font-weight: 700; letter-spacing: .3rem; text-align: center;
    padding: 1rem; background: var(--surface-alt); border-radius: var(--radius);
    font-variant-numeric: tabular-nums;
}

/* --- Kundenformular ---

   Diese Seite folgt bewusst NICHT dem Bedienpanel, sondern der bestehenden
   JURA-24/7-Seite: dieselbe Schrift (Inter), dieselbe Schriftgroesse (16 px), dieselbe
   graue Flaeche mit weisser Spalte, dieselben Ueberschriften mit duenner Unterlinie und
   dieselben eckigen Eingabefelder. Der Kunde soll nicht merken, dass er das System
   gewechselt hat.

   ⚠️ ALLES hier haengt an .public-page. Die Klassen .choice, .code-display, .field und
   .btn gehoeren auch dem Panel; ohne diesen Vorfahren wuerden die Regeln dort mitgelten
   und das Panel auf einer Seite umbauen, die niemand angefasst hat.

   Die Schrift ist mitgeliefert (wwwroot/fonts/inter, SIL Open Font License, Lizenztext
   liegt daneben). Nachladen aus dem Netz kommt nicht in Frage: Die Oberflaeche muss auch
   in einem abgeschotteten Netz vollstaendig darstellbar bleiben. */

@font-face {
    font-family: "Inter";
    font-style: normal;
    /* Variable Schrift: eine Datei traegt die ganze Achse, deshalb eine Spanne statt
       eines Werts. Ohne die Spanne rechnet der Browser 300 aus 400 herunter (synthetisch
       duenner geht nicht — er nimmt dann einfach 400). */
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/inter/inter-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: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/inter/inter-latin-ext.woff2") format("woff2");
    /* Kostet nichts, solange niemand diese Zeichen tippt — der Browser laedt die Datei
       erst, wenn eines vorkommt. Kundennamen in der Schweiz enthalten regelmaessig
       welche (Šimić, Gökhan, Wałęsa), und ohne diesen Block faellt genau dieser Name
       sichtbar in eine andere Schrift. */
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

.public-page {
    --jb-ink: #4c525e;
    --jb-line: #ddd;
    --jb-field: #555;
    --jb-flat: #eee;
    --jb-width: 960px;

    font-family: Inter, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 16px;
    font-weight: 300;
    line-height: 1.5;
    color: var(--jb-ink);
    background: #d4d4d6;

    /* Spalte, damit die weisse Flaeche bis zur Fusszeile reicht. Ohne das endet sie beim
       letzten Absatz — auf der kurzen Bestaetigungsseite haengt der Inhalt dann in einem
       weissen Streifen über grauem Rest. */
    min-height: 100vh; display: flex; flex-direction: column;
}
.public-page .public-content { flex: 1; }

/* Nach dem Seitenaufbau setzt Blazor den Fokus auf die Ueberschrift (FocusOnNavigate in
   Routes.razor, per JavaScript mit tabindex="-1"). Der Browser zeichnet dann einen blauen
   Rahmen um die ganze Zeile — auf einer Seite, die der Kunde gerade erst geoeffnet hat,
   sieht das nach einem Fehler aus.
   ⚠️ :focus-visible reicht hier nicht: Chrome wertet den gesetzten Fokus je nach letzter
   Eingabeart als sichtbar; im ersten Anlauf blieb der Rahmen stehen. Eine Ueberschrift ist
   kein Bedienelement — es geht kein Tastaturhinweis verloren, der Fokus dient allein der
   Vorlesesoftware, und die braucht keinen Rahmen. */
.public-page h1:focus { outline: none; }

/* Kopfband und Fusszeile sind weiss, der Rest der Seite grau — dazwischen liegt der
   dunkle Streifen. Genau diese Schichtung macht den Wiedererkennungswert aus. */
.public-brandbar { background: #fff; }
.public-bar { min-height: 50px; background: linear-gradient(to bottom, #363a42, #4c525e); }
.public-width { width: 100%; max-width: var(--jb-width); margin: 0 auto; padding: 0 1rem; }
/* Kopfband nach dem Vorbild von ch.jura.com. Die Werte sind nicht geschaetzt, sondern aus
   den Tailwind-Klassen des dortigen Kopfbereichs abgelesen (Einheit 0,25 rem = 4 px):
   lg:h-25 = 100 px hohes Band, lg:ml-14.5 = 58 px Einzug, lg:w-32 = 128 px Logo,
   items-center = senkrecht mittig, also 22,5 px ueber und unter dem Logo.
   ⚠️ Das Logo folgt der Kante der Seite, NICHT der 960-px-Spalte. Genau daran ging ein
   frueherer Versuch vorbei: Die Spalte steht mittig, auf einem breiten Bildschirm liegen
   ueber 400 px zwischen Seitenrand und Spaltenrand — ein am Spaltenrand ausgerichtetes Logo
   wandert damit in die Seitenmitte, und je breiter der Bildschirm, desto weiter. Der Abstand
   muss von der Kante aus fest sein, sonst ist er auf keinem Bildschirm der gemessene.
   ⚠️ Hier weichen wir bewusst von ch.jura.com ab: Dort sitzt das Kopfband in einem auf
   1536 px begrenzten, mittigen Kasten (max-w-screen-2xl), also wandert das Logo oberhalb
   dieser Breite doch nach rechts — auf 1920 px um 192 px. Bis 1536 px sind beide Wege
   identisch; darueber ist dieser der ruhigere. */
.public-brandbar .public-width {
    max-width: none;
    height: 100px; display: flex; align-items: center;
    padding-top: 0; padding-bottom: 0; padding-left: 58px;
}

/* Das JURA-Logo steht dort, wo vorher der Schriftzug „24/7 SERVICE" stand. 128x55 ist die
   Groesse, in der ch.jura.com dieselbe Datei zeichnet — nicht gewaehlt, sondern abgelesen.
   ⚠️ Die Datei hat einen weissen, undurchsichtigen Hintergrund und passt nur auf das weisse
   Kopfband. Wird der Streifen je eingefaerbt, braucht es eine Fassung mit Transparenz, sonst
   steht ein weisser Kasten um das Logo.
   Der Bildrand ist hier klein (276x118 gross, 270x117 sichtbar) — bei der Anzeigegroesse
   1,4 px links. Bei der Vorgaengerdatei waren es 4 px, und daran ging eine Runde verloren:
   Bei diesem Logo darf man den Kasten als Mass nehmen, bei jenem nicht. */
.public-logo { display: block; width: 128px; height: 55px; max-width: 100%; }

/* Die weisse Spalte. Das Original ist auf 960 px festgenagelt (<meta viewport
   width=1350>) und auf dem Telefon unbrauchbar; hier ist dieselbe Breite eine
   Obergrenze. Am Schreibtisch sieht es gleich aus, am Telefon funktioniert es. */
.public-content { background: #fff; padding-top: 40px; padding-bottom: 50px; }

/* Nur die Seitenueberschrift steht mittig — die Abschnittsueberschriften (h2) bleiben
   links, sonst verliert die Spalte ihre Leselinie. */
.public-page h1 {
    font-size: 1.3rem; font-weight: 400; color: var(--jb-ink);
    border-bottom: 1px solid var(--jb-line);
    padding-bottom: 10px; margin: 0 0 28px;
    text-align: center;
}

.public-page h2 {
    font-size: 1.1rem; font-weight: 400; color: var(--jb-ink);
    border-bottom: 1px solid var(--jb-line);
    padding-bottom: 10px; margin: 40px 0 20px;
}

.public-page h3 { font-size: 1rem; font-weight: 600; margin: 0 0 .5rem; }
.public-page .lead { margin: 0 0 24px; }

/* Der Hinweiskasten des Originals: flache graue Flaeche, keine Rundung, keine Linie. */
.public-note { background: var(--jb-flat); padding: 12px 14px; margin-bottom: 20px; font-size: .9rem; }

.step-list { counter-reset: step; list-style: none; padding: 0; margin: 0 0 24px; }
.step-list li { counter-increment: step; padding: 6px 0 6px 34px; position: relative; font-size: .9rem; }
.step-list li::before {
    content: counter(step) "."; position: absolute; left: 0; top: 6px;
    width: 24px; text-align: right; font-weight: 600; color: var(--jb-ink);
}

/* Felder: eckig, dunkle Linie, feste Hoechstbreite — wie im Original. Die Hoechstbreite
   ist kein Zierrat: Ein 900 px breites Feld fuer eine Postleitzahl laedt zum Vertippen
   ein und macht das Formular unlesbar. */
.public-page .field { margin-bottom: 14px; }
.public-page .field > label { display: block; margin-bottom: 4px; font-size: .9rem; font-weight: 400; }
.public-page .field .help { font-size: .8rem; color: #7b818b; margin-top: 4px; }

/* ⚠️ NICHT über input[type=text] auswählen. Blazors <InputText> schreibt gar kein
   type-Attribut — es kommt <input name="…" class="valid" value=""> heraus. Der
   Attributwähler greift dann nirgends, und die Felder stehen in Browserbreite (rund
   130 px) nebeneinander, während das Auswahlfeld daneben 480 px breit ist. Genau so sah
   es im ersten Anlauf aus. Deshalb: alles ausser Ankreuz- und Auswahlknöpfen. */
.public-page input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
.public-page select,
.public-page textarea {
    display: block; width: 100%; max-width: 480px;
    padding: 7px; border: 1px solid var(--jb-field); border-radius: 0;
    font-family: inherit; font-size: 1rem; font-weight: 300; color: var(--jb-ink);
    background: #fff;
}
.public-page textarea { max-width: 100%; min-height: 110px; }
.public-page input:focus, .public-page select:focus, .public-page textarea:focus {
    outline: 2px solid var(--jb-ink); outline-offset: -1px;
}
.public-page .invalid { border-color: var(--danger); }
.public-page .validation-message { color: var(--danger); font-size: .85rem; margin-top: 4px; display: block; }

/* Auswahlfelder mit Erlaeuterung. Das Original loest das mit einem ℹ-Symbol und einem
   ausklappbaren Kasten; hier steht die Erlaeuterung fest unter der Wahl, weil sie die
   Entscheidung traegt und niemand nach ihr sucht. */
.public-page .choice {
    display: flex; gap: 10px; align-items: flex-start;
    border: 1px solid var(--jb-line); border-radius: 0;
    padding: 12px; margin: 0; background: #fff; cursor: pointer;
}
.public-page .choice:hover { background: #fafafa; }
.public-page .choice.selected { border-color: var(--jb-ink); background: var(--jb-flat); }
.public-page .choice input { margin-top: 3px; flex: none; width: auto; }
.public-page .choice span { display: block; }
.public-page .choice strong { display: block; font-weight: 600; font-size: .95rem; }
.public-page .choice small { display: block; margin-top: 4px; font-size: .82rem; color: #7b818b; }
.public-page .choice-set { display: grid; gap: 10px; margin-bottom: 14px; }
@media (min-width: 700px) {
    .public-page .choice-set.two   { grid-template-columns: repeat(2, 1fr); }
    .public-page .choice-set.three { grid-template-columns: repeat(3, 1fr); }
}

.public-page .btn {
    border-radius: 0; border: 1px solid var(--jb-ink);
    background: var(--jb-ink); color: #fff;
    font-family: inherit; font-size: 1rem; font-weight: 400;
    padding: 9px 26px; cursor: pointer;
}
.public-page .btn:hover:not(:disabled) { background: #363a42; border-color: #363a42; }
.public-page .btn:disabled { opacity: .55; cursor: default; }

.public-page .alert { border-radius: 0; }

/* Ein <fieldset> bringt eigenen Rahmen, Innenabstand und eine Mindestbreite mit. Ohne diese
   Zeile bekäme das Formular eine Umrandung, die es vorher nicht hatte, und liesse sich auf
   schmalen Geräten nicht mehr zusammenschieben (min-width: min-content ist die Vorgabe). */
.public-page .public-fields { border: 0; padding: 0; margin: 0; min-width: 0; }
.public-page .public-fields:disabled { opacity: .5; }

/* --- Wartezustand beim Absenden ---

   Die Anlage antwortet gemessen in rund 3,5 s auf jeden Aufruf; mit Speichern und Rückweg
   sind es etwa fünf. Der Kunde steht unter Umständen bereits vor der Anlage. Deshalb ein
   Feld, das sagt, worauf gewartet wird, statt eines ausgegrauten Knopfes.

   Alles rein über die Stilvorlage: Die Wartezeit selbst darf keine weiteren Aufrufe erzeugen,
   und ein Zähler, der im Sekundentakt Aktualisierungen über die Verbindung schickt, wäre
   ausgerechnet dann Last, wenn die Anlage ohnehin beschäftigt ist. */
.public-page .public-wait {
    border: 1px solid var(--jb-line); background: var(--jb-flat);
    padding: 18px 20px 20px;
}
.public-page .public-wait strong { display: block; font-weight: 600; }
.public-page .public-wait p { margin: 0; font-size: .9rem; color: #6a707b; }

.public-page .public-wait-kopf {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    margin-bottom: 4px;
}

/* --- Der Balken ---

   Er schrumpft in zwanzig Sekunden von voll auf null: Ein hin- und herlaufender Streifen sagt nur
   „es geschieht etwas", ein schrumpfender sagt „es wird weniger". Nach Ablauf übernimmt doch
   noch der laufende Streifen — die Schätzung ist dann aufgebraucht, aber die Arbeit läuft. */
.public-page .public-wait-bar {
    position: relative; height: 3px; background: #dcdfe3; overflow: hidden; margin-bottom: 14px;
}
.public-page .public-wait-bar span,
.public-page .public-wait-bar::after {
    position: absolute; top: 0; left: 0; height: 100%; background: var(--jb-ink);
}
.public-page .public-wait-bar span {
    width: 100%; transform-origin: left;
    animation: public-wait-schrumpfen 20s linear forwards;
}
.public-page .public-wait-bar::after {
    content: ""; width: 35%; opacity: 0;
    animation: public-wait-lauf 1.4s ease-in-out 20s infinite,
               public-wait-einblenden .3s linear 20s forwards;
}

@keyframes public-wait-schrumpfen {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
}
@keyframes public-wait-lauf {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(285%); }
}
@keyframes public-wait-einblenden {
    to { opacity: 1; }
}

/* --- Der Zähler ---

   Die Ziffern 10…0 stehen untereinander; sichtbar ist immer genau eine. Der Streifen wird mit
   steps(20) je Sekunde um eine Zeile weitergeschoben.

   ⚠️ Die Zeilenhöhe muss überall dieselbe Zahl sein — Zeile, Fensterhöhe und Verschiebung
   hängen aneinander. In em gerechnet käme je nach Schriftgrösse ein Bruchteil heraus, und der
   Zähler stünde dauerhaft zwischen zwei Ziffern. */
.public-page .public-wait-uhr {
    height: 30px; overflow: hidden; flex: none;
    font-size: 1.6rem; font-weight: 300; line-height: 30px;
    font-variant-numeric: tabular-nums; color: var(--jb-ink);
    /* Bei null verschwindet der Zähler. Eine stehengebliebene Null sagt nichts mehr — was
       dann gilt, steht im Hinweis darunter, und der erscheint im selben Augenblick. */
    animation: public-wait-ausblenden .4s ease 20s forwards;
}
@keyframes public-wait-ausblenden {
    to { opacity: 0; }
}
.public-page .public-wait-uhr > div {
    animation: public-wait-ticken 20s steps(20) forwards;
}
.public-page .public-wait-uhr span { display: block; height: 30px; text-align: right; }

@keyframes public-wait-ticken {
    to { transform: translateY(-600px); }   /* 20 Schritte à 30 px */
}

/* Erscheint von allein nach zwanzig Sekunden — also genau dann, wenn das Warten auffällig wird.

   ⚠️ Der Selektor muss das p mitnennen: .public-page .public-wait p (0,2,1) ist spezifischer
   als .public-page .public-wait-hint (0,2,0) und setzte den Abstand wieder auf null. Der
   Hinweis klebte dann an der Zeile darüber — derselbe Fallstrick wie beim Einwilligungsfeld. */
.public-page .public-wait p.public-wait-hint {
    margin-top: 12px; opacity: 0;
    animation: public-wait-hinweis .4s ease-out 20s forwards;
}

@keyframes public-wait-hinweis {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

/* Wer bewegte Oberflächen abgeschaltet hat, behält den schrumpfenden Balken und den Zähler:
   Beide tragen eine Auskunft — wie lange es noch dauert —, und dafür ist die Einstellung nicht
   gedacht. Weg fällt allein der endlos hin- und herlaufende Streifen danach; an seine Stelle
   tritt ein ruhiges Pulsieren. Gar nichts wäre falsch: Ein stehender leerer Balken sähe aus wie
   eine hängende Seite. */
@media (prefers-reduced-motion: reduce) {
    /* ⚠️ Ohne das Einblenden daneben: Beide würden die Deckkraft setzen, und die in der Liste
       spätere gewinnt — das Pulsieren stünde still auf voller Deckkraft. Nötig ist es hier
       ohnehin nicht, denn vor Ablauf der zwanzig Sekunden gilt die Grundeinstellung 0. */
    .public-page .public-wait-bar::after {
        width: 100%;
        animation: public-wait-puls 2s ease-in-out 20s infinite;
    }

    @keyframes public-wait-puls {
        0%, 100% { opacity: .2; }
        50%      { opacity: .6; }
    }
}

.public-page .code-display {
    font-size: 2.2rem; font-weight: 600; letter-spacing: .3rem; text-align: center;
    padding: 18px; background: var(--jb-flat); border-radius: 0;
    font-variant-numeric: tabular-nums; color: var(--jb-ink);
}

.public-footer { padding-top: 18px; padding-bottom: 18px; font-size: .8rem; color: #6a707b; }

/* --- Anmeldung --- */

.plain-shell { min-height: 100vh; }

.auth-page { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 2rem 1rem; }
.auth-card { width: 100%; max-width: 400px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1.75rem; }
.auth-head { text-align: center; margin-bottom: 1.5rem; }
.auth-head .brand-mark { display: inline-block; margin-bottom: .75rem; }
.auth-head h1 { margin-bottom: .25rem; }
.auth-head .subtitle { color: var(--ink-soft); font-size: .85rem; }
.auth-submit { width: 100%; justify-content: center; margin-top: .5rem; }
.auth-hint { margin: 1.25rem 0 0; text-align: center; font-size: .8rem; color: var(--ink-soft); }

.auth-card .input { width: 100%; }

/* --- Benutzermenü rechts oben ---

   Frei über dem Seitenkopf statt in dessen Fluss: So steht es auf jeder Seite an derselben
   Stelle, ohne dass die Seiten es selbst einbauen müssen. .page-head hält den Platz frei,
   damit die Seitenschaltflächen links daneben landen statt darunter. */

.topbar { position: absolute; top: 1.5rem; right: 2rem; z-index: 30; }
.content { position: relative; }
.page-head { padding-right: 13rem; }

.user-menu { position: relative; }

.user-menu-trigger {
    display: flex; align-items: center; gap: .4rem; cursor: pointer;
    padding: .3rem .6rem; border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--surface); font-size: .82rem; max-width: 12rem;
    list-style: none; user-select: none;
}
.user-menu-trigger::-webkit-details-marker { display: none; }
.user-menu-trigger:hover { background: var(--surface-alt); }
.user-menu[open] .user-menu-trigger { border-color: var(--accent); }

.user-menu-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.user-menu-caret { color: var(--ink-soft); font-size: .7rem; flex: 0 0 auto; }
.user-menu[open] .user-menu-caret { transform: rotate(180deg); }

.user-menu-panel {
    position: absolute; right: 0; top: calc(100% + .35rem); min-width: 15rem;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 4px 16px rgba(0, 0, 0, .18); padding: .35rem 0; z-index: 40;
}

.user-menu-head { padding: .5rem .85rem .6rem; border-bottom: 1px solid var(--line); margin-bottom: .35rem; }
.user-menu-head strong { display: block; font-size: .85rem; }
.user-menu-head small { color: var(--ink-soft); font-size: .72rem; }

.user-menu-group { padding-bottom: .35rem; }
.user-menu-group form { margin: 0; }
.user-menu-title {
    padding: .3rem .85rem .15rem; font-size: .68rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft);
}

.user-menu-item {
    display: flex; align-items: center; gap: .5rem; width: 100%;
    padding: .4rem .85rem; border: none; background: none; cursor: pointer;
    font: inherit; font-size: .84rem; color: var(--ink); text-align: left;
}
.user-menu-item:hover { background: var(--surface-alt); text-decoration: none; }
.user-menu-item.selected { font-weight: 600; color: var(--accent-text); }
.user-menu-check { width: .8rem; flex: 0 0 .8rem; color: var(--accent-text); font-size: .75rem; }
.user-menu-logout { color: var(--danger-text); }

.user-menu-separator { height: 1px; background: var(--line); margin: .35rem 0; }

/* --- Fehleranzeige von Blazor --- */

#blazor-error-ui {
    background: var(--alert-warning-bg); color: var(--badge-warning-ink); bottom: 0; display: none;
    left: 0; padding: .8rem 1.2rem; position: fixed; width: 100%; z-index: 1000;
    box-shadow: 0 -1px 4px rgba(0, 0, 0, .1);
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 1rem; top: .8rem; }

@media (max-width: 900px) {
    .app-shell { flex-direction: column; }
    .sidebar { width: 100%; flex: none; height: auto; position: static; }
    .nav-sections { display: flex; flex-wrap: wrap; gap: .5rem; }
    .content { padding: 1rem; }

    /* Auf schmalen Geräten reicht die Breite nicht für beides nebeneinander —
       dann steht das Menü über dem Seitenkopf statt daneben. */
    .topbar { position: static; display: flex; justify-content: flex-end; margin-bottom: .75rem; }
    .page-head { padding-right: 0; }
}
