/*
 * base.css — shared across every Yamis page (loaded first by
 * AssetHelper::cssLinks() before any page-specific file).
 *
 * ── Design direction ────────────────────────────────────────────────
 * The name is the brief. Ymir is the primordial giant of Norse myth,
 * formed in Ginnungagap -- the yawning void between Muspelheim (fire)
 * and Niflheim (ice) -- and the world was forged from his body. The
 * product's own tagline already says "Build worlds from nothing".
 *
 * So the palette is that myth, not a generic dev-tool theme (this file
 * previously used GitHub's exact hex values -- #0d1117 / #58a6ff -- and
 * looked like every other tool as a result):
 *   void   deep cold blue-black, the gap itself
 *   stone  raised surfaces, slabs of the giant's body
 *   rime   pale frost blue -- the STRUCTURAL accent (links, marks, focus)
 *   ember  forge gold -- the ENERGY accent, deliberately rationed to
 *          primary actions and whatever is live right now. Gold instead
 *          of the usual green "go" colour is the one real risk here: it
 *          is the only warm thing on the page, so it pulls the eye
 *          exactly where something is happening, and it is what makes
 *          the whole thing read as forged rather than merely dark.
 *
 * ── Halle (22.10.2026) ──────────────────────────────────────────────
 * Tim: "Wir haben ein super Logo, aber das Design fuehlt sich an wie von
 * einem Anfaenger-Webdesigner." Yamis soll Premium-KI vermitteln: Macht,
 * Ehrfurcht, Respekt, Uebersicht -- ein Privileg, ihn nutzen zu duerfen.
 * Die Farben oben blieben, gefehlt hat die Umsetzung: Systemschriften
 * (die Serifen-Ueberschrift sah aus wie Times aus dem Browser), flache
 * Kaesten ohne Licht, ein flaches oranges Rechteck als Hauptknopf.
 *
 *   Licht    faellt von oben wie durch Eis: jede Tafel hat eine helle
 *            Oberkante (--edge) und einen tiefen Schatten (--deep); die
 *            Buehne (body) hat kuehles Licht von oben, Glut von unten.
 *   Glut     ein geschliffener Verlauf wie der Kristall im Logo, nicht
 *            eine flache Farbe -- weiterhin nur fuer die Haupthandlung.
 *   Der Kern der Kristall aus dem Logo ist der Senden-Knopf im Chat und
 *            atmet nur, waehrend Yamis denkt. Die einzige Bewegung.
 *
 * Schrift, selbst ausgeliefert (ymir/public/fonts, kein CDN):
 *   --font-display  Michroma -- die breite Schrift im Sinne von J.A.R.V.I.S.,
 *                   NUR fuer Wortmarke, Seitentitel und Begruessungen.
 *   --font-ui       IBM Plex Sans fuer alles, was man bedient.
 *   --font-mono     IBM Plex Mono fuer Code und Kennungen.
 *
 * Colors are CSS custom properties so the light/dark toggle (base.js,
 * UserMenu's dropdown) only swaps the :root block, never a rule. Dark is
 * the default (bare :root); [data-theme="light"] on <html> overrides.
 */

@font-face { font-family: "Michroma"; src: url("../fonts/michroma-latin-400-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Plex"; font-weight: 400; src: url("../fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Plex"; font-weight: 500; src: url("../fonts/ibm-plex-sans-latin-500-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Plex"; font-weight: 600 700; src: url("../fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Plex Mono"; src: url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2"); font-display: swap; }

:root {
  /* ── Ginnungagap: the void ── */
  --color-bg: #04060C;
  --color-bg-elevated: #0E1522;
  --color-bg-sunken: #02040A;
  --color-bg-hover: #152031;
  --color-border: rgba(168, 196, 226, 0.15);
  --color-border-subtle: rgba(168, 196, 226, 0.08);

  /* ── Niflheim: rime, frost, structure ── */
  --color-text: #E6EEF8;
  --color-text-muted: #9AACC2;
  --color-text-faint: #637489;
  --color-accent: #A8C4E2;
  --color-accent-rgb: 168, 196, 226;
  --color-accent-strong: #CFE2F5;

  /* ── Muspelheim: the forge ── */
  --color-ember: #EFAE45;
  --color-ember-rgb: 239, 174, 69;
  --color-ember-dim: #B8701A;
  --color-ember-bg: #221706;
  --color-ember-hi: #FBDC93;
  --color-ember-lo: #B8701A;

  /* ── Semantic ── */
  --color-success: #6CC79A;
  --color-success-bg: #0A2219;
  --color-danger: #E9757A;
  --color-danger-bg: #2A0F13;
  --color-danger-rgb: 233, 117, 122;
  --color-warning: #EFAE45;
  --color-warning-bg: #221706;
  --color-info-bg: #0F1D2F;
  --color-neutral-bg: #152031;
  --color-neutral-text: #9AACC2;

  --color-btn-green: #EFAE45;
  --color-btn-green-hover: #F6C567;
  --color-btn-red: #B04848;
  --color-btn-blue: #24405F;
  --color-btn-text: #1B1204;

  /* ── Halle: Flaechen, Licht, Buehne ── */
  --halle-tafel: linear-gradient(180deg, rgba(20, 29, 42, 0.78), rgba(10, 15, 26, 0.78));
  --halle-leiste: linear-gradient(180deg, rgba(14, 20, 32, 0.96), rgba(7, 11, 19, 0.96));
  --halle-feld: rgba(2, 4, 9, 0.65);
  --halle-licht: radial-gradient(1100px 520px at 62% -12%, rgba(168, 196, 226, 0.085), transparent 70%),
                 radial-gradient(700px 360px at 55% 112%, rgba(239, 174, 69, 0.05), transparent 70%);
  --edge: inset 0 1px 0 rgba(168, 196, 226, 0.09);
  --deep: 0 24px 60px -24px rgba(0, 0, 0, 0.8), 0 2px 6px rgba(0, 0, 0, 0.35);
  --glut-knopf: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 48%),
                linear-gradient(135deg, #FBDC93, #EFAE45 45%, #B8701A);

  /* ── Type ── */
  --font-display: "Michroma", "Plex", ui-sans-serif, system-ui, sans-serif;
  --font-ui: "Plex", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Plex Mono", ui-monospace, "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;

  --radius: 14px;
  --radius-sm: 10px;
  --radius-panel: 18px;
  --rail-breite: 280px;
}

/* Helles Thema: Reif und Glut auf hellem Eis -- nicht einfach umgedreht.
   Die Flaechen sind kuehl-weiss, Linien und Struktur tiefblau, die Glut
   bleibt der goldene Schliff (dunkle Schrift darauf), nur satter. */
:root[data-theme="light"] {
  --color-bg: #EEF2F7;
  --color-bg-elevated: #FFFFFF;
  --color-bg-sunken: #E4EAF2;
  --color-bg-hover: #E3EAF3;
  --color-border: rgba(27, 58, 96, 0.16);
  --color-border-subtle: rgba(27, 58, 96, 0.09);

  --color-text: #0E1A2B;
  --color-text-muted: #4A5B72;
  --color-text-faint: #77879C;
  --color-accent: #2F5D8A;
  --color-accent-rgb: 47, 93, 138;
  --color-accent-strong: #1B4068;

  --color-ember: #A9670E;
  --color-ember-rgb: 200, 132, 30;
  --color-ember-dim: #D6A253;
  --color-ember-bg: #FBF0DA;
  --color-ember-hi: #F7D58A;
  --color-ember-lo: #A9670E;

  --color-success: #1C7A4C;
  --color-success-bg: #DEF5E8;
  --color-danger: #A82C2C;
  --color-danger-bg: #FBE6E6;
  --color-danger-rgb: 168, 44, 44;
  --color-warning: #A9670E;
  --color-warning-bg: #FBF0DA;
  --color-info-bg: #E2ECF7;
  --color-neutral-bg: #E3EAF3;
  --color-neutral-text: #4A5B72;

  --color-btn-green: #E9A43C;
  --color-btn-green-hover: #F0B65A;
  --color-btn-red: #A82C2C;
  --color-btn-blue: #2F5D8A;
  --color-btn-text: #1B1204;

  --halle-tafel: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(248, 251, 254, 0.92));
  --halle-leiste: linear-gradient(180deg, rgba(250, 252, 255, 0.97), rgba(239, 244, 250, 0.97));
  --halle-feld: #FFFFFF;
  --halle-licht: radial-gradient(1100px 520px at 62% -12%, rgba(255, 255, 255, 0.9), transparent 70%),
                 radial-gradient(700px 360px at 55% 112%, rgba(233, 164, 60, 0.08), transparent 70%);
  --edge: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  --deep: 0 18px 44px -22px rgba(20, 45, 80, 0.28), 0 1px 3px rgba(20, 45, 80, 0.08);
  --glut-knopf: linear-gradient(180deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0) 48%),
                linear-gradient(135deg, #F7D58A, #E9A43C 45%, #B8701A);
}

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

body {
  font-family: var(--font-ui);
  background: var(--color-bg);
  color: var(--color-text);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* Every number in this app -- ids, counts, percentages, clock times --
   uses tabular figures so columns of them line up instead of wobbling. */
.num, td .num, .mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

::selection { background: rgba(var(--color-ember-rgb), 0.28); }

/* Scrollbalken (23.10.2026): vorher die grauen Standardbalken des Browsers
   auf dunklem Grund. Jetzt schmal, abgerundet und in der Akzentfarbe --
   kaum sichtbar in Ruhe, deutlicher beim Darueberfahren. Gilt fuer alle
   Bereiche, die scrollen (Hauptspalte, Seitenleiste, Chat, Code, Tabellen),
   in beiden Themen, weil die Farbe aus --color-accent-rgb kommt. */
:root {
  --scroll-daumen: rgba(var(--color-accent-rgb), 0.22);
  --scroll-daumen-hover: rgba(var(--color-accent-rgb), 0.42);
}
/* Firefox kennt nur die Standard-Eigenschaften. Chrome nimmt sie auch -- dann
   aber mit kleinen Pfeilen an den Enden; dort gilt deshalb ::-webkit-scrollbar. */
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-color: var(--scroll-daumen) transparent; scrollbar-width: thin; }
  *:hover { scrollbar-color: var(--scroll-daumen-hover) transparent; }
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--scroll-daumen);
  border-radius: 10px;
  /* Der durchsichtige Rand macht den Daumen schmaler als die Leiste -- er schwebt. */
  border: 3px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--scroll-daumen-hover); }
::-webkit-scrollbar-button { display: none; }

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

/* ── App shell: fixed sidebar + scrolling main ─────────────────────── */
body { display: flex; min-height: 100vh; }

.app-sidebar {
  flex: 0 0 244px;
  width: 244px;
  background: var(--color-bg-elevated);
  border-right: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  /* The current-page marker sits at left:-12px, outside the link's own
     box, which otherwise gives the column its own horizontal scrollbar. */
  overflow-x: hidden;
}
/* A hairline of forge light down the sidebar's edge -- the one ambient
   trace of the ember accent present on every page. */
.app-sidebar::after {
  content: "";
  position: absolute; top: 0; bottom: 0; right: -1px; width: 1px;
  background: linear-gradient(180deg, transparent, rgba(var(--color-ember-rgb), 0.30) 22%, rgba(var(--color-ember-rgb), 0.30) 62%, transparent);
  pointer-events: none;
}

.sidebar-brand {
  display: block;
  padding: 20px 20px 18px;
  border-bottom: 1px solid var(--color-border-subtle);
}
/* Das Logo ist seit Entwurf G ein Bildzeichen mit Schriftzug (341x120,
   Seitenverhaeltnis rund 2,8:1 statt vorher 4,75:1). Bei der alten Hoehe
   von 30px waere das Zeichen kaum zu erkennen, daher hoeher. */
.sidebar-brand img { height: 48px; width: auto; display: block; }

/* Zwei Fassungen des Logos: die dunkle ist Vorgabe, die helle gilt, sobald
   <html data-theme="light"> gesetzt ist. Beide <img> stehen im Markup,
   CSS blendet die unpassende aus -- so wechselt das Logo ohne Skript mit
   dem Theme-Schalter mit. */
.logo-hell { display: none !important; }
:root[data-theme="light"] .logo-dunkel { display: none !important; }
:root[data-theme="light"] .logo-hell { display: block !important; }

.sidebar-nav { flex: 1; padding: 14px 12px; }
.sidebar-group + .sidebar-group { margin-top: 20px; }
.sidebar-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-faint);
  padding: 0 10px 7px;
}
.sidebar-link {
  display: block;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  text-decoration: none;
  font-size: 13.5px;
  position: relative;
}
.sidebar-link:hover { background: var(--color-bg-hover); color: var(--color-text); }
/* Bildzeichen der Hauptpunkte: nur die schmale Chat-Leiste zeigt sie (chat.css). */
.sidebar-icon { display: none; }
/* The current page is the one place ember appears in the sidebar. */
.sidebar-link.is-current { background: var(--color-bg-hover); color: var(--color-text); font-weight: 600; }
.sidebar-link.is-current::before {
  content: "";
  position: absolute; left: -12px; top: 7px; bottom: 7px; width: 2px;
  border-radius: 0 2px 2px 0;
  background: var(--color-ember);
}

.sidebar-foot { padding: 12px; border-top: 1px solid var(--color-border-subtle); }
.sidebar-foot .user-menu-trigger { width: 100%; justify-content: flex-start; }
.sidebar-foot .user-menu-name { flex: 1; text-align: left; }
/* Opens upward -- there is no room below it at the bottom of the column. */
.sidebar-foot .user-menu-panel { top: auto; bottom: calc(100% + 8px); left: 0; right: auto; min-width: 210px; }

.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ── Page head ─────────────────────────────────────────────────────── */
.page-head {
  border-bottom: 1px solid var(--color-border-subtle);
  padding: 20px 32px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}
.page-head h1 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.005em;
}

.container { max-width: 1080px; margin: 28px auto 64px; padding: 0 32px; width: 100%; }

/* ── Section headings ──────────────────────────────────────────────── */
h2 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin-bottom: 14px;
}
h3 { font-size: 15px; font-weight: 600; letter-spacing: 0.01em; }

/* Uppercase micro-label. Used for section eyebrows and table headers --
   the same device in both places so the page reads as one system. */
.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* ── Flashes ───────────────────────────────────────────────────────── */
.flash, .flash-error, .flash-token {
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  margin-bottom: 18px;
  font-size: 13.5px;
  border: 1px solid transparent;
}
.flash { background: var(--color-success-bg); color: var(--color-success); border-color: rgba(95, 191, 139, 0.25); }
.flash-error { background: var(--color-danger-bg); color: var(--color-danger); border-color: rgba(var(--color-danger-rgb), 0.28); }
.flash-token {
  background: var(--color-info-bg); color: var(--color-accent-strong);
  font-family: var(--font-mono); word-break: break-all; border-color: var(--color-border);
}
.flash-token strong { color: var(--color-ember); font-family: var(--font-ui); }
.hint { color: var(--color-text-muted); font-size: 13px; margin: 4px 0 12px; }
.empty {
  text-align: center; padding: 44px 20px; color: var(--color-text-muted);
  border: 1px dashed var(--color-border); border-radius: var(--radius);
}

/* ── Tables ────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; margin-bottom: 24px; }
th, td {
  text-align: left; padding: 11px 14px;
  border-bottom: 1px solid var(--color-border-subtle);
  /* `anywhere` was wrong here: it also shrinks a column's min-content
     width, so real words got hyphen-less broken mid-letter ("NAM E",
     "Beas t") on any table with many columns -- confirmed on the Server
     Manager. `break-word` still breaks a genuinely too-long token (clone
     URL, hash, permission key) but never below a normal word's width. */
  overflow-wrap: break-word;
}
th {
  color: var(--color-text-faint);
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  border-bottom-color: var(--color-border);
}
td { font-size: 13.5px; vertical-align: top; }
tbody tr:hover { background: var(--color-bg-elevated); }
td a { color: var(--color-accent); text-decoration: none; }
td a:hover { color: var(--color-accent-strong); text-decoration: underline; }

/* ── Cards & forms ─────────────────────────────────────────────────── */
.form-card {
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 22px;
}
.form-card h3 { margin-bottom: 16px; color: var(--color-text); }
.form-row { margin-bottom: 14px; }
.form-row label {
  display: block; font-size: 11px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--color-text-faint); margin-bottom: 6px;
}
.form-row input, .form-row select, .form-row textarea {
  width: 100%; padding: 8px 11px;
  background: var(--color-bg-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text); font-size: 14px; font-family: inherit;
}
.form-row textarea { min-height: 64px; }
.form-row input::placeholder, .form-row textarea::placeholder { color: var(--color-text-faint); }
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
  outline: none; border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(var(--color-accent-rgb), 0.16);
}
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.form-grid .form-row.full { grid-column: 1 / -1; }

/* ── Buttons ───────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 15px;
  border: 1px solid var(--color-border);
  background: var(--color-bg-hover);
  color: var(--color-text);
  border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600; font-family: inherit;
  cursor: pointer; text-decoration: none;
}
.btn:hover { border-color: var(--color-text-faint); }
/* Ember = the primary action. Rationed on purpose: at most one per view. */
.btn-green { background: var(--color-btn-green); color: var(--color-btn-text); border-color: transparent; }
.btn-green:hover { background: var(--color-btn-green-hover); border-color: transparent; }
.btn-red { background: transparent; color: var(--color-danger); border-color: rgba(var(--color-danger-rgb), 0.4); }
.btn-red:hover { background: var(--color-danger-bg); border-color: var(--color-danger); }
.btn-blue { background: var(--color-btn-blue); color: var(--color-text); border-color: transparent; }
.btn-blue:hover { background: var(--color-accent); color: var(--color-btn-text); }

.enabled { color: var(--color-success); }
.disabled { color: var(--color-text-faint); }

/* ── Status badges ─────────────────────────────────────────────────── */
.status-badge {
  display: inline-block; padding: 3px 9px;
  border-radius: 999px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
}
.status-queued { background: var(--color-neutral-bg); color: var(--color-neutral-text); }
/* Everything actively in flight wears the forge colour -- that is the
   whole point of rationing ember: if it glows, Yamis is working on it. */
.status-running, .status-planning, .status-stepping, .status-verifying, .status-critic {
  background: var(--color-ember-bg); color: var(--color-ember);
  border-color: rgba(var(--color-ember-rgb), 0.35);
}
.status-escalated { background: var(--color-warning-bg); color: var(--color-warning); }
.status-paused { background: var(--color-neutral-bg); color: var(--color-neutral-text); }
.status-completed { background: var(--color-success-bg); color: var(--color-success); border-color: rgba(95, 191, 139, 0.28); }
.status-failed { background: var(--color-danger-bg); color: var(--color-danger); border-color: rgba(var(--color-danger-rgb), 0.3); }
.status-cancelled { background: var(--color-neutral-bg); color: var(--color-text-faint); }

/* ── User account dropdown (UserMenu.class.php) ────────────────────── */
.user-menu { position: relative; }
.user-menu-trigger {
  display: flex; align-items: center; gap: 7px;
  background: none; border: 1px solid transparent; cursor: pointer;
  color: var(--color-text-muted); font-size: 13.5px; font-family: inherit;
  padding: 6px 10px; border-radius: var(--radius-sm);
}
.user-menu-trigger:hover { background: var(--color-bg-hover); color: var(--color-text); }
.user-menu.open .user-menu-trigger { background: var(--color-bg-hover); color: var(--color-text); border-color: var(--color-border); }
.user-menu-icon { display: flex; color: var(--color-text-faint); }
.user-menu-chevron { display: flex; transition: transform 0.15s ease; }
.user-menu.open .user-menu-chevron { transform: rotate(180deg); }

.user-menu-panel {
  position: absolute; right: 0; top: calc(100% + 8px);
  background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  border-radius: var(--radius); min-width: 232px; padding: 7px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
  z-index: 100;
}
.user-menu-header { padding: 9px 11px 11px; border-bottom: 1px solid var(--color-border); margin-bottom: 6px; }
.user-menu-header-name { font-size: 14px; font-weight: 600; color: var(--color-text); }
.user-menu-header-role {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--color-ember); margin-top: 2px;
}
.user-menu-section-label {
  font-size: 10px; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--color-text-faint);
  padding: 8px 11px 4px;
}
.user-menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 11px; border-radius: var(--radius-sm); border: none; background: none;
  color: var(--color-text); font-size: 13px; font-family: inherit;
  text-decoration: none; cursor: pointer; text-align: left;
}
.user-menu-item:hover { background: var(--color-bg-hover); }
.user-menu-item-icon { display: flex; color: var(--color-text-faint); flex-shrink: 0; }
.user-menu-item-danger:hover { color: var(--color-danger); }
.user-menu-item-danger:hover .user-menu-item-icon { color: var(--color-danger); }
.user-menu-divider { height: 1px; background: var(--color-border); margin: 7px 2px; }

/* Below this the sidebar stops being a column and becomes a normal
   band across the top -- a 244px rail on a phone leaves nothing for the
   actual page. */
@media (max-width: 860px) {
  body { flex-direction: column; }
  .app-sidebar {
    flex: none; width: 100%; height: auto; position: static;
    border-right: none; border-bottom: 1px solid var(--color-border);
  }
  .app-sidebar::after { display: none; }
  .sidebar-brand { padding: 14px 16px 12px; }
  .sidebar-brand img { height: 38px; }
  .sidebar-nav { display: flex; flex-wrap: wrap; gap: 14px; padding: 10px 12px; }
  .sidebar-group + .sidebar-group { margin-top: 0; }
  .sidebar-group { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
  .sidebar-group-label { padding: 0 8px 0 0; }
  .sidebar-link.is-current::before { display: none; }
  .sidebar-link.is-current { box-shadow: inset 0 -2px 0 var(--color-ember); }
  .sidebar-foot .user-menu-panel { top: calc(100% + 8px); bottom: auto; right: 0; left: auto; }
  .page-head { padding: 16px 16px 14px; }
  .container { margin: 20px auto 48px; padding: 0 16px; }
  .form-grid { grid-template-columns: 1fr; }

  /* ── Tabellen auf schmalen Geraeten ──────────────────────────────
     Eine Tabelle mit acht Spalten passt auf kein Telefon. Bisher zog
     sie die GANZE Seite in die Breite: gemessen 1035 px bei den
     Projekten, 1117 bei den Servern, 751 bei den Benutzern - auf einem
     390 px breiten Bildschirm. Man scrollte also die Seite samt
     Navigation zur Seite, um eine Spalte zu lesen, und fand danach den
     Weg zurueck nicht.

     Jetzt scrollt die Tabelle IN SICH. Der Rest der Seite bleibt, wo er
     ist. `display: block` macht aus ihr den Scrollkasten; die Zeilen
     ordnen sich innen weiter als Tabelle an. */
  body table {
    display: block;
    overflow-x: auto;
    max-width: 100%;
  }

  /* ── Tippziele ───────────────────────────────────────────────────
     Ein Ziel von 30 Pixeln trifft man mit dem Finger nicht zuverlaessig;
     44 sind die uebliche Untergrenze. Gemessen waren auf jeder Seite
     zwischen 16 und 105 Bedienelemente darunter. Nur bei grobem
     Zeigegeraet (Finger) - mit der Maus bleibt alles kompakt. */
  body .btn, body button, body .sidebar-link {
    min-height: 44px;
  }
  body input:not([type="checkbox"]):not([type="radio"]), body select, body textarea {
    min-height: 44px;
    /* 16px verhindert, dass iOS beim Antippen hineinzoomt. */
    font-size: 16px;
  }
  /* 24 statt 22: das ist die Untergrenze aus WCAG 2.2 fuer ein
     Bedienelement. Und weil ein Haken selten allein steht, wird die
     Beschriftung drumherum mitgezaehlt - sie ist die Flaeche, die man
     tatsaechlich trifft. */
  body input[type="checkbox"], body input[type="radio"] {
    width: 24px; height: 24px;
  }
  body label:has(> input[type="checkbox"]),
  body label:has(> input[type="radio"]) {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
  }

  /* Kleinstschrift ist auf einem Telefon nicht mehr lesbar. Gemessen
     waren es bis zu 92 Stellen je Seite - Statusmarken bei 11 px,
     Gruppenbeschriftungen bei 10. Am Schreibtisch mag das elegant sein,
     in der Hand ist es Ratespiel. */
  body .muted, body small, body code, body kbd,
  body .stat-label, body .status-badge, body .badge, body .eyebrow,
  body .sidebar-group-label, body .user-menu-header-role,
  body .project-type, body .project-mr, body .rule-meta, body .rule-tag,
  body th, body label {
    font-size: max(12px, 0.86rem);
  }

  /* ── Trefferflaeche fuer Links in Tabellen ───────────────────────
     Die Aufgabennummern ("#162") sind der Weg in eine Aufgabe hinein -
     und waren 33x16 Pixel gross. Statt die Zeilen aufzublaehen bekommt
     der Link Innenabstand und gibt ihn per negativem Aussenabstand
     wieder her: die Flaeche waechst, das Aussehen bleibt. */
  body td a, body th a, body a.num {
    display: inline-block;
    padding: 12px 6px;
    margin: -12px -6px;
  }

  /* Dieselbe Ueberlegung fuer die uebrigen kleinen Linkflaechen:
     Filterknoepfe ueber einer Liste, die Eintraege im Wiki-Verzeichnis. */
  body a.filter, body .wiki-sidebar-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* Ein Dialog nimmt auf dem Telefon die volle Breite. */
  dialog {
    width: calc(100vw - 16px);
    max-height: calc(100vh - 32px);
    padding: 18px 16px;
  }
  .dialog-fuss { flex-direction: column-reverse; }
  .dialog-fuss .btn { width: 100%; justify-content: center; }
}

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

/* ── Dialoge und Listenköpfe ───────────────────────────────────────────
   Seltene Formulare gehören nicht dauerhaft über die Liste, die man
   eigentlich sehen will. Das eingebaute <dialog> bringt Fokusfalle,
   Escape und die richtige Rolle für Screenreader mit — hier steht nur
   das Aussehen. */
.listen-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 8px 0 12px;
  flex-wrap: wrap;
}
.listen-kopf h2 { margin: 0; font-size: 1.15rem; }

dialog {
  border: 1px solid var(--color-border);
  border-radius: 10px;
  background: var(--color-bg-elevated);
  color: var(--color-text);
  padding: 24px 26px;
  width: min(560px, calc(100vw - 32px));
  /* Ein Dialog, der länger ist als das Fenster, muss in sich scrollen —
     sonst ist der Absenden-Knopf unerreichbar. Genau der Fehler, den
     diese Änderung auf der Seite selbst behebt. */
  max-height: min(86vh, 900px);
  overflow-y: auto;
}
dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
dialog h3 { margin-top: 0; }
.dialog-fuss {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border-subtle);
}

/* Text, der nur vorgelesen wird.
   Ein Knopf mit der Aufschrift "Übernehmen" ist in einer Tabelle mit
   sechs Zeilen mehrdeutig: übernehmen wofür? Sehende sehen die Zeile,
   ein Screenreader liest den Knopf allein vor. Diese Ergänzung schließt
   die Lücke, ohne die Oberfläche zu verändern.
   Nicht `display:none` — das würde auch das Vorlesen unterbinden. */
.nur-vorlesen {
  /* OHNE position: absolute.
     Die uebliche Rezeptur fuer "nur vorlesen" arbeitet mit absoluter
     Positionierung. Innerhalb einer breiten Tabelle mit eigenem
     Scrollkasten ist das falsch: ein absolut positioniertes Element
     entkommt dem Kasten, wenn dieser nicht selbst positioniert ist, und
     landet an seiner rechnerischen Stelle im Dokument. Auf dem Telefon
     zog das die Modellseite auf 3076 statt 375 Pixel Breite - achtfache
     Breite, waagerechtes Scrollen ueber die ganze Seite.
     Als Inline-Element mit 1x1 Pixel bleibt der Text im Fluss, wird
     vorgelesen und schiebt nichts. */
  display: inline-block;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  vertical-align: middle;
}

/* "Mehr" in der Seitenleiste: eingeklappt, oeffnet sich per Klick oder von
   selbst, wenn man auf einer seiner Seiten ist (AppNav). */
.sidebar-mehr > summary { cursor: pointer; list-style: none; user-select: none; }
.sidebar-mehr > summary::-webkit-details-marker { display: none; }
.sidebar-mehr > summary::after { content: ' ▸'; opacity: .6; }
.sidebar-mehr[open] > summary::after { content: ' ▾'; }
.sidebar-group + .sidebar-mehr, .sidebar-mehr + .sidebar-group { margin-top: 20px; }

/* ══ HALLE (22.10.2026) ═══════════════════════════════════════════════
   Die Schicht ueber allem Vorigen: Buehne, Leiste, Knoepfe, Felder,
   Tafeln. Steht bewusst am Ende -- die Seiten-Stylesheets bauen auf den
   Variablen auf und ziehen damit von selbst mit. */

html { background: var(--color-bg); }
body {
  font-family: var(--font-ui);
  font-size: 14.5px;
  background: var(--halle-licht), var(--color-bg);
  background-attachment: fixed;
}
.num, td .num, .mono { font-family: var(--font-mono); }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Links ohne eigene Gestaltung: Reif statt Browserblau. */
.app-main a:not([class]) { color: var(--color-accent); text-decoration: none; }
.app-main a:not([class]):hover { color: var(--color-accent-strong); text-decoration: underline; }

/* Wortmarke: YAMIS in Michroma, das A in Glut -- wie im Logo. */
.wortmarke {
  font-family: var(--font-display); font-weight: 400; letter-spacing: .38em;
  color: var(--color-text); white-space: nowrap; line-height: 1;
}
.wortmarke .glut-a { color: var(--color-ember); }

/* ── Leiste ── */
.app-sidebar {
  flex: 0 0 var(--rail-breite); width: var(--rail-breite);
  background: var(--halle-leiste);
  border-right: 1px solid var(--color-border-subtle);
}
.app-sidebar::after { display: none; }
.sidebar-brand {
  display: flex; align-items: center; gap: 12px;
  padding: 20px 22px 18px; border-bottom: 0; text-decoration: none;
}
.sidebar-brand img { height: 36px; width: 36px; }
.sidebar-brand .wortmarke { font-size: 15px; }
.sidebar-nav { padding: 6px 14px 14px; }
.sidebar-group + .sidebar-group, .sidebar-group + .sidebar-mehr, .sidebar-mehr + .sidebar-group { margin-top: 18px; }
.sidebar-group-label {
  font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: var(--color-text-faint); padding: 0 10px 6px;
}
.sidebar-link {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 10px; border-radius: 9px; font-size: 14px; color: var(--color-text-muted);
}
.sidebar-link:hover { background: rgba(var(--color-accent-rgb), .06); color: var(--color-text); }
.sidebar-link.is-current {
  background: rgba(var(--color-accent-rgb), .09); color: var(--color-text); font-weight: 500;
  box-shadow: inset 2px 0 0 var(--color-ember);
}
.sidebar-link.is-current::before { display: none; }
.sidebar-icon { display: inline-flex; flex: none; opacity: .8; }
.sidebar-icon svg { width: 18px; height: 18px; }
.sidebar-mehr > summary::after { content: ''; display: inline-block; width: 6px; height: 6px; margin-left: 8px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg) translateY(-1px); opacity: .6; }
.sidebar-mehr[open] > summary::after { content: ''; transform: rotate(45deg) translateY(-3px); }
.sidebar-platz, .sidebar-alle { display: none; }

.sidebar-foot { padding: 10px 14px 14px; border-top: 1px solid var(--color-border-subtle); }

/* ── Konto unten in der Leiste ── */
.user-menu-trigger { gap: 10px; padding: 8px 8px; border-radius: 10px; color: var(--color-text); }
.user-menu-bild {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-weight: 600; font-size: 13px; color: var(--color-accent);
  background: var(--color-bg-hover); border: 1px solid var(--color-border);
}
.user-menu-wer { display: flex; flex-direction: column; min-width: 0; text-align: left; line-height: 1.25; }
.user-menu-wer small { font-size: 12px; color: var(--color-text-faint); }
.user-menu-panel {
  background: var(--halle-tafel), var(--color-bg-elevated); border-color: var(--color-border);
  border-radius: 14px; box-shadow: var(--edge), var(--deep);
}
.user-menu-header-role { font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; }

/* ── Seitenkopf und Ueberschriften ── */
.page-head { border-bottom: 0; padding: 30px 40px 6px; }
.page-head h1 { font-family: var(--font-display); font-size: 23px; font-weight: 400; letter-spacing: .04em; }
.container { margin-top: 22px; }
h2 { font-family: var(--font-ui); font-size: 18px; font-weight: 600; letter-spacing: 0; }
.eyebrow, th, .form-row label, .user-menu-section-label {
  text-transform: none; letter-spacing: 0;
}
.eyebrow { font-size: 13px; font-weight: 500; color: var(--color-text-faint); }
th { font-size: 12.5px; font-weight: 500; }

/* ── Tafeln ── */
.form-card, dialog {
  background: var(--halle-tafel), var(--color-bg-elevated);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-panel);
  box-shadow: var(--edge), var(--deep);
}
tbody tr:hover { background: rgba(var(--color-accent-rgb), .04); }

/* ── Felder ── */
.form-row label { font-size: 13px; font-weight: 500; color: var(--color-text-muted); }
.form-row input, .form-row select, .form-row textarea {
  padding: 10px 13px; border-radius: 11px;
  background: var(--halle-feld); border: 1px solid var(--color-border);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .35);
}
:root[data-theme="light"] .form-row input, :root[data-theme="light"] .form-row select, :root[data-theme="light"] .form-row textarea { box-shadow: inset 0 1px 2px rgba(20, 45, 80, .06); }
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
  border-color: rgba(var(--color-accent-rgb), .55);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .35), 0 0 0 4px rgba(var(--color-accent-rgb), .10);
}

/* ── Knoepfe ── */
.btn {
  padding: 8px 16px; border-radius: 11px; font-weight: 500; letter-spacing: .01em;
  background: rgba(var(--color-accent-rgb), .05); border: 1px solid var(--color-border);
  transition: background .15s, border-color .15s, filter .15s;
}
.btn:hover { background: rgba(var(--color-accent-rgb), .09); border-color: rgba(var(--color-accent-rgb), .32); }
/* Haupthandlung: geschliffene Glut statt flaches Orange. */
.btn-green, .btn-glut {
  color: #1B1204; font-weight: 600;
  background: var(--glut-knopf); border: 1px solid rgba(255, 226, 160, .55);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .35), 0 8px 26px -10px rgba(var(--color-ember-rgb), .6), inset 0 -2px 0 rgba(120, 60, 0, .3);
}
.btn-green:hover, .btn-glut:hover { background: var(--glut-knopf); border-color: rgba(255, 226, 160, .7); filter: brightness(1.06); }
.btn-blue { background: rgba(var(--color-accent-rgb), .1); color: var(--color-text); border-color: rgba(var(--color-accent-rgb), .3); }
.btn-blue:hover { background: rgba(var(--color-accent-rgb), .18); color: var(--color-text); }

.status-badge { font-family: var(--font-ui); font-weight: 500; letter-spacing: 0; font-size: 12px; }

/* ── Handy: Kopfleiste mit Schublade statt Navigationsblock ── */
.app-kopfleiste, .nav-schleier { display: none; }
@media (max-width: 860px) {
  .app-kopfleiste {
    display: flex; align-items: center; gap: 10px; position: sticky; top: 0; z-index: 30;
    min-height: 56px; padding: 6px 10px; padding-top: max(6px, env(safe-area-inset-top));
    background: var(--halle-leiste); border-bottom: 1px solid var(--color-border-subtle);
    backdrop-filter: blur(12px);
  }
  .app-kopfleiste .kopf-knopf {
    display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px;
    border: 0; border-radius: 12px; background: none; color: var(--color-text-muted); cursor: pointer;
  }
  .app-kopfleiste .kopf-marke { display: flex; align-items: center; gap: 10px; text-decoration: none; }
  .app-kopfleiste .kopf-marke img { width: 30px; height: 30px; }
  .app-kopfleiste .wortmarke { font-size: 13px; }

  /* Die Leiste selbst wird zur Schublade von links (Werte von oben zurueck). */
  .app-sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 60;
    width: min(300px, 86vw); height: auto; flex: none; overflow-y: auto;
    border-right: 1px solid var(--color-border); border-bottom: 0;
    transform: translateX(-102%); visibility: hidden; transition: transform .2s ease, visibility .2s;
    background: var(--halle-leiste), var(--color-bg); /* Schublade: voll deckend */
  }
  body.nav-offen .app-sidebar { transform: none; visibility: visible; box-shadow: 10px 0 30px rgba(0, 0, 0, .45); }
  .sidebar-nav { display: block; padding: 6px 14px 14px; }
  .sidebar-group { display: block; }
  .sidebar-group + .sidebar-group, .sidebar-group + .sidebar-mehr, .sidebar-mehr + .sidebar-group { margin-top: 16px; }
  .sidebar-group-label { padding: 0 10px 6px; }
  .sidebar-link.is-current { box-shadow: inset 2px 0 0 var(--color-ember); }
  .sidebar-foot .user-menu-panel { top: auto; bottom: calc(100% + 8px); left: 0; right: auto; }
  .nav-schleier {
    display: block; position: fixed; inset: 0; z-index: 55; background: rgba(0, 0, 0, .5);
    opacity: 0; pointer-events: none; transition: opacity .2s ease;
  }
  body.nav-offen .nav-schleier { opacity: 1; pointer-events: auto; }
  .page-head { padding: 20px 16px 4px; }
  .page-head h1 { font-size: 19px; }
}

/* ── Sprachwahl der oeffentlichen Seiten (Seitensprache, 25.10.2026) ──
   Flagge oben rechts, ohne JavaScript als <details>. */
.sprachwahl { position: relative; font-size: 14px; }
.sprachwahl summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 9px; color: var(--color-text-muted);
  border: 1px solid var(--color-border-subtle); background: var(--color-bg-elevated);
}
.sprachwahl summary::-webkit-details-marker { display: none; }
.sprachwahl-flagge { font-size: 17px; line-height: 1; }
.sprachwahl-code { font-size: 12px; letter-spacing: .06em; }
.sprachwahl ul {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; min-width: 170px; margin: 0; padding: 6px;
  list-style: none; background: var(--color-bg-elevated); border: 1px solid var(--color-border);
  border-radius: 12px; box-shadow: var(--deep, 0 12px 40px rgba(0,0,0,.4));
}
.sprachwahl li a {
  display: block; padding: 8px 10px; border-radius: 8px; color: var(--color-text); text-decoration: none; white-space: nowrap;
}
.sprachwahl li a:hover, .sprachwahl li a[aria-current="true"] { background: var(--color-bg-hover); }
