/* ============================================================
   Auskunft-Admin — Design-System „Papier und Praezision"
   Uebernommen aus der Firmenwebsite: warmes Papier-Weiss, Tinte,
   Ultramarin. Clash Display / Switzer / Fragment Mono, Radius 10px.
   Bewusst nuechtern: kein Three.js, keine Reveal-Animationen,
   keine Marketing-Dekoration. Ein schnelles Werkzeug.
   Fonts liegen lokal unter /admin-static/fonts/ (relative Pfade).
   ============================================================ */

@font-face {
  font-family: 'Clash Display';
  src: url('fonts/clash-display-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Clash Display';
  src: url('fonts/clash-display-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('fonts/switzer-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('fonts/switzer-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('fonts/switzer-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Fragment Mono';
  src: url('fonts/fragment-mono-400-latin-ext.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  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;
}
@font-face {
  font-family: 'Fragment Mono';
  src: url('fonts/fragment-mono-400-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  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;
}

/* ---------- Tokens ---------- */

:root {
  /* Flaechen und Tinte (1:1 Firmenwebsite) */
  --paper: #ffffff;
  --paper-2: #f6f6f4;
  --paper-bright: #ffffff;
  --ink: #16161a;
  --ink-70: rgba(22, 22, 26, 0.72);
  --ink-55: rgba(22, 22, 26, 0.62);   /* AA fuer Kicker, Fine, Label */
  --line: rgba(22, 22, 26, 0.16);
  --line-soft: rgba(22, 22, 26, 0.09);
  --blue: #2438c9;                     /* Ultramarin, Aktionsfarbe */
  --blue-deep: #1c2da8;                /* Hover */
  --dark: #101014;                     /* Snippet-Box */
  --dark-text: #f2f2f0;
  --dark-text-soft: rgba(242, 242, 240, 0.62);
  --dark-line: rgba(255, 255, 255, 0.14);

  /* Status (AA gegen #fff geprueft) */
  --ok: #2e7d43;      --ok-soft: #e9f1eb;
  --warn: #8a5a00;    --warn-soft: #f5edda;
  --err: #b3382e;     --err-soft: #f8ebe8;
  --eu: #24477a;      --eu-soft: #e7edf5;
  --run: #8a5a00;

  --font-display: 'Clash Display', 'Segoe UI', sans-serif;
  --font-text:    'Switzer', 'Segoe UI', sans-serif;
  --font-mono:    'Fragment Mono', 'Consolas', monospace;
  --font-serif:   'Gambetta', Georgia, serif;

  --w: min(1180px, calc(100vw - clamp(2rem, 6vw, 5rem)));
  --radius: 10px;
  --ease: cubic-bezier(0.22, 0.8, 0.24, 1);
  --topbar-h: 4.2rem;
}

/* ---------- Grundlagen ---------- */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--topbar-h);
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 1.0625rem;
  line-height: 1.65;
  font-feature-settings: 'ss01' on;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
h1 { font-size: clamp(1.7rem, 3vw, 2.3rem); }
h2 { font-size: 1.3rem; margin-bottom: 0.7rem; }
h3 { font-size: 1.02rem; margin: 1.3rem 0 0.5rem; }
h4 { font-size: 0.9rem; }

p { margin: 0; }
a { color: inherit; }
img { max-width: 100%; display: block; }

::selection { background: var(--blue); color: #fff; }

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Skip-Link: unsichtbar bis Tastaturfokus, dann Pille oben links */
.skiplink {
  position: fixed;
  top: 0.7rem;
  left: 0.7rem;
  z-index: 3100;
  padding: 0.6rem 1.1rem;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  transform: translateY(calc(-100% - 2rem));
}
.skiplink:focus,
.skiplink:focus-visible { transform: none; }

/* ---------- Typo-Bausteine ---------- */

.mono { font-family: var(--font-mono); font-size: 0.86em; }
.muted { color: var(--ink-70); }
.strong { font-weight: 600; }
.acc { color: var(--blue); }

.kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-55);
}
.kicker::after {
  content: '';
  flex: 1;
  align-self: center;
  height: 1px;
  background: var(--line);
}

.lead {
  font-size: clamp(1.1rem, 1.6vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-70);
  max-width: 38em;
}
.fine {
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--ink-55);
  max-width: 60em;
}

.tlink {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--ink-55);
  transition: color 0.2s, text-decoration-color 0.2s;
}
.tlink:hover { color: var(--blue); text-decoration-color: var(--blue); }

/* ---------- Topbar (fix) ---------- */

.topbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 3000;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--line-soft);
}

.topbar-inner {
  width: var(--w);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 2rem;
  padding-block: 0.9rem;
  min-height: var(--topbar-h);
}

.brand {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--ink);
  white-space: nowrap;
}
.brand b { font-weight: 600; color: var(--blue); transition: color 0.2s; }
.brand:hover b { color: var(--blue-deep); }

.topnav {
  display: flex;
  gap: clamp(1rem, 2vw, 1.8rem);
  align-items: center;
  flex-wrap: wrap;
}
.topnav a {
  font-family: var(--font-text);
  font-size: 0.94rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink-70);
  padding-block: 0.3rem;
  position: relative;
  transition: color 0.2s;
}
.topnav a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s var(--ease);
}
.topnav a:hover,
.topnav a[aria-current='page'] { color: var(--ink); }
.topnav a:hover::after,
.topnav a[aria-current='page']::after { transform: scaleX(1); }

.topbar-cta { margin-left: auto; }

/* ---------- Wrap und Footer ---------- */

.wrap {
  width: var(--w);
  margin: 0 auto 4rem;
  padding-top: calc(var(--topbar-h) + 1rem);
}

.foot {
  border-top: 1px solid var(--line);
  padding: 1rem clamp(1rem, 3vw, 2.5rem);
  color: var(--ink-55);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
}

/* ---------- Sub-Navigation (tenant.html, klebendes Inhaltsverzeichnis) ---------- */

.sub-nav {
  position: sticky;
  top: var(--topbar-h);
  z-index: 1500;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line-soft);
  display: flex;
  gap: 1.4rem;
  padding: 0.6rem 0;
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
  overflow-x: auto;
}
.sub-nav a {
  font-family: var(--font-text);
  font-size: 0.94rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink-70);
  padding-block: 0.3rem;
  position: relative;
  white-space: nowrap;
  transition: color 0.2s;
}
.sub-nav a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s var(--ease);
}
.sub-nav a:hover,
.sub-nav a[aria-current='true'] { color: var(--ink); }
.sub-nav a:hover::after,
.sub-nav a[aria-current='true']::after { transform: scaleX(1); }

/* ---------- Banner ---------- */

.banner {
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 0.7rem 1rem;
  margin-bottom: 1.2rem;
  font-family: var(--font-text);
  font-size: 0.9rem;
  line-height: 1.5;
}
.banner.ok   { color: var(--ok);   border-color: rgba(46, 125, 67, 0.3);  background: var(--ok-soft); }
.banner.err  { color: var(--err);  border-color: rgba(179, 56, 46, 0.3);  background: var(--err-soft); }
.banner.warn { color: var(--warn); border-color: rgba(138, 90, 0, 0.3);   background: var(--warn-soft); }
.banner code { font-family: var(--font-mono); font-size: 0.9em; }
form .banner, .stack .banner { margin: 0 0 0.4rem; }

/* ---------- Karten (.card, Alias .panel) ---------- */

.card, .panel {
  background: var(--paper-bright);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 2px);
  padding: clamp(1.2rem, 2.4vw, 1.8rem);
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
}
.card.narrow, .panel.narrow { max-width: 660px; }
.card-head, .panel-head { margin-bottom: 1rem; }
.card-lead { color: var(--ink-70); }

.card-warn, .warn-panel {
  border-color: var(--warn);
  background: var(--warn-soft);
}
.card-warn h2, .warn-panel h2 { color: var(--warn); }
.warn-panel ul, .card-warn ul { padding-left: 1.2rem; }
.warn-list li { margin: 0.3rem 0; }

.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
@media (max-width: 1080px) { .two-col { grid-template-columns: 1fr; } }

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

/* Basisregel deckt nackte <button> in Formularen ab; die .btn-*-Klassen
   sind der explizite Weg (siehe Templates). Beide fuehren zur selben Optik. */
.btn,
button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-text);
  font-weight: 500;
  font-size: 0.98rem;
  line-height: 1.2;
  padding: 0.75rem 1.4rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  background: var(--ink);
  color: var(--paper);
  transition: background 0.22s var(--ease), color 0.22s var(--ease),
    border-color 0.22s var(--ease), transform 0.18s var(--ease);
}
.btn:active,
button:active { transform: translateY(1px); }
button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Das hidden-Attribut muss auch bei per Typ/Klasse gesetztem display greifen.
   Die Author-Regeln (button{display:inline-flex}, input{display:block}) schlagen
   sonst die UA-Regel [hidden]{display:none} (Author vor UA, spezifitaetsunab-
   haengig), sodass mit `hidden` markierte Steuerelemente sichtbar blieben. */
[hidden] { display: none !important; }

/* Der Typ-Selektor button[type='submit'] hat hoehere Spezifitaet (0,1,1) als
   die Einzelklassen .btn-danger/.btn-line (0,1,0) und wuerde deren Optik sonst
   ueberschreiben (der destruktivste Knopf saehe aus wie ein Primaerknopf). Die
   ink-Basis gilt daher nur fuer submit-Knoepfe OHNE eine dieser Klassen. */
.btn-ink,
button[type='submit']:not(.btn-danger):not(.btn-line):not(.danger):not(.secondary) {
  background: var(--ink); color: var(--paper); border-color: transparent;
}
.btn-ink:hover,
button[type='submit']:not(.btn-danger):not(.btn-line):not(.danger):not(.secondary):hover:not(:disabled) {
  background: var(--blue); color: #fff;
}

.btn-line,
button.secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--line);
}
.btn-line:hover,
button.secondary:hover:not(:disabled) {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.btn-danger,
button.danger {
  background: transparent;
  color: var(--err);
  border-color: var(--err);
}
.btn-danger:hover,
button.danger:hover:not(:disabled) { background: var(--err); color: #fff; border-color: var(--err); }

.btn-s,
button.small { padding: 0.5rem 0.9rem; font-size: 0.85rem; }

.btn-row { display: flex; gap: 0.8rem; margin-top: 1.1rem; flex-wrap: wrap; align-items: center; }
.btn-row form { display: inline; }

/* ---------- Formulare und Felder ---------- */

.stack { display: flex; flex-direction: column; gap: 1.1rem; margin-top: 0.6rem; }

/* Label als Block (Bestand: Label umschliesst Input) und .field-Wrapper. */
.field label,
.field > span.label,
form label,
label {
  display: block;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 0.4rem;
}

input, select, textarea {
  display: block;
  width: 100%;
  font: inherit;
  font-size: 1rem;                     /* mind. 16px, sonst zoomt iOS */
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.7rem 0.9rem;
  margin-top: 0.35rem;
  transition: border-color 0.2s, box-shadow 0.2s;
  resize: vertical;
}
/* Erste Zeile im Label ist der Text, danach folgt das Feld: der obere
   Abstand traegt das Feld, nicht den Text (Label ist Block). */
label > input,
label > select,
label > textarea { margin-top: 0.35rem; }

textarea { min-height: 3.4em; }
textarea.mono { font-family: var(--font-mono); font-size: 0.9rem; }

input:hover, select:hover, textarea:hover { border-color: var(--ink-55); }

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(36, 56, 201, 0.13);
}

input::placeholder, textarea::placeholder { color: var(--ink-55); opacity: 0.7; }

select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.6rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%2316161a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px 8px;
}

.field.is-invalid input,
.field.is-invalid textarea,
.field.is-invalid select {
  border-color: var(--err);
  box-shadow: 0 0 0 3px rgba(179, 56, 46, 0.12);
}

.check { display: flex; align-items: center; gap: 0.6rem; }
.check label { margin-bottom: 0; }
.check input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--blue);
  flex: none;
}

.hint {
  display: block;
  font-size: 0.82rem;
  color: var(--ink-55);
  line-height: 1.5;
  margin-top: 0.35rem;
  max-width: 62ch;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.2rem;
}
.grid-2 .span-2 { grid-column: 1 / -1; }
@media (max-width: 860px) { .grid-2 { grid-template-columns: 1fr; } }

.inline { display: inline; }
.inline select {
  display: inline-block;
  width: auto;
  margin: 0;
  padding: 0.3rem 1.8rem 0.3rem 0.5rem;
  font-size: 0.85rem;
  background-position: right 0.5rem center;
}

.upload-row {
  display: flex;
  gap: 0.8rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin: 0.8rem 0 1.2rem;
}
.upload-row input[type='file'] {
  width: auto;
  background: transparent;
  border: none;
  padding-left: 0;
  margin-top: 0;
}
.upload-row select { width: auto; }
.upload-row label { flex: 1; min-width: 220px; margin-bottom: 0; }

/* Button-Form-Auswahl mit Mini-Vorschau */
.shape-pick {
  border: none;
  padding: 0;
  display: flex;
  gap: 1.6rem;
  flex-wrap: wrap;
  align-items: center;
}
.shape-pick legend {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 0.5rem;
}
.shape-pick label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  cursor: pointer;
  margin-bottom: 0;
}
.shape-pick input { width: auto; height: auto; margin: 0; accent-color: var(--blue); }
.shape-demo {
  width: 24px;
  height: 24px;
  background: var(--ink);
  display: inline-block;
  flex: none;
}
.shape-demo.rounded { border-radius: 7px; }
.shape-demo.circle { border-radius: 50%; }
.shape-demo.square { border-radius: 3px; }

/* Logo-Vorschau */
.logo-preview {
  max-height: 72px;
  max-width: 240px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  padding: 6px;
}

/* ---------- Tabellen (.tbl, Alias nacktes table) ---------- */

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

table, .tbl {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.6rem;
}
table th, .tbl th {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-55);
  text-align: left;
  font-weight: 400;
  padding: 0.5rem 0.8rem 0.5rem 0;
  border-bottom: 1px solid var(--line);
}
table td, .tbl td {
  padding: 0.65rem 0.8rem 0.65rem 0;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
  font-size: 0.95rem;
}
table tr:hover td, .tbl tr:hover td { background: var(--paper-2); }
.tbl td.num, table td.num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.warn-row td { color: var(--warn); }

/* ---------- Status-Pills ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge .dot { width: 0.45em; height: 0.45em; border-radius: 50%; background: currentColor; }
.badge.ok  { color: var(--ok);     background: var(--ok-soft);   border-color: rgba(46, 125, 67, 0.25); }
.badge.off { color: var(--ink-55); background: var(--paper-2);   border-color: var(--line); }
.badge.run { color: var(--run);    background: var(--warn-soft); border-color: rgba(138, 90, 0, 0.25); }
.badge.err { color: var(--err);    background: var(--err-soft);  border-color: rgba(179, 56, 46, 0.25); }
.badge.eu  { color: var(--eu);     background: var(--eu-soft);   border-color: rgba(36, 71, 122, 0.25); }

/* ---------- Meter ---------- */

.meter {
  display: inline-block;
  width: 90px;
  height: 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  vertical-align: middle;
  margin-right: 0.5rem;
  background: var(--paper-2);
  overflow: hidden;
}
.meter.wide { width: min(420px, 100%); height: 8px; margin: 0.4rem 0 1rem; display: block; }
.meter i { display: block; height: 100%; background: var(--ok); border-radius: 999px; }
.meter i.near { background: var(--warn); }
.meter i.over { background: var(--err); }

/* Grosse Nutzungs-Kennzahl */
.usage-figure {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2rem, 4vw, 2.8rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* ---------- Snippet-Box ---------- */

.snippet {
  background: var(--dark);
  color: var(--dark-text);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  margin: 0.5rem 0 0.4rem;
  user-select: all;
}
.snippet code { font-family: inherit; }

/* ---------- Test-Chat (Admin-Optik, an Widget angelehnt) ---------- */

.chat-log {
  border: 1px solid var(--line);
  background: var(--paper-2);
  border-radius: var(--radius);
  padding: 0.9rem;
  height: 340px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 0.4rem;
}
.chat-empty { color: var(--ink-55); font-size: 0.88rem; margin: auto; }
.chat-msg {
  max-width: 82%;
  padding: 0.55rem 0.8rem;
  font-size: 0.95rem;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
.chat-msg.user {
  align-self: flex-end;
  background: var(--ink);
  color: var(--paper);
  border-radius: 16px 16px 6px 16px;
}
.chat-msg.bot {
  align-self: flex-start;
  background: var(--paper-bright);
  border: 1px solid var(--line);
  border-radius: 16px 16px 16px 6px;
}
.chat-msg.chat-err {
  border: 1px solid var(--err);
  color: var(--err);
  background: var(--err-soft);
}
.chat-sources {
  align-self: flex-start;
  max-width: 82%;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-55);
}
.chat-sources ol { padding-left: 1.2rem; margin-top: 0.15rem; }
.chat-handoff {
  align-self: flex-start;
  max-width: 82%;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-70);
  border-left: 3px solid var(--blue);
  padding-left: 0.5rem;
}
.chat-form { display: flex; gap: 0.6rem; margin-top: 0.8rem; flex-wrap: wrap; }
.chat-form input { flex: 1; min-width: 220px; margin-top: 0; }

/* ---------- Wissensluecken, Filter, Berichte ---------- */

.filter-row {
  font-size: 0.9rem;
  color: var(--ink-70);
  margin-bottom: 0.6rem;
}
.filter-row strong {
  font-weight: 500;
  color: #fff;
  background: var(--blue);
  padding: 0.16rem 0.6rem;
  border-radius: 999px;
}
.filter-row a { text-decoration: underline; text-underline-offset: 3px; }
.filter-row a:hover { color: var(--blue); }

details.report { margin: 0.4rem 0; }
.report-body {
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  margin: 0.5rem 0 1rem;
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  overflow-x: auto;
}

details summary {
  cursor: pointer;
  color: var(--ink-70);
  padding: 0.4rem 0;
  transition: color 0.2s;
}
details summary:hover { color: var(--blue); }
details.report summary { font-size: 0.9rem; }

/* ---------- Widget-Zweispalter (tenant.html, Erscheinungsbild) ---------- */

/* Die Breite der Vorschau steht seit dem 04.08.2026 an EINER Stelle, und die
   Rasterspur wie der Rahmen lesen dieselbe Variable. Vorher waren es zwei
   Zahlen an zwei Orten (Spur 380 hier, Rahmenbreite 380 im JS von
   tenant.html), plus ein `max-width:100%` am Rahmen, das die groessere der
   beiden still wieder auf die kleinere klemmte. Wer eine der Zahlen anfasste,
   aenderte damit nichts Sichtbares und suchte den Fehler an der falschen
   Stelle.

   600 statt 380 ist keine Geschmacksfrage, sondern die Bedingung dafuer, dass
   die Vorschau ueberhaupt eine Rechner-Ansicht zeigen kann: Das Widget
   schaltet unterhalb von 520 Pixel Innenbreite auf seinen Handy-Zweig
   (Bottom-Sheet ueber die volle Breite, feste Hoehe). In einem 380 Pixel
   breiten Rahmen war deshalb JEDE Vorschau eine Handy-Vorschau, und die
   Felder Fenster-Breite und Fenster-Hoehe blieben in jeder Ansicht wirkungslos.
   Die Rechnung: 600 abzueglich 2 Pixel Rahmen ergibt 598 Pixel Innenbreite,
   also ueber den 520 des Umschaltpunkts und zugleich weit genug fuer das
   breiteste erlaubte Fenster (560 Pixel plus die 32 Pixel Rand, die sich das
   Widget freihaelt, macht 592).
   Verworfen: die Vorschau verkleinert darzustellen (transform: scale). Das
   haette die Spalte schmal gelassen, aber jede Schriftgroesse verfaelscht,
   und eine Vorschau, deren Text man nicht eins zu eins lesen kann, beantwortet
   die einzige Frage nicht, fuer die sie da ist. */
.widget-layout {
  --preview-w: 600px;
  display: grid;
  /* Die Spur ist bewusst 18 Pixel breiter als der Rahmen. Wird die Vorschau
     bei hohem Rahmen zum eigenen Scroller (siehe .widget-preview), braucht
     dessen Balken Platz; ohne diese Zugabe naehme er ihn dem Rahmen weg, und
     die Spalte bekaeme zusaetzlich einen waagerechten Balken. 18 statt 16,
     weil Windows-Balken je nach Einstellung etwas breiter ausfallen. */
  grid-template-columns: minmax(0, 1fr) calc(var(--preview-w) + 18px);
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: start;
}
.widget-fields { min-width: 0; }

/* Solange die Vorschau daneben steht, macht `.grid-2` in der Feldspalte genau
   EINE Spur. Ohne das laeuft die Seite hier waagerecht ueber, seit die
   Vorschau 600 statt 380 Pixel breit ist: Die Vorschauspur ist damit von 380
   auf 618 gewachsen, und diese 238 Pixel fehlen der Feldspalte.

   Alles Folgende ist GERECHNET, nicht im Browser gemessen. Was der Feldspalte
   bleibt: `.wrap` (min(1180px, 100vw - clamp(2rem, 6vw, 5rem))) abzueglich
   Kartenrand (2) und Kartenpolster (2 x clamp(1.2rem, 2.4vw, 1.8rem)),
   abzueglich Vorschauspur (600 + 18) und Spalt (clamp(1.5rem, 3vw, 2.5rem)):
     1101 px Fenster: 1034,9 - 2 - 52,8 - 618 - 33,0 = 329,1
     1200 px Fenster: 1128,0 - 2 - 57,6 - 618 - 36,0 = 414,4
     ab rund 1334 px: 1180,0 - 2 - 57,6 - 618 - 40,0 = 462,4
   Mehr als 462,4 gibt es auf KEINEM Bildschirm, weil `--w` bei 1180 gedeckelt
   ist. Der engste Fall ist 1101 px, denn genau dort beginnt der Zweispalter
   (die Regel `max-width: 1100px` weiter unten).

   Der breiteste Bewohner der Spalte ist eine Farbzeile: 42 Waehler + 8 Spalt
   + Textfeld, und das Textfeld ist size=20 in Fragment Mono 14,4px, also
   172,8 Inhalt + 28,8 Polster (2 x 0,9rem) + 2 Rahmen = 203,6. Macht 253,6.
   ZWEI davon plus 19,2 Spalt waeren 526,4 und passen weder in 462,4 noch in
   329,1: Zwei Feldspalten neben dieser Vorschau gehen auf keiner
   Fensterbreite, einspaltig bleiben bei 1101 px noch 75,5 Pixel Reserve und
   ab 1334 px 208,8. Die uebrigen Raster der Spalte sind schmaler: die drei
   Zahlenfelder der Feinjustierung rund 245 (20 Zeichen der Textschrift in
   16px, Spinner, Polster, Rahmen), die Textfelder rund 215, das Auswahlfeld
   rund 150. Diese drei Zahlen sind Schaetzungen, weil sie an den Metriken
   einer proportionalen Schrift haengen; auch die pessimistische Lesart bleibt
   klar unter 329,1. Die Groessenstufen-Knoepfe und die Formauswahl sind Flex
   mit `wrap` und brechen ohnehin um.

   Verworfen (a): `--w` fuer diese Seite anheben. Zwei Feldspalten brauchten
   526,4 + 40 Spalt + 618 Vorschau + 57,6 Polster + 2 Rand = 1244 Pixel. Die
   gibt es bei 1101 px Fensterbreite nicht, egal wie hoch der Deckel steht,
   also waere zusaetzlich der Umbruchpunkt von 1100 auf ueber 1250 zu
   verschieben. Und `--w` ist die Zeilenlaenge JEDER Admin-Seite, nicht nur
   dieser.
   Verworfen (c): das Textfeld der Farbzeile schmaler machen. Bei 1101 px
   duerfte eine Farbzeile 154,9 breit sein, das Textfeld also 104,9: das ist
   size=8, gerade sieben Zeichen fuer #rrggbb plus Schreibmarke, und der
   Abstand zum Ueberlauf betruege 5 Pixel. Er haengt damit an der genauen
   Zeichenbreite von Fragment Mono, also an einer Zahl, die beim naechsten
   Umbau niemand nachrechnet.

   Die Abfrage ist absichtlich das genaue Gegenstueck zu `max-width: 1100px`
   und nicht `min-width: 1101px`: Fensterbreiten sind bei Zoomstufen nicht
   ganzzahlig, und 1100,5 px waere sonst nebeneinander UND zweispaltig im
   Feld, also genau der Ueberlauf. Unterhalb greift die Regel nicht, dort
   gelten wieder `.grid-2` und sein 860er-Umbruch. */
@media not all and (max-width: 1100px) {
  /* `minmax(0, 1fr)` und nicht `1fr`: `1fr` heisst `minmax(auto, 1fr)`, und
     `auto` liesse die Spur an einem einzelnen breiten Kind wieder aufgehen. */
  .widget-fields .grid-2 { grid-template-columns: minmax(0, 1fr); }
}

.widget-preview {
  position: sticky;
  top: calc(var(--topbar-h) + 4rem);
  align-self: start;
  /* Auffangnetz fuer den hohen Rahmen: Wer 720 Pixel Fensterhoehe einstellt,
     bekommt einen 852 Pixel hohen Rahmen (siehe applyFrameSize in
     tenant.html), und der ist auf einem Laptop hoeher als der sichtbare
     Bereich. Ein klebendes Element, das hoeher ist als das Fenster, laesst
     sich nicht zu Ende scrollen: sein unteres Ende bliebe unerreichbar, und
     genau dort sitzt das Chatfenster. Der eigene Scroller kostet einen
     Balken, macht den Rahmen aber vollstaendig erreichbar.
     Verworfen: das Kleben ganz aufzugeben. Dann laeuft die Vorschau beim
     Einstellen der Farben nach oben aus dem Bild, also weg von genau der
     Arbeit, fuer die man sie braucht. */
  max-height: calc(100vh - var(--topbar-h) - 5rem);
  overflow: auto;
}
.widget-preview iframe,
#widget-preview {
  width: var(--preview-w, 360px);
  /* Nur der Startwert. Sobald das JS laeuft, setzt applyFrameSize Breite und
     Hoehe inline, die Hoehe abhaengig von der eingestellten Fensterhoehe. */
  height: 660px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper-2);
}
/* Werkzeugleiste ueber der Vorschau (Desktop/Handy, offen/zu) */
.preview-tools {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.7rem;
}
/* Derzeit von keiner Vorlage benutzt, bleibt aber in Groesse und Verhalten am
   echten Rahmen, damit ein spaeterer Einbau nicht zwei Bauarten mischt. */
.preview-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: var(--preview-w, 360px);
  height: 660px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: var(--paper-2);
  color: var(--ink-55);
  padding: 1.5rem;
}
@media (max-width: 1100px) {
  .widget-layout { grid-template-columns: minmax(0, 1fr); }
  .widget-preview {
    position: static;
    order: -1;
    /* Einspaltig steht die Vorschau im Fluss und kann so hoch werden, wie sie
       will: der Deckel und der eigene Scroller von oben wuerden hier nur
       grundlos beschneiden. */
    max-height: none;
    overflow: visible;
  }
  /* Einspaltig ist die Huelle regelmaessig schmaler als 600 Pixel, spaetestens
     ab etwa 640 Pixel Fensterbreite. Hier MUSS der Rahmen mitschrumpfen, sonst
     laeuft die Seite waagerecht ueber. Im Zweispalter steht diese Regel
     bewusst NICHT: dort war sie der Grund, warum eine breitere Vorschau nie
     ankam. Das JS setzt nur `width` inline, `max-width` bleibt davon
     unberuehrt und gewinnt gegen jede Breitenangabe. */
  .widget-preview iframe,
  #widget-preview,
  .preview-placeholder { max-width: 100%; }
}

/* ---------- Gefahrenzone ---------- */

.danger-zone, .card.card-danger {
  border-color: var(--err);
}
.danger-zone h2, .card-danger h2 { color: var(--err); }

/* ---------- Login (eigenstaendig, kein extends) ---------- */

.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--paper-2);
  padding: 1.5rem;
}
.login-box {
  width: min(400px, 100%);
  background: var(--paper-bright);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 6px);
  box-shadow: 0 22px 44px -30px rgba(22, 22, 26, 0.25);
  padding: clamp(1.6rem, 4vw, 2.2rem);
}
.login-box .brand { display: block; margin-bottom: 1.2rem; }
.login-box h1 { margin-bottom: 1rem; }
.login-box form { display: flex; flex-direction: column; gap: 0.9rem; }
.login-box button { width: 100%; }
.login-foot {
  margin-top: 1.4rem;
  color: var(--ink-55);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
}

/* ---------- Responsive ---------- */

@media (max-width: 720px) {
  .card, .panel { padding: clamp(1rem, 4vw, 1.3rem); }
}
@media (max-width: 620px) {
  body { font-size: 1rem; }
  /* `.widget-layout` stand hier bis zum 04.08.2026 mit in der Liste und war
     ein waagerechter Ueberlauf: Der Zweispalter ist ab 1100 Pixel ohnehin
     einspaltig, diese Regel setzte ihn nur ein zweites Mal, dabei aber auf
     `1fr` statt auf `minmax(0, 1fr)`. `1fr` heisst `minmax(auto, 1fr)`, und
     `auto` ist als Untergrenze die Mindestbreite des Inhalts: der Rahmen mit
     seinen 600 Pixel Breitenangabe. Die Spur waere damit nie unter 600
     gefallen, egal wie schmal das Fenster ist, und die ganze Seite haette
     waagerecht gescrollt (ein prozentuales `max-width` zaehlt bei dieser
     Rechnung nicht mit). Die 1100er-Regel weiter oben macht dasselbe richtig. */
  .grid-2, .two-col { grid-template-columns: 1fr; }
  .btn-row { flex-direction: column; align-items: stretch; }
  .btn-row form { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
