/* BOBcheck – App-Shell und Bildschirme auf Basis des Industry-Systems.
   Alle Werte kommen aus den Tokens in industry.css. */

[hidden] { display: none !important; }
/* Einzige Farbe neben dem Stahlblau: das Gelb der 1. Klasse am Wagenteil A2. */
:root { --color-first-class: #e3b505; }
/* Hoehe der Leiste unten (ohne Trennlinie und Rand fuer die iPhone-Leiste) –
   die Hinweise nehmen dieselbe Flaeche ein. */
:root { --fuss-hoehe: 58px; }
html { height: 100%; -webkit-text-size-adjust: 100%; }
body { min-height: 100%; background: var(--color-bg); }
@media (min-width: 760px) { body { background: var(--color-neutral-200); } }

/* — Shell — */
.shell {
  display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh;
  width: 100%; max-width: 720px; margin: 0 auto; background: var(--color-bg);
}
@media (min-width: 760px) {
  .shell { border-left: 1px solid var(--color-divider); border-right: 1px solid var(--color-divider); }
}
.statusline {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 8px 16px 2px; font-size: 11px; color: var(--color-neutral-700);
  font-variant-numeric: tabular-nums;
}
.statusline span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Der Programmstand gehört zum Namen, tritt aber zurück – er beantwortet nur die
   Frage „welcher Stand läuft hier gerade?“. */
.statusline-version { color: var(--color-neutral-500); font-size: 10px; }
/* Oben rechts nur, wer angemeldet ist – und der Weg hinaus. */
.statusline-konto { display: flex; align-items: center; gap: 8px; }
.statusline-konto form { display: flex; }
/* Vertretung: Wer die App als jemand anderes sieht, soll es nicht vergessen
   koennen – dieselbe Signalfarbe wie die Marke „neu“, aber als Umriss: ein
   Zustand, keine Neuigkeit. */
.statusline-vertretung {
  border: 1px solid var(--color-signal); border-radius: 2px;
  padding: 1px 6px; color: var(--color-signal); font-weight: 600;
}
.statusline-abmelden {
  border: 0; background: none; padding: 0; font: inherit; color: var(--color-accent);
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.header {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--color-divider);
  position: sticky; top: 0; background: var(--color-bg); z-index: 5;
}
.header-text { flex: 1; min-width: 0; }
.header-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 21px; line-height: 1.1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.main { flex: 1; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); }

/* — Fuss: Leiste und Hinweise —
   Der Fuss klebt unten; in ihm liegen die Leiste und, fuer einen Moment,
   die Hinweise genau ueber ihr. */
.fuss { position: sticky; bottom: 0; z-index: 5; }
.tabbar {
  display: flex; border-top: 1px solid var(--color-divider);
  background: var(--color-bg); padding-bottom: env(safe-area-inset-bottom);
}
.tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 0; padding: 9px 2px 11px; min-height: var(--fuss-hoehe); color: var(--color-neutral-700);
  text-decoration: none; font-family: var(--font-body); font-size: 10px; background: transparent; cursor: pointer;
}
.tab:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.tab[aria-current="page"] { color: var(--color-accent); }

/* — Anmeldung / Installer — */
.auth-shell {
  padding: var(--space-8) var(--space-6); display: flex; flex-direction: column; gap: var(--space-6);
  min-height: 100vh; min-height: 100dvh; width: 100%; max-width: 440px; margin: 0 auto; background: var(--color-bg);
}
.auth-shell.is-wide { max-width: 640px; }
.auth-logo { width: 100%; max-width: 420px; height: auto; margin-top: var(--space-8); }

/* — Intro der Anmeldeseite —
   Ein Bildstreifen im Format 5:4: fahrender Zug, Schwenk auf die Seite mit dem
   Logo, Zoom darauf. Das letzte Filmbild ist das Logo auf dem Seitenhintergrund,
   dort uebernimmt das Standbild – der Rahmen bleibt danach stehen.
   Ohne Film ist .logo-buehne nur ein Rahmen um das Bild. */
.logo-buehne { position: relative; width: 100%; max-width: 420px; margin: var(--space-8) auto 0; }
.logo-buehne .auth-logo { display: block; margin: 0; }
/* Bildformat 5:4 – 4/5 = 80 % der Breite. Oben etwas weniger Luft als sonst,
   sonst steht die Seite leer. */
.logo-buehne.hat-intro { height: 0; padding-top: 80%; overflow: hidden; margin-top: var(--space-4); }
.logo-buehne.hat-intro .auth-logo {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain;
  animation: intro-standbild 120ms linear 2300ms both;
}
.intro-film {
  position: absolute; inset: 0; pointer-events: none;
  background-image: var(--film); background-repeat: no-repeat;
  background-size: 100% calc(var(--bilder, 30) * 100%);
  animation: intro-film 2400ms steps(30, jump-none) both,
             intro-ende 120ms linear 2300ms both;
}
@keyframes intro-film { from { background-position: 0 0; } to { background-position: 0 100%; } }
@keyframes intro-ende { to { opacity: 0; } }
@keyframes intro-standbild { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .logo-buehne.hat-intro { height: auto; padding-top: 0; animation: none; }
  .logo-buehne.hat-intro .auth-logo { position: static; height: auto; animation: none; }
  .intro-film { display: none; }
}
.auth-shell h3 { margin: 0; }
.auth-foot { margin-top: auto; font-size: 11px; color: var(--color-neutral-600); text-align: center; padding-top: var(--space-6); }

/* — Bausteine — */
.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.stack-3 { display: flex; flex-direction: column; gap: var(--space-3); }
.stack-2 { display: flex; flex-direction: column; gap: var(--space-2); }
.row { display: flex; align-items: center; gap: 8px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.row-baseline { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.wrap { display: flex; flex-wrap: wrap; gap: 6px; }
.wrap-8 { display: flex; flex-wrap: wrap; gap: 8px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.grid-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.grow { flex: 1; min-width: 0; }
.muted { color: var(--color-neutral-700); }
.faint { color: var(--color-neutral-600); }
/* Der Wochentag sagt schneller als das Datum, wann etwas ansteht – er steht
   vorn und bleibt auch in gedaempftem Text lesbar. */
.wochentag { font-weight: 600; color: var(--color-text); }
.card-kicker .wochentag, .tag .wochentag { font-weight: 700; color: inherit; }
.small { font-size: 12px; }
.tiny { font-size: 11px; }
.text-13 { font-size: 13px; }
.mono { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; color: var(--color-accent-700); }
.mono-12 { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; color: var(--color-accent-700); }
.mono-10 { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 10px; color: var(--color-accent-700); }
.num { font-variant-numeric: tabular-nums; }
.right { text-align: right; }
.center { text-align: center; }
.h-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
.title-20 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 20px; line-height: 1.15; }
.title-19 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 19px; line-height: 1.15; }
.title-18 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 18px; line-height: 1.15; }
.kpi { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 38px; line-height: 1; }
.section-title { margin: 0 0 8px; display: flex; align-items: center; gap: 8px; }
/* Marke fuer Handlungsbedarf: an einer Ueberschrift und an der Leiste unten. */
.badge {
  display: inline-grid; place-items: center; min-width: 20px; height: 18px; padding: 0 5px;
  background: var(--color-signal); color: #fff; line-height: 1;
  font-family: var(--font-body); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.tab { position: relative; }
.tab .badge { position: absolute; top: 4px; left: calc(50% + 3px); min-width: 16px; height: 16px; padding: 0 4px; font-size: 10px; }
.icon { display: inline-block; vertical-align: middle; flex: none; }
.icon-accent { color: var(--color-signal); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
a.card, a.btn { text-decoration: none; }
a.card { color: inherit; }
.card.is-link { cursor: pointer; }
.card.is-link:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }
.btn { -webkit-tap-highlight-color: transparent; }
.btn-lg { min-height: 48px; }
.btn-md { min-height: 44px; }
.btn-sq { min-height: 44px; min-width: 44px; padding: 0; }
.btn-primary .icon { color: inherit; }
.btn.is-active, .chip.is-active { border-color: var(--color-accent); background: var(--color-accent); color: var(--color-bg); }
.btn-block + .btn-block { margin-top: 0; }
.input { min-height: 44px; }
.field-error { font-size: 12px; color: var(--color-signal-800); margin-top: 5px; }
.input.is-invalid { border-color: var(--color-signal-700); }
.form-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }
.form-row { display: flex; gap: 8px; }
.form-row > .field { flex: 1; }
.form-row > .field.w-96 { flex: 0 0 96px; }
.form-row > .field.w-80 { flex: 0 0 80px; }   /* Anrede neben zwei Namensfeldern */
.notice {
  font-size: 12px; color: var(--color-neutral-700); padding: 10px; border: 1px dashed var(--color-divider); line-height: 1.45;
}
.notice-strong { font-size: 13px; padding: 10px 12px; border: 1px solid var(--color-divider); border-left: 3px solid var(--color-signal); line-height: 1.45; }
.notice-error { font-size: 13px; padding: 10px 12px; border: 1px solid var(--color-signal-300); border-left: 3px solid var(--color-signal-700); color: var(--color-signal-900); background: var(--color-signal-100); line-height: 1.45; }

/* — Kacheln (Dashboard) — */
.tile {
  flex-direction: column; align-items: flex-start; gap: 8px; padding: var(--space-4);
  min-height: 96px; text-align: left; justify-content: flex-start;
}
.tile .icon { color: var(--color-accent); }
.tile-label { font-size: 14px; }
.tile-hint { font-family: var(--font-body); font-size: 11px; font-weight: 400; color: var(--color-neutral-700); }

/* — Listen in Blueprint-Boxen — */
.list { display: flex; flex-direction: column; }
.list-row {
  display: flex; align-items: center; gap: 12px; width: 100%; border: 0; border-bottom: 1px solid var(--color-divider);
  justify-content: flex-start; padding: 14px; min-height: 54px; text-align: left; background: transparent;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; color: var(--color-text);
  text-decoration: none; cursor: pointer;
}
.list .list-row:last-child { border-bottom: 0; }
.list-row:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.list-row .icon { color: var(--color-accent); }
.list-row .hint { margin-left: auto; font-family: var(--font-body); font-size: 11px; font-weight: 400; color: var(--color-neutral-700); white-space: nowrap; }
.list-row.is-static { cursor: default; }
.list-row.is-static:hover { background: transparent; }
.place-row { min-height: 56px; padding: 12px; gap: 10px; font-family: var(--font-body); font-weight: 400; font-size: 13px; }
.place-row .place-motif { font-size: 11px; color: var(--color-neutral-700); text-align: right; max-width: 110px; }
.report-row { min-height: 52px; padding: 12px; gap: 10px; font-family: var(--font-body); font-weight: 400; font-size: 13px; border: 1px solid var(--color-divider); }
/* Erfassen, Schritt 2: je Objekt eine Karte, darunter die Stellen, an denen es
   sitzt. Gemeldet wird das Objekt – der Wagen ist nur die Ortsangabe.
   Angekreuzt wird wie im Warenkorb, quer über alle Karten. */
.stelle-gruppe { gap: 10px; }
.stelle-orte { display: flex; flex-direction: column; gap: 6px; }
.stelle-ort {
  display: flex; align-items: center; min-height: 46px; gap: 8px; padding: 8px 10px;
  border: 1px solid var(--color-divider); background: var(--color-bg); cursor: pointer;
  font-family: var(--font-body); font-weight: 400; font-size: 13px; text-align: left;
}
.stelle-ort input[type=checkbox] { width: 20px; height: 20px; flex: none; accent-color: var(--color-accent); margin: 0; }
.stelle-ort .tag { flex: none; }
.stelle-ort.is-first-class { box-shadow: inset 3px 0 0 var(--color-first-class); }
.stelle-ort:has(input:checked) { border-color: var(--color-accent); background: var(--color-accent-100); }
.stelle-ort:focus-within { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.stelle-alle {
  display: flex; align-items: center; gap: 6px; flex: none; cursor: pointer;
  font-family: var(--font-body); font-weight: 400; font-size: 12px; color: var(--color-neutral-700);
}
.stelle-alle input { width: 18px; height: 18px; accent-color: var(--color-accent); margin: 0; }
/* Selten gebrauchte Felder klappen zu – das Wartungsintervall ist die Ausnahme,
   nicht die Regel, und soll das Formular nicht dominieren. */
.feld-gruppe { border: 1px solid var(--color-divider); padding: 8px 10px; }
.feld-gruppe > summary { cursor: pointer; font-size: 13px; color: var(--color-neutral-800); }
.feld-gruppe[open] > summary { margin-bottom: 8px; }
/* Schritt 3: je Objekt eine Karte mit seinen Stellen und seinem Grund. */
.korb-posten { gap: 10px; }
/* Was schon offen steht, laesst sich nicht noch einmal melden – die Zeile fuehrt
   stattdessen zur bestehenden Meldung. */
.stelle-ort.is-offen {
  color: var(--color-neutral-700); background: var(--color-neutral-100);
  border-style: dashed; text-decoration: none; cursor: pointer;
}
.stelle-ort.is-offen .tag { opacity: .7; }
/* Meldungskarte: Der Link deckt die ganze Karte, liegt aber unter den Knoepfen
   darin – so oeffnet ein Tipp irgendwo die Meldung, ein Tipp aufs Foto dagegen
   das Bild. */
.karte-flaeche { position: relative; }
.karten-link { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.karte-flaeche .thumb-knopf { position: relative; z-index: 2; }
/* Die Kennzeile der Meldungskarte liest sich in Schwarz wie der uebrige Text:
   Nummer, Ort und Tag sind Angaben, kein Signal. Rot bleibt der Marke „neu“
   vorbehalten – in einer roten Zeile ginge sie unter. Die Terminkarten
   behalten ihr Rot, deshalb steht die Regel hier und nicht an .card-kicker. */
.karte-flaeche .card-kicker { color: var(--color-text); }
/* Das Foto zur Meldung ist so groß wie die Objektvorschau daneben – zwei
   Bilder in einer Zeile sollen gleich viel wiegen. Es zeigt den Bildausschnitt
   statt der ganzen Aufnahme; in dieser Größe erkennt man davon mehr. Doppelte
   Klasse, damit .thumb weiter unten nicht gewinnt. */
.thumb.thumb-mini { width: 52px; height: 52px; object-fit: cover; background: none; }
/* „neu“: noch nie vor Augen gehabt – auffällig, aber nicht laut.
   Die Marke vergeht, nachdem sie tatsächlich zu sehen war: Das Skript setzt
   `.geht`, sobald die Zeile im Bild steht und ein paar Sekunden vergangen
   sind. So wird das Verschwinden bemerkt und verstanden – die Meldung gilt ab
   jetzt als gesehen. Ohne Skript läuft dieselbe Bewegung zeitgesteuert.
   Erst verblasst die Marke, dann räumt sie ihren Platz. */
/* Dieselbe Marke wie unten an der Leiste, nur mit Wort statt Zahl – wer sie
   dort kennt, erkennt sie hier wieder. Sie steht am Ende der Zeile, die die
   Nummer traegt: hinter den Kenndaten, nicht zwischen ihnen. */
.badge-neu {
  vertical-align: baseline; letter-spacing: .04em; text-transform: none;
  overflow: hidden; white-space: nowrap; max-width: 6em;
}
.badge-neu.geht { animation: neu-vergeht 1400ms both; }
html.no-js .badge-neu { animation: neu-vergeht 1400ms 4s both; }
/* Erst hüpfen – das zieht den Blick hin –, dann verblassen und den Platz
   räumen. Wer hinsieht, sieht das Ende der Neuigkeit. */
@keyframes neu-vergeht {
  0%   { transform: scale(1); opacity: 1; max-width: 6em; }
  10%  { transform: scale(1.25) translateY(-3px); }
  22%  { transform: scale(.92) translateY(0); }
  32%  { transform: scale(1.1) translateY(-1px); }
  42%  { transform: scale(1); }
  55%  { transform: scale(1); opacity: 1; max-width: 6em; }
  80%  { opacity: 0; transform: scale(.9); max-width: 6em; }
  100% { opacity: 0; max-width: 0; min-width: 0; padding-left: 0; padding-right: 0; margin-right: -4px; }
}
@media (prefers-reduced-motion: reduce) {
  /* Kein Hüpfen – nur verblassen und Platz räumen. */
  @keyframes neu-vergeht {
    0%   { opacity: 1; max-width: 6em; }
    55%  { opacity: 1; max-width: 6em; }
    80%  { opacity: 0; max-width: 6em; }
    100% { opacity: 0; max-width: 0; min-width: 0; padding-left: 0; padding-right: 0; margin-right: -4px; }
  }
}
/* Der Stand steht über dem Foto und ist so breit wie es – zwei Marken
   übereinander, die dieselbe Kante halten. */
.karte-flaeche .status-marke { min-width: 52px; justify-content: center; }
/* In der Fusszeile einer Karte koennen zwei Daten stehen (gemeldet, erledigt).
   Wird es eng, rutscht der Fotohinweis in die naechste Zeile, statt aus der
   Karte zu laufen. */
.card-meta { flex-wrap: wrap; }
.report-row .sub { font-size: 11px; color: var(--color-neutral-700); }
/* Die Zeile fuehrt zur Meldung, die Marke rechts hakt sie ab – als Knopf, der
   wie eine Marke aussieht. */
.report-row > a { color: inherit; text-decoration: none; min-width: 0; }
.tag-knopf { font-family: var(--font-body); font-weight: 400; cursor: pointer; border: 0; background: transparent; gap: 5px; }
.tag-knopf.tag-outline { border: 1px solid var(--color-accent); }
.tag-knopf.tag-neutral { background: var(--color-neutral-100); }
.tag-knopf:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.tag-knopf:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.tag-knopf .icon { width: 13px; height: 13px; }
/* Wartungen ankreuzen – beim Anfragen und im Dialog „Termin ändern“. Die
   ganze Zeile ist der Schalter; erledigte stehen nur zur Auskunft da. */
.wartung-wahl { font-family: var(--font-body); font-weight: 400; font-size: 13px; }
.wartung-wahl input[type=checkbox], .wartung-wahl input[type=radio] { width: 20px; height: 20px; flex: none; accent-color: var(--color-accent); margin: 0; }
.wartung-wahl .tag { flex: none; }
.wartung-wahl.is-static { color: var(--color-neutral-700); }
/* „Rechnung an“: rechts an jeder Wartung, eine Abweichung von der Vorgabe
   farbig hinterlegt – bei der Anfrage, im Dialog „Termin ändern“, an der Meldung. */
.feld-kopf { display: flex !important; justify-content: space-between; gap: 8px; }
.wartung-wahl.mit-rechnung { cursor: default; gap: 10px; }
.wartung-wahl.mit-rechnung > label { cursor: pointer; min-width: 0; }
.rechnung-wahl { flex: none; width: 112px; min-height: 36px; padding: 2px 6px; font-size: 13px; }
.wartung-wahl.is-anders { background: var(--color-accent-2-100); box-shadow: inset 3px 0 0 var(--color-accent-2); }
.wartung-wahl.is-anders .rechnung-wahl { border-color: var(--color-accent-2); color: var(--color-accent-2-800); font-weight: 500; background: var(--color-surface); }
.rechnung-marke { display: inline-block; margin-top: 4px; font-size: 11px; color: var(--color-accent-2-800); background: var(--color-accent-2-100); padding: 1px 6px; border-radius: 3px; }

/* Die letzten Bewegungen des Materialbestands im Objektdialog. */
.bestand-verlauf { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--color-divider); }

/* — Seitenriss — */
/* Seitenriss: Breite fuellen, Hoehe aus dem Seitenverhaeltnis der Datei. Die
   width/height-Angaben am <img> halten den Platz frei, bevor das Bild da ist. */
.side-view { width: 100%; height: auto; display: block; opacity: .9; }
figure.blueprint .side-view { opacity: 1; }

/* — Einfahrt: Kamerafahrt vom Fuehrerstand in die Seitenansicht —
   Die Bilder stammen aus dem 3D-Modell und liegen als senkrechter Streifen in
   einer Datei; abgespielt wird er, indem der Bildausschnitt in festen Schritten
   nach unten wandert. Das letzte Bild ist die Seitenansicht selbst, danach
   verschwindet der Streifen und das Standbild darunter bleibt stehen – das ist
   zugleich die Fassung fuer Drucken und fuer "weniger Bewegung".
   Der Rahmen behaelt die Masse des Standbilds. */
.zug-rahmen { display: block; position: relative; }
.zug-film {
  position: absolute; inset: 0; pointer-events: none;
  background-image: var(--film); background-repeat: no-repeat;
  background-size: 100% calc(var(--bilder, 24) * 100%);
  animation: zug-film 1250ms steps(24, jump-none) both,
             zug-film-ende 200ms linear both;
  animation-delay: calc(var(--i, 0) * 90ms), calc(1200ms + var(--i, 0) * 90ms);
}
@keyframes zug-film {
  from { background-position: 0 0; }
  to   { background-position: 0 100%; }
}
@keyframes zug-film-ende {
  to { opacity: 0; }
}
/* Solange die Fahrt laeuft, bleibt das Standbild unsichtbar – sonst stuende der
   ganze Zug hinter der Nahaufnahme. Am Ende der Fahrt tritt es an ihre Stelle. */
/* Das letzte Filmbild und das Standbild zeigen dieselbe Einstellung, nur in
   unterschiedlicher Aufloesung. Sie wechseln deshalb ueberblendet – hart
   geschnitten wuerde man das Nachschaerfen als Sprung sehen. */
.zug-rahmen.hat-film .side-view {
  animation: zug-standbild 200ms linear calc(1200ms + var(--i, 0) * 90ms) both;
}
@keyframes zug-standbild {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .zug-film { display: none; }
  .zug-rahmen.hat-film .side-view { animation: none; }
}
@media print {
  .zug-film { display: none; }
  .zug-rahmen.hat-film .side-view { animation: none; opacity: 1; }
}

/* Fotos zu Meldungen: volle Breite, nichts abgeschnitten – und ohne den
   Blaustich der duotone-Klasse: Wer eine Wartung beurteilt, will die Farbe
   sehen, die vor Ort war. */
.photo { display: block; width: 100%; height: auto; max-height: 320px; object-fit: contain; }
/* Das Foto selbst ist der Knopf: antippen zeigt es gross. */
.bild-knopf { display: block; width: 100%; border: 0; padding: 0; background: none; cursor: zoom-in; line-height: 0; }
.bild-knopf:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.photo-placeholder {
  background: repeating-linear-gradient(135deg, var(--color-neutral-200) 0 8px, var(--color-neutral-300) 8px 16px);
  display: grid; place-items: center; height: 190px;
}
.photo-placeholder.is-small { width: 52px; height: 52px; border: 1px solid var(--color-divider); flex: none; }
/* Vorschau antippen: oeffnet das Bild gross. Der Knopf traegt nur das Bild. */
.thumb-knopf { border: 0; padding: 0; background: none; cursor: zoom-in; flex: none; line-height: 0; }
.thumb-knopf:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Wartung bearbeiten: das bisherige Foto klein neben dem Hinweis, dass ein
   neues es ersetzt. */
.foto-bisher { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.bild-dialog { max-width: min(720px, calc(100% - 2 * var(--space-4))); }
.bild-gross {
  display: block; width: 100%; height: auto; max-height: 70vh; object-fit: contain;
  background: repeating-conic-gradient(var(--color-neutral-200) 0% 25%, var(--color-neutral-100) 0% 50%) 0 0 / 18px 18px;
}
/* Platzierungen eines Objekts, nach Konfiguration gebuendelt. Dieselbe
   Platzierung heisst in mehreren Konfigurationen gleich – die Marke davor
   sagt, um welche es geht. */
.platz-gruppen { display: flex; flex-direction: column; gap: 4px; }
.platz-gruppe { display: flex; align-items: baseline; gap: 6px; }
.platz-gruppe > .tag { flex: none; }
.photo-placeholder.is-thumb { width: 52px; height: 52px; flex: none; }
.photo-placeholder span { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; color: var(--color-neutral-800); }
.photo-drop { min-height: 88px; flex-direction: column; gap: 8px; border-style: dashed; cursor: pointer; }
.photo-drop .icon { color: var(--color-accent); }
.photo-preview { height: 150px; display: grid; place-items: center; overflow: hidden; }
.photo-preview img { max-width: 100%; max-height: 150px; object-fit: contain; }
/* Fotos fuellen das Feld, Zeichnungen sollen ganz zu sehen sein – deshalb
   passt sich das Bild ein statt zu beschneiden. */
.thumb { width: 52px; height: 52px; object-fit: contain; border: 1px solid var(--color-divider); flex: none; background: var(--color-neutral-100); }

/* — Wagenteile, Chips, Segmente — */
.wagon-btn { min-height: 44px; min-width: 56px; flex-direction: column; gap: 2px; }
.wagon-btn small { font-family: var(--font-body); font-weight: 400; font-size: 10px; color: var(--color-neutral-700); }
.wagon-btn.is-active small { color: var(--color-bg); }
.wagon-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: 8px; }
/* Beim Erfassen stehen die Wagenteile immer in einer Reihe – der Zug soll als
   Ganzes lesbar bleiben, so wie er auf dem Seitenriss darüber steht. */
.wagon-row { display: flex; gap: 6px; align-items: stretch; }
.wagon-row .wagon-btn { flex: 1 1 0; min-width: 0; padding-left: 2px; padding-right: 2px; }
.wagon-row .wagon-btn small { font-size: 9px; }
/* Erste Klasse: gelbe Umrandung der Fenster am Fahrzeug, hier als Streifen. */
.wagon-btn.is-first-class { box-shadow: inset 0 3px 0 var(--color-first-class); }
.wagon-btn.is-first-class.is-active { box-shadow: inset 0 3px 0 var(--color-first-class); }
.tag-first-class { border: 1px solid var(--color-first-class); color: var(--color-neutral-900); background: color-mix(in srgb, var(--color-first-class) 22%, transparent); }
/* Zurückgenommen: kein Erfolg, aber auch kein Fehler – gestrichelt und blass,
   damit es sich von „erledigt“ unterscheidet. */
.tag-zurueck { border: 1px dashed var(--color-neutral-500); color: var(--color-neutral-700); background: transparent; }
.chip { min-height: 44px; cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.chip:has(input:checked) { border-color: var(--color-accent); background: var(--color-accent); color: var(--color-bg); }
.chip:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.seg-block { display: flex; width: 100%; }
.seg-block .seg-opt { flex: 1; min-height: 44px; justify-content: center; border-top: 0; border-bottom: 0; text-decoration: none; color: inherit; font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; }
.seg-block .seg-opt[aria-current="page"], .seg-block .seg-opt.is-active { background: var(--color-accent); color: var(--color-bg); }
/* Der gewaehlte Filter ist blau wie ein Primaerknopf und verhaelt sich beim
   Ueberfahren auch so: etwas helleres Blau. Die geerbte Regel taeuschte sich
   hier – sie tauscht die Flaeche gegen einen hellen Grauton, weil sie nur
   Segmente mit Radioknopf als „gewaehlt“ erkennt. Die weisse Schrift stand
   dann auf Hellgrau. */
.seg .seg-opt[aria-current="page"]:hover,
.seg .seg-opt.is-active:hover { background: var(--color-accent-600); color: var(--color-bg); }
/* Die Zahl hinter dem Filter tritt zurueck – sie ist Beiwerk zur Beschriftung,
   nicht ihresgleichen. Ziffern in gleicher Breite, damit die Segmente beim
   Wechsel nicht springen. Wird es eng (schmales Geraet, vierstellige Zahlen),
   rutscht die Zahl unter die Beschriftung, statt aus dem Segment zu laufen. */
.seg-block .seg-opt { flex-wrap: wrap; align-content: center; gap: 0 5px; padding-left: 6px; padding-right: 6px; line-height: 1.2; }
.seg-zahl { font-family: var(--font-body); font-weight: 400; font-size: 11px; opacity: .65; font-variant-numeric: tabular-nums; }
/* Termine: vier Staende, einer davon „Abgeschlossen“ – etwas kleiner, damit
   die Leiste auch auf schmalen Geraeten in einer Zeile bleibt. Die rote Marke
   sagt, in welchem Stand eine Neuigkeit wartet. */
.seg-termine .seg-opt { font-size: 13px; padding-left: 4px; padding-right: 4px; }
.seg-neu { min-width: 16px; height: 16px; padding: 0 4px; font-size: 10px; }
/* — Meldungsübersicht in der Menge —
   Offen ist der Arbeitsvorrat (Karten, nach Zug gebündelt), das Archiv eine
   Liste aus Zeilen unter Monatsüberschriften: Eine Karte misst 149 px, eine
   Zeile 56 – bei Hunderten erledigter Wartungen ist das der Unterschied
   zwischen Blättern und Scrollen. */
.gruppe { display: flex; flex-direction: column; gap: var(--space-2); }
.gruppe-kopf { display: flex; align-items: baseline; gap: 8px; }
.gruppe-kopf .zug-name {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px;
  color: var(--color-text); text-decoration: none;
}
.gruppe-kopf .btn-ghost { margin-left: auto; }
.gruppe-kopf .zug { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 13px; color: var(--color-accent-800); text-decoration: none; }
/* Im Archiv steht unter dem Tag je Zug ein Block – die Zwischenzeile bleibt
   schmal, sie ordnet nur ein und soll nicht wie eine zweite Überschrift wirken. */
.untergruppe { display: flex; flex-direction: column; gap: 4px; }
.untergruppe + .untergruppe { margin-top: var(--space-2); }
.untergruppe-kopf { display: flex; align-items: baseline; gap: 8px; padding-left: 2px; }
.untergruppe-kopf .zug {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 13px;
  color: var(--color-accent-800); text-decoration: none;
}
.report-zeile { min-height: 56px; padding: 8px 10px; gap: 10px; font-family: var(--font-body); font-weight: 400; font-size: 13px; }
.report-zeile .tiny { display: block; }
.thumb-klein, .photo-placeholder.thumb-klein { width: 34px; height: 34px; flex: none; border: 1px solid var(--color-divider); object-fit: contain; background: var(--color-neutral-100); }
.zeile-tag { font-size: 11px; color: var(--color-neutral-700); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Zwei Auswahlfelder und ein Knopf – auf schmalen Geräten untereinander. */
.filterzeile { display: flex; flex-wrap: wrap; gap: 8px; }
.filterzeile .input { flex: 1 1 140px; min-width: 0; }
.tabelle-auswertung td, .tabelle-auswertung th { white-space: nowrap; }
.tabelle-auswertung td:first-child, .tabelle-auswertung th:first-child { white-space: normal; min-width: 140px; }

/* Fortschritt eines Rollouts: wie viel der Kampagne erledigt ist. Zwei
   Rechtecke – mehr braucht die Auskunft „25 von 106“ nicht. */
.fortschritt { height: 8px; background: var(--color-neutral-200); border: 1px solid var(--color-divider); }
.fortschritt > span { display: block; height: 100%; background: var(--color-accent); }
.steps { display: flex; gap: 6px; }
.step { flex: 1; height: 4px; background: var(--color-neutral-300); }
.step.is-done { background: var(--color-accent); }
.step-label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-neutral-700); }
.search { position: relative; display: flex; align-items: center; flex: 1; }
/* In einer Reihe soll das Suchfeld die Breite fuellen – deshalb flex: 1. Steht
   es dagegen allein in der Spalte, waere dieselbe Regel eine Falle: Dort zeigt
   die Hauptachse nach unten, und das Feld waechst in die Hoehe, sobald darunter
   wenig steht. Der Abstand zum Rest schwankte damit je nach Inhalt. */
.main > .search { flex: none; }
.search .icon { position: absolute; left: 10px; color: var(--color-neutral-600); pointer-events: none; }
.search .input { padding-left: 32px; min-height: 44px; }

/* — Zeitleiste — */
.timeline { display: flex; flex-direction: column; }
.timeline-item { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--color-divider); }
.timeline-dot { width: 6px; height: 6px; background: var(--color-signal); margin-top: 7px; flex: none; }
.timeline-what { font-size: 13px; }
.timeline-who { font-size: 11px; color: var(--color-neutral-700); }

/* — Konto — */
.avatar {
  width: 44px; height: 44px; background: var(--color-accent); color: var(--color-bg); display: grid; place-items: center;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; flex: none;
}

/* — Toast —
   Ein Hinweis deckt fuer einen Moment genau die Leiste unten ab: gleich
   breit, gleich hoch, samt Trennlinie und Rand fuer die iPhone-Leiste. Ueber
   den Bedienelementen der Seite schwebte er im Weg. Die Flaeche bleibt
   dunkelblau, der Rahmen ist das Rot der Marken. Bis zu drei Zeilen passen
   in die Flaeche; erst ein noch laengerer Text waechst nach oben, statt
   abgeschnitten zu werden. Mehrere Hinweise kommen nacheinander (app.js);
   ein Tipp blendet den aktuellen aus. */
.toast {
  position: absolute; left: 0; right: 0; bottom: 0; min-height: 100%; z-index: 1;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 3px 14px calc(3px + env(safe-area-inset-bottom));
  background: var(--color-accent-900); color: var(--color-bg); border: 2px solid var(--color-signal);
  font-size: 13px; line-height: 1.25; cursor: pointer; transition: opacity 160ms;
}
.toast.is-hidden { opacity: 0; pointer-events: none; }
.toast.is-wartend { display: none; }
/* Ohne Leiste (Anmeldung, Installer): dieselbe Flaeche am unteren Rand, so
   breit wie die Seite. */
.toast.is-low {
  position: fixed; left: 50%; right: auto; transform: translateX(-50%); width: min(100%, 440px);
  min-height: calc(var(--fuss-hoehe) + 1px + env(safe-area-inset-bottom)); z-index: 20;
}
/* Ohne Skript verschwindet ein Hinweis von selbst – sonst laege er auf Dauer
   ueber der Leiste. */
html.no-js .toast { animation: toast-weg 1ms 4s forwards; }
@keyframes toast-weg { to { opacity: 0; visibility: hidden; pointer-events: none; } }

/* — Dialog (natives <dialog>) — */
dialog.dialog { border: 1px solid var(--color-divider); max-width: min(440px, calc(100% - 2 * var(--space-4))); width: 100%; margin: auto; background: var(--color-bg); color: var(--color-text); }
dialog.dialog:not([open]) { display: none; }
dialog.dialog::backdrop { background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent); }
dialog .dialog-actions .btn { min-height: 44px; }

/* — Tabellen — */
.table-wrap { overflow-x: auto; }
.table td.k { color: var(--color-neutral-700); }
.table td.mono { white-space: nowrap; }
.table td.v { text-align: right; font-variant-numeric: tabular-nums; }
.table td.num, .table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.table .input { min-height: 36px; width: 64px; text-align: right; padding: 4px 8px; }
.table-compact td, .table-compact th { padding: var(--space-2) var(--space-1); }

/* — Hilfe (Markdown) — */
.prose { font-size: 15px; line-height: 1.55; }
.prose h1 { font-size: 25px; margin: 0 0 var(--space-3); }
.prose h2 { font-size: 20px; margin: var(--space-6) 0 var(--space-2); }
.prose h3 { font-size: 17px; margin: var(--space-4) 0 var(--space-2); }
.prose p { margin: 0 0 var(--space-3); }
.prose ul, .prose ol { margin: 0 0 var(--space-3); padding-left: 22px; }
.prose li { margin-bottom: 4px; }
.prose code { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 13px; color: var(--color-accent-700); background: var(--color-surface); padding: 1px 4px; }
.prose pre { background: var(--color-surface); border: 1px solid var(--color-divider); padding: var(--space-3); overflow-x: auto; font-size: 12px; line-height: 1.45; margin: 0 0 var(--space-3); }
.prose pre code { background: transparent; padding: 0; color: inherit; }
.prose blockquote { margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3); border-left: 3px solid var(--color-accent); color: var(--color-neutral-800); font-size: 14px; }
.prose table { width: 100%; border-collapse: collapse; font-size: 13px; margin: 0 0 var(--space-3); }
.prose th { text-align: left; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-neutral-700); padding: var(--space-2); border-bottom: 1px solid var(--color-divider); }
.prose td { padding: var(--space-2); border-bottom: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent); vertical-align: top; }
.prose hr { height: 1px; border: 0; background: var(--color-divider); margin: var(--space-4) 0; }
.prose img { border: 1px solid var(--color-divider); }
.prose a { color: var(--color-accent-700); }
.prose .tag { vertical-align: middle; }

/* — Diverses — */
.log-box { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; background: var(--color-surface); border: 1px solid var(--color-divider); padding: var(--space-3); max-height: 320px; overflow: auto; margin: 0; }
.req-list { display: flex; flex-direction: column; }
.req-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--color-divider); font-size: 13px; }
.req-row:last-child { border-bottom: 0; }
.req-row .icon { color: var(--color-accent); }
.req-row.is-bad .icon { color: var(--color-signal-700); }
.req-row .hint { margin-left: auto; font-size: 11px; color: var(--color-neutral-700); text-align: right; }
.no-js-only { display: none; }
.no-js .no-js-only { display: block; }
.no-js .js-only { display: none; }
@media print { .tabbar, .toast, .header .btn, .statusline { display: none !important; } .shell { max-width: none; } }

/* — Vorschlagsfeld (Zugsuche) — */
.combo { position: relative; }
.combo-list {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0;
  margin: 0; padding: 0; list-style: none; background: var(--color-bg);
  max-height: 320px; overflow-y: auto; box-shadow: var(--shadow-md);
}
.combo-list li + li { border-top: 1px solid var(--color-divider); }
.combo-list.is-stale { opacity: .45; pointer-events: none; }
.combo-link {
  display: flex; flex-direction: column; gap: 2px; justify-content: center;
  padding: 9px 12px; min-height: 44px; text-decoration: none; color: inherit;
}
.combo-link:hover, .combo-link.is-active { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.combo-name { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px; }
.combo-meta { font-size: 11px; color: var(--color-neutral-700); }

/* — Wartungsfenster — */
.window-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.window-trains { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; line-height: 1.2; }
.window-item { display: flex; gap: 8px; padding: 6px 0; border-top: 1px solid var(--color-divider); font-size: 13px; }
.window-item .zug { font-family: var(--font-heading); font-weight: var(--font-heading-weight); min-width: 92px; }

/* — Merkzettel (zugeordnete Platzierungen an einem Objekt) — */
.chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 34px; padding: 4px 0; }
.chips:empty::before { content: "noch keine"; font-size: 12px; color: var(--color-neutral-600); }
.chip-tag {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 10px;
  border: 1px solid var(--color-divider); background: var(--color-accent-100); font-size: 12px;
}
.chip-x {
  border: 0; background: transparent; cursor: pointer; font-size: 16px; line-height: 1;
  padding: 0 2px; color: var(--color-accent-800);
}
.chip-x:hover { color: var(--color-accent-900); }

/* — Abrechnung: der Wochenbeleg — */
.beleg-termin { padding: 8px 0; border-top: 1px solid var(--color-divider); }
.beleg-termin:first-child { border-top: 0; padding-top: 0; }
.beleg-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.beleg-kopf a { color: inherit; text-decoration: none; font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; min-width: 0; }
.beleg-wartung { font-size: 12px; line-height: 1.45; padding-left: 12px; text-indent: -12px; overflow-wrap: anywhere; }
.beleg-wartung::before { content: "–\00a0\00a0"; color: var(--color-neutral-600); }
.beleg-zeile { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.beleg-zeile > a { flex: 1; min-width: 0; color: inherit; text-decoration: none; font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; padding-left: 12px; text-indent: -12px; }
.beleg-zeile > a::before { content: "–\00a0\00a0"; color: var(--color-neutral-600); }
.beleg-zeit { display: inline-flex; align-items: center; gap: 4px; flex: none; font-size: 11px; color: var(--color-neutral-700); }
.beleg-zeit .input { width: 60px; padding: 4px 6px; font-size: 13px; text-align: right; }
/* „Std.“ und „€“ gleich breit – so stehen Zeit- und Preisfelder untereinander. */
.beleg-zeit > span { min-width: 24px; }
.beleg-material { font-size: 12px; color: var(--color-neutral-700); padding-left: 12px; }
.beleg-text { font-size: 11px; line-height: 1.35; color: var(--color-neutral-600); margin-top: 2px; padding-left: 12px; }
.beleg-zeile.beleg-material > span:first-child { flex: 1; min-width: 0; }
.beleg-hinweis { color: var(--color-signal-700); }
.beleg-summe { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; padding-top: 8px; border-top: 1px solid var(--color-divider); font-size: 13px; }
.beleg-json { margin: 0; max-height: 420px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; line-height: 1.4; }
/* Eine Wartung in den Beleg eines anderen Kunden schieben: Das Symbol klappt
   „Rechnung an“ auf – ohne Skript, ueber das unsichtbare Kaestchen davor. */
.beleg-zeile { position: relative; flex-wrap: wrap; }
.beleg-zeile > .umschalter { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.beleg-empf-knopf { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 40px; color: var(--color-neutral-600); border: 1px solid transparent; border-radius: var(--radius-md); cursor: pointer; }
.beleg-empf-knopf:hover { color: var(--color-accent-2-800); }
.umschalter:checked + .beleg-empf-knopf { color: var(--color-accent-2-800); background: var(--color-accent-2-100); border-color: var(--color-accent-2-300); }
.umschalter:focus-visible + .beleg-empf-knopf { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.beleg-empf-platz { visibility: hidden; cursor: default; }
.beleg-umstellen { display: none; flex: 0 0 100%; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin: 2px 0 6px; padding: 8px 10px; background: var(--color-accent-2-100); border-left: 3px solid var(--color-accent-2); font-size: 12px; }
.umschalter:checked ~ .beleg-umstellen { display: flex; }
.beleg-umstellen .input { width: auto; min-width: 140px; min-height: 36px; padding: 2px 8px; font-size: 13px; background: var(--color-surface); }
/* Die Rechnungsempfaenger in den Einstellungen */
.empf-zeile { align-items: flex-start; flex-wrap: wrap; gap: 8px; padding: 12px; font-family: var(--font-body); font-weight: 400; font-size: 13px; cursor: default; }
.empf-zeile:hover { background: transparent; }
.empf-zeile .form-row { width: 100%; }
.empf-zeile .field > label { margin-bottom: 3px; }

/* — Übersicht (seit 2.69.0) —
   Begruessung, Woche, Kapazitaet, Kennzahl mit Zeitraum, Neuigkeiten. Alles
   Linienzeichnung im Stahlblau; Rot nur fuer Neues, Ueberschreitungen und
   offen Gebliebenes. Entwurf: docs/konzept/dashboard.md. */
.kopf { display: flex; align-items: baseline; gap: 8px; margin: 0 0 8px; }
.kopf h5 { margin: 0; display: flex; align-items: center; gap: 8px; }
.kopf .weg { margin-left: auto; font-size: 12px; color: var(--color-accent); text-decoration: none; }
.kopf .zusatz { font-size: 11px; color: var(--color-neutral-700); }
.weg-zeile { display: block; margin-top: 6px; font-size: 12px; color: var(--color-accent); text-decoration: none; }

/* Die Begruessung: Tafel mit dem Symbol der Tageszeit, deren Toenung durch die
   Stahlblau-Rampe wandert – Zusatzfarben wie im Kundenportal kennt das System
   nicht. Unten faehrt der Seitenriss eines Zuges leise aus dem Bild – als
   stille Linie, ohne Bewegung (so entschieden). */
.gruss { display: grid; grid-template-columns: 54px 1fr; gap: 4px 12px; align-items: center; padding: 14px 14px 12px; overflow: hidden; }
.gruss-tafel {
  grid-row: span 2; width: 54px; height: 54px; display: grid; place-items: center;
  border: 1px solid var(--color-divider); color: var(--color-accent-700); background: var(--gruss-ton, var(--color-accent-100));
}
.gruss-tafel .icon { width: 30px; height: 30px; }
.gruss-satz { margin: 0; font-size: 25px; line-height: 1.08; letter-spacing: -0.01em; }
.gruss-datum { font-size: 11px; color: var(--color-neutral-700); font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.gruss-lage { grid-column: 1 / -1; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--color-divider); font-size: 13px; line-height: 1.4; display: flex; flex-wrap: wrap; gap: 4px 12px; }
.gruss-lage a, .gruss-knapp a { color: var(--color-text); text-decoration: none; display: inline-flex; align-items: center; gap: 5px; }
.gruss-lage a .icon, .gruss-knapp a .icon { color: var(--color-accent); }
.gruss-lage a:hover span, .gruss-knapp a:hover span { text-decoration: underline; text-underline-offset: 2px; }
.gruss-zug { grid-column: 1 / -1; margin: 6px -14px -13px; overflow: hidden; }
.gruss-zug img { width: 112%; max-width: none; height: auto; margin-left: 4%; filter: grayscale(1) contrast(1.05); opacity: .3; }
.gruss.morgens     { --gruss-ton: var(--color-accent-100); }
.gruss.mittags     { --gruss-ton: var(--color-accent-200); }
.gruss.nachmittags { --gruss-ton: var(--color-accent-2-200); }
.gruss.abends      { --gruss-ton: var(--color-accent-2-300); }
.gruss.nachts      { --gruss-ton: var(--color-accent-800); }
.gruss.nachts .gruss-tafel { color: var(--color-bg); }
/* Nach dem ersten Aufruf der Sitzung: nur Datum und Lage. */
.gruss-knapp { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: 12px; color: var(--color-neutral-700); }
.gruss-knapp-datum { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.gruss-knapp-datum .icon { color: var(--color-accent-700); }

/* Kapazitaet eines Zeitfensters: gebucht voll, angefragt schraffiert, was nicht
   mehr hineinpasst rot hinter dem Grenzstrich. */
.kapazitaet { position: relative; height: 10px; margin-top: 8px; background: var(--color-neutral-100); border: 1px solid var(--color-divider); }
.kapazitaet > span { position: absolute; top: 0; bottom: 0; }
.kapazitaet .gebucht { background: var(--color-accent); }
.kapazitaet .angefragt { background: repeating-linear-gradient(135deg, var(--color-accent-500) 0 2px, transparent 2px 5px); box-shadow: inset 0 0 0 1px var(--color-accent-500); }
.kapazitaet .drueber { background: repeating-linear-gradient(135deg, var(--color-signal-600) 0 2px, transparent 2px 5px); box-shadow: inset 0 0 0 1px var(--color-signal-600); }
.kapazitaet .grenze { top: -4px; bottom: -4px; width: 0; border-left: 1.5px solid var(--color-text); }
.kapazitaet-text { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 2px 8px; margin-top: 4px; font-size: 11px; color: var(--color-neutral-700); font-variant-numeric: tabular-nums; }
.kapazitaet-text .zu-viel { color: var(--color-signal-800); }

/* Die Woche: Kennzahl, Fortschritt, je Tag eine Saeule im gleichen Raster. */
.woche-kopf { display: flex; align-items: flex-end; gap: 12px; }
.woche-kopf .kpi { font-size: 40px; }
.woche-kopf .kpi small { font-size: 22px; color: var(--color-neutral-600); }
.woche-kopf .was { font-size: 12px; color: var(--color-neutral-700); line-height: 1.3; padding-bottom: 4px; }
.woche-kopf .neben { margin-left: auto; text-align: right; font-size: 11px; color: var(--color-neutral-700); line-height: 1.5; padding-bottom: 3px; }
.woche-kopf .neben strong { color: var(--color-text); font-variant-numeric: tabular-nums; }
.woche { display: grid; grid-template-columns: repeat(5, 1fr); border: 1px solid var(--color-divider); margin-top: 10px; }
.wtag { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 7px 4px 8px; text-decoration: none; color: inherit; }
.wtag + .wtag { border-left: 1px solid var(--color-divider); }
.wtag:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }
.wtag-name { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 13px; line-height: 1; }
.wtag-datum { font-size: 10px; color: var(--color-neutral-600); line-height: 1; font-variant-numeric: tabular-nums; }
.wtag-saeule { width: 18px; height: 54px; display: flex; flex-direction: column-reverse; border: 1px solid var(--color-divider); background: var(--color-neutral-100); }
.wtag-saeule > span { display: block; flex: none; }
.wtag-saeule .erledigt { background: var(--color-accent); }
.wtag-saeule .offen { background: var(--color-bg); box-shadow: inset 0 0 0 1px var(--color-accent); }
.wtag-saeule .angefragt { background: repeating-linear-gradient(135deg, var(--color-accent-400) 0 2px, transparent 2px 4px); }
.wtag-zahl { font-size: 11px; font-variant-numeric: tabular-nums; line-height: 1; }
.wtag-zahl.leer { color: var(--color-neutral-500); }
/* Heute: blauer Rahmen und Wochentag in Akzentblau – Rot bleibt dem
   „offen geblieben“ vorbehalten, sonst lesen sich beide gleich. */
.wtag.ist-heute { box-shadow: inset 0 0 0 1.5px var(--color-accent); }
.wtag.ist-heute .wtag-name { color: var(--color-accent); }
.wtag .rest { position: absolute; top: 5px; right: 5px; width: 7px; height: 7px; background: var(--color-signal); }
.legende { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 6px; font-size: 10.5px; color: var(--color-neutral-700); }
.legende i { display: inline-block; width: 9px; height: 9px; margin-right: 4px; vertical-align: -1px; }
.legende .l-erledigt { background: var(--color-accent); }
.legende .l-offen { box-shadow: inset 0 0 0 1px var(--color-accent); }
.legende .l-angefragt { background: repeating-linear-gradient(135deg, var(--color-accent-400) 0 2px, transparent 2px 4px); box-shadow: inset 0 0 0 1px var(--color-accent-400); }
.legende .l-rest { background: var(--color-signal); }

/* Heute in der Werkstatt */
.heute { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; align-items: center; }
.heute .titel { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 19px; line-height: 1.15; color: inherit; text-decoration: none; }
.heute .fortschritt { grid-column: 1 / -1; margin-top: 6px; }

/* Kennzahl mit Zeitraum: drei Segmente als Radioknoepfe, das Stylesheet zeigt
   den gewaehlten Zeitraum – ohne Skript, ohne Neuladen. */
.zeitraum { display: flex; width: 100%; }
.zeitraum .seg-opt { flex: 1; justify-content: center; font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; min-height: 36px; padding: 4px 6px; }
.zeitraum-feld { display: none; }
.zeitraum-karte:has(input[value="90"]:checked) .zeitraum-feld[data-tage="90"],
.zeitraum-karte:has(input[value="30"]:checked) .zeitraum-feld[data-tage="30"],
.zeitraum-karte:has(input[value="7"]:checked) .zeitraum-feld[data-tage="7"] { display: block; }
@supports not selector(:has(a)) {
  .zeitraum { display: none; }
  .zeitraum-feld[data-tage="90"] { display: block; }
}
.kennzahl { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 8px; margin-top: 12px; }
.kennzahl .kpi { font-size: 40px; }
.kennzahl .einheit { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 20px; }
.kennzahl .bezug { font-size: 12px; color: var(--color-neutral-700); }
.kennzahl-zeile { font-size: 12px; color: var(--color-neutral-700); line-height: 1.45; font-variant-numeric: tabular-nums; }
.kennzahl-zeile strong { color: var(--color-text); }
.diagramm { display: block; width: 100%; height: auto; margin-top: 10px; }
.diagramm .balken { fill: var(--color-accent); }
.diagramm .balken.schaetzung { fill: var(--color-accent-400); }
.diagramm .grund { stroke: var(--color-divider); stroke-width: 1; }
.diagramm .schnitt { stroke: var(--color-signal); stroke-width: 1; stroke-dasharray: 4 3; }
.diagramm .schnitt-text { fill: var(--color-signal-800); font: 600 10px var(--font-body); paint-order: stroke; stroke: var(--color-bg); stroke-width: 3px; stroke-linejoin: round; }
.diagramm .achse { fill: var(--color-neutral-600); font: 400 9.5px var(--font-body); }
.diagramm .wert { fill: var(--color-text); font: 500 10px var(--font-body); paint-order: stroke; stroke: var(--color-bg); stroke-width: 3px; stroke-linejoin: round; }
.quelle { font-size: 11px; color: var(--color-neutral-700); margin-top: 6px; line-height: 1.4; }

/* Neu bei den Terminen (Planer) */
.neu-zeile { display: flex; align-items: flex-start; gap: 10px; padding: 11px 12px; border-bottom: 1px solid var(--color-divider); font-size: 13px; text-decoration: none; color: inherit; }
.list .neu-zeile:last-child { border-bottom: 0; }
.neu-zeile:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.neu-zeile > .icon { margin-top: 2px; color: var(--color-accent); }
.neu-zeile.ist-abgelehnt > .icon { color: var(--color-signal-700); }
.neu-zeile .was { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; line-height: 1.2; }
.neu-zeile .sub { font-size: 11px; color: var(--color-neutral-700); line-height: 1.4; }
.neu-zeile .tags { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex: none; }
.tag-abgelehnt { border: 1px solid var(--color-signal-700); color: var(--color-signal-800); }

/* Zu beauftragen: je Zug ein Balken */
.zug-balken { display: grid; grid-template-columns: minmax(56px, max-content) minmax(60px, 1fr) auto; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--color-divider); text-decoration: none; color: inherit; font-size: 12px; }
.list .zug-balken:last-child { border-bottom: 0; }
.zug-balken:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.zug-balken .zug { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; }
.zug-balken .spur { height: 8px; display: flex; background: var(--color-neutral-100); border: 1px solid var(--color-divider); }
.zug-balken .spur .ohne { background: var(--color-accent); }
.zug-balken .spur .geplant { background: var(--color-accent-300); }
.zug-balken .hint { font-size: 11px; color: var(--color-neutral-700); white-space: nowrap; }

/* Wochenbeleg (Creative Services) */
.beleg-reihe { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; padding: 9px 0; border-bottom: 1px solid var(--color-divider); font-size: 12px; text-decoration: none; color: inherit; }
.beleg-reihe:last-of-type { border-bottom: 0; }
.beleg-reihe .wer { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px; }
.beleg-reihe .betrag { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; color: var(--color-accent-700); text-align: right; }
.beleg-reihe .sub { grid-column: 1 / -1; font-size: 11px; color: var(--color-neutral-700); }

/* Übersicht anpassen */
.uebersicht-anpassen { align-self: center; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--color-accent); text-decoration: none; }
.anpassen-zeile { display: flex; align-items: center; gap: 6px; padding: 10px 12px; border-bottom: 1px solid var(--color-divider); font-size: 13px; }
.list .anpassen-zeile:last-child { border-bottom: 0; }
.anpassen-titel { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px; }
.anpassen-zeile.ist-aus .anpassen-titel, .anpassen-zeile.ist-aus .tiny { color: var(--color-neutral-500); }
.anpassen-schalter { flex: none; min-height: 36px; font-size: 12px; gap: 5px; }
.anpassen-zeile.ist-aus .anpassen-schalter { color: var(--color-neutral-600); }
.icon-hoch { transform: rotate(180deg); }
