Design-System Sprint A: utilities.css + 948 Inline-Styles → Utility-Klassen, SW by-v1102

PHASE 1 — Sofort-Cleanup ohne Risiko:
- Neue Datei utilities.css mit ~25 Klassen für häufige Kombinationen:
  * text-xs-muted, text-xs-secondary, text-sm-muted, text-sm-secondary
  * flex-gap-2/3, flex-col-gap-2/3/4, flex-center-gap-1/2/3
  * flex-between, flex-1-min, mb-1/3, mt-1/3
  * icon-xs/sm/md/lg, label-block, caption
- index.html bindet utilities.css ein
- mb-3/mt-3 ergänzt (waren in design-system.css unvollständig)

PHASE 2 — .by-tab Modifier für Vereinheitlichung:
- .by-tabs.grid (mit --tab-cols Variable für Admin/Health/etc.)
- .by-tabs.sticky (Desktop vertikale Tabs für Admin)
- .by-tabs.wrap (Zuchthunde, flex-wrap statt scroll)
- .by-tabs.separated (Sitting, mit eigenem Hintergrund + Border)

PHASE 3 — Inline-Style → Klassen-Migration (Python-Script):
- 948 Inline-Styles entfernt (5101 → 4153, -18%)
- 962 Migrationen über 47 Page-Dateien
- Top-Treffer: admin.js (180), health.js (67), dog-profile.js (67),
  litters.js (62), settings.js (61), zuchthunde.js (51)
- Patterns: text-muted, text-secondary, text-danger, text-xs-muted,
  text-sm-muted, grid-2 (Duplikat-Bug behoben!), flex-col-gap-3,
  p-3/4, mb-2/3/4, hidden, w-full, flex-1, ...
- Bewahrt bestehende class-Attribute (mergt korrekt)

Alle 19 Tests grün. Kein visueller Diff erwartet (gleiche Property-Werte).
This commit is contained in:
rene 2026-05-27 07:11:27 +02:00
parent 279f76714e
commit 459cd425f2
54 changed files with 1809 additions and 956 deletions

View file

@ -118,7 +118,7 @@ window.Page_litters = (() => {
padding:var(--space-3) var(--space-4);
display:flex;align-items:center;gap:var(--space-3)">
${logoHtml}
<div style="flex:1;min-width:0">
<div class="flex-1-min">
<h2 style="margin:0 0 2px;font-size:var(--text-lg);font-weight:700;
color:var(--c-text);white-space:nowrap;overflow:hidden;
text-overflow:ellipsis;line-height:1.2">${_esc(zwinger)}</h2>
@ -126,7 +126,7 @@ window.Page_litters = (() => {
<svg style="width:11px;height:11px;color:var(--c-primary);flex-shrink:0" viewBox="0 0 256 256">
<use href="/icons/phosphor.svg#lock-key"></use>
</svg>
<span style="font-size:var(--text-xs);color:var(--c-text-secondary)">Privater Bereich · Nur du siehst das</span>
<span class="text-xs-secondary">Privater Bereich · Nur du siehst das</span>
</div>
</div>
</div>`;
@ -232,7 +232,7 @@ window.Page_litters = (() => {
el.innerHTML = `
<div style="text-align:center;padding:var(--space-8) var(--space-4);
border:1px dashed var(--c-border);border-radius:var(--radius-lg)">
<p style="color:var(--c-text-muted)">Keine Würfe für diesen Filter.</p>
<p class="text-muted">Keine Würfe für diesen Filter.</p>
</div>`;
return;
}
@ -248,8 +248,8 @@ window.Page_litters = (() => {
el.innerHTML = `
<div style="text-align:center;padding:var(--space-10) var(--space-4)">
<div style="font-size:3rem;margin-bottom:var(--space-3)">${UI.icon('dog')}</div>
<p style="color:var(--c-text-secondary)">Noch keine Würfe angelegt.</p>
<button class="btn btn-primary" style="margin-top:var(--space-4)" id="litters-first-btn">
<p class="text-secondary">Noch keine Würfe angelegt.</p>
<button class="btn btn-primary mt-4" id="litters-first-btn">
${UI.icon('plus')} Ersten Wurf anlegen
</button>
</div>`;
@ -325,10 +325,10 @@ window.Page_litters = (() => {
const label = l.geburt_datum ? `Geburt ${_fmtDate(l.geburt_datum)}` : `Erwartet ${_fmtDate(l.erwartetes_datum)}`;
let countdownHtml = '';
if (days !== null && !l.geburt_datum) {
const c = days < 0 ? `<span style="color:var(--c-danger)">überfällig</span>`
: days === 0 ? `<span style="color:var(--c-success)">heute!</span>`
const c = days < 0 ? `<span class="text-danger">überfällig</span>`
: days === 0 ? `<span class="text-success">heute!</span>`
: days <= 7 ? `<span style="color:var(--c-warning,#f59e0b)">${days}d</span>`
: `<span style="color:var(--c-text-muted)">${days}d</span>`;
: `<span class="text-muted">${days}d</span>`;
countdownHtml = ` · ${c}`;
}
datumChip = `<span style="display:inline-flex;align-items:center;gap:4px;font-size:var(--text-xs);color:var(--c-text-secondary)">${UI.icon('calendar-dots')} ${label}${countdownHtml}</span>`;
@ -359,7 +359,7 @@ window.Page_litters = (() => {
${l.wurf_name ? `<span style="font-size:var(--text-base);font-weight:700;color:var(--c-text)">${_esc(l.wurf_name)}</span>` : ''}
</div>` : ''}
<div style="display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;margin-bottom:var(--space-2)">
<span style="font-size:var(--text-sm);color:var(--c-text-secondary)">${elternLabel}</span>
<span class="text-sm-secondary">${elternLabel}</span>
${_statusBadge(l.status)}
${sichtbarChip}
</div>
@ -390,7 +390,7 @@ window.Page_litters = (() => {
${UI.icon('pencil-simple')}
</button>
<button class="btn btn-ghost btn-sm litters-delete-btn" data-id="${l.id}" title="Löschen"
style="color:var(--c-danger)">
class="text-danger">
${UI.icon('trash')}
</button>
</div>
@ -401,10 +401,10 @@ window.Page_litters = (() => {
<!-- Welpen-Bereich -->
<div id="puppies-wrap-${l.id}" style="display:none;padding:var(--space-3) var(--space-4)">
<div id="puppies-inner-${l.id}">
<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Lädt</p>
<p class="text-sm-muted">Lädt</p>
</div>
<button class="btn btn-secondary btn-sm litters-add-puppy-btn" data-id="${l.id}"
style="margin-top:var(--space-3)">
class="mt-3">
${UI.icon('plus')} Welpen hinzufügen
</button>
</div>
@ -412,10 +412,10 @@ window.Page_litters = (() => {
<!-- Wartelisten-Bereich -->
<div id="waitlist-wrap-${l.id}" style="display:none;padding:var(--space-3) var(--space-4)">
<div id="waitlist-inner-${l.id}">
<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Lädt</p>
<p class="text-sm-muted">Lädt</p>
</div>
<button class="btn btn-secondary btn-sm litters-add-waitlist-btn" data-id="${l.id}"
style="margin-top:var(--space-3)">
class="mt-3">
${UI.icon('plus')} Interessent eintragen
</button>
</div>
@ -461,7 +461,7 @@ window.Page_litters = (() => {
function _renderPuppies(container, litterId, puppies) {
if (!puppies.length) {
container.innerHTML = `<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Noch keine Welpen eingetragen.</p>`;
container.innerHTML = `<p class="text-sm-muted">Noch keine Welpen eingetragen.</p>`;
return;
}
@ -469,10 +469,10 @@ window.Page_litters = (() => {
<div class="litters-puppy-row" data-puppy-id="${p.id}">
<div class="litters-puppy-info">
${_genderIcon(p.geschlecht)}
<span class="litters-puppy-name">${p.name ? _esc(p.name) : '<em style="color:var(--c-text-muted)">Unbenannt</em>'}</span>
<span class="litters-puppy-name">${p.name ? _esc(p.name) : '<em class="text-muted">Unbenannt</em>'}</span>
${p.farbe ? `<span style="color:var(--c-text-secondary);font-size:var(--text-xs)">${_esc(p.farbe)}</span>` : ''}
${_puppyStatusBadge(p.status)}
<span class="litters-puppy-last-weight" id="puppy-last-weight-${p.id}" style="font-size:var(--text-xs);color:var(--c-text-secondary)"></span>
<span class="litters-puppy-last-weight" id="puppy-last-weight-${p.id}" class="text-xs-secondary"></span>
</div>
<div class="litters-puppy-actions">
<button class="btn btn-ghost btn-xs litters-puppy-photo-btn" data-litter-id="${litterId}" data-puppy-id="${p.id}"
@ -542,16 +542,16 @@ window.Page_litters = (() => {
const puppyLabel = puppy.name || 'Welpe';
const body = `
<div id="weight-history" style="margin-bottom:var(--space-3)">
<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Lädt</p>
<div id="weight-history" class="mb-3">
<p class="text-sm-muted">Lädt</p>
</div>
<hr style="margin:var(--space-3) 0;border:none;border-top:1px solid var(--c-border)">
<form id="weight-form" style="display:flex;gap:var(--space-2);align-items:flex-end">
<div style="flex:1">
<div class="flex-1">
<label style="display:block;font-size:var(--text-xs);color:var(--c-text-secondary);margin-bottom:var(--space-1)">Gewicht (g)</label>
<input class="form-control" name="gewicht_g" type="number" min="1" max="99999" step="1" required placeholder="z. B. 420">
</div>
<div style="flex:1">
<div class="flex-1">
<label style="display:block;font-size:var(--text-xs);color:var(--c-text-secondary);margin-bottom:var(--space-1)">Datum</label>
<input class="form-control" name="gemessen_am" type="date" required value="${today}">
</div>
@ -600,7 +600,7 @@ window.Page_litters = (() => {
try {
const weights = await API.get(`/litters/puppies/${puppyId}/weights`);
if (!weights || !weights.length) {
el.innerHTML = `<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Noch keine Messungen eingetragen.</p>`;
el.innerHTML = `<p class="text-sm-muted">Noch keine Messungen eingetragen.</p>`;
return;
}
@ -630,22 +630,22 @@ window.Page_litters = (() => {
el.innerHTML = `
<!-- Stats-Zeile -->
<div style="display:flex;gap:var(--space-3);flex-wrap:wrap;margin-bottom:var(--space-3)">
<div style="text-align:center">
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">Aktuell</div>
<div class="text-center">
<div class="text-xs-muted">Aktuell</div>
<div style="font-size:var(--text-base);font-weight:700;color:var(--c-primary)">${last} g</div>
</div>
<div style="text-align:center">
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">Zunahme</div>
<div class="text-center">
<div class="text-xs-muted">Zunahme</div>
<div style="font-size:var(--text-base);font-weight:700;color:${gain >= 0 ? 'var(--c-success)' : 'var(--c-danger)'}">
${gain >= 0 ? '+' : ''}${gain} g
</div>
</div>
<div style="text-align:center">
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">Ø tägl.</div>
<div class="text-center">
<div class="text-xs-muted">Ø tägl.</div>
<div style="font-size:var(--text-base);font-weight:700;color:var(--c-text)">${dailyGain} g</div>
</div>
<div style="text-align:center">
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">Messungen</div>
<div class="text-center">
<div class="text-xs-muted">Messungen</div>
<div style="font-size:var(--text-base);font-weight:700;color:var(--c-text)">${weights.length}</div>
</div>
</div>
@ -764,22 +764,22 @@ window.Page_litters = (() => {
<div style="text-align:center;padding:var(--space-6) var(--space-4);border:1px dashed var(--c-border);border-radius:var(--radius-md)">
<div style="font-size:2rem;margin-bottom:var(--space-2)">${UI.icon('users')}</div>
<p style="font-weight:600;font-size:var(--text-sm);color:var(--c-text);margin-bottom:var(--space-1)">Noch keine Interessenten</p>
<p style="font-size:var(--text-xs);color:var(--c-text-muted)">Trage Anfragen ein mit Wunsch-Geschlecht, Kontaktdaten und Status.</p>
<p class="text-xs-muted">Trage Anfragen ein mit Wunsch-Geschlecht, Kontaktdaten und Status.</p>
</div>`;
return;
}
container.innerHTML = header + `
<div style="display:flex;flex-direction:column;gap:var(--space-2)">
<div class="flex-col-gap-2">
${entries.map((e, i) => `
<div style="background:var(--c-bg-secondary);border-radius:var(--radius-md);padding:var(--space-3) var(--space-3);display:flex;gap:var(--space-3);align-items:flex-start" data-entry-id="${e.id}">
<div style="background:var(--c-primary);color:white;border-radius:50%;width:1.6rem;height:1.6rem;display:flex;align-items:center;justify-content:center;font-size:var(--text-xs);font-weight:700;flex-shrink:0;margin-top:2px">${i + 1}</div>
<div style="flex:1;min-width:0">
<div class="flex-1-min">
<div style="display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;margin-bottom:var(--space-1)">
<span style="font-weight:600;font-size:var(--text-sm)">${_esc(e.name)}</span>
${_wlStatusBadge(e.status)}
${e.wunsch_geschlecht && e.wunsch_geschlecht !== 'egal' ? `<span style="font-size:var(--text-xs);color:var(--c-text-secondary)">${e.wunsch_geschlecht === 'maennlich' ? '♂ Rüde' : '♀ Hündin'}</span>` : ''}
${e.wunsch_farbe ? `<span style="font-size:var(--text-xs);color:var(--c-text-secondary)">${_esc(e.wunsch_farbe)}</span>` : ''}
${e.wunsch_geschlecht && e.wunsch_geschlecht !== 'egal' ? `<span class="text-xs-secondary">${e.wunsch_geschlecht === 'maennlich' ? '♂ Rüde' : '♀ Hündin'}</span>` : ''}
${e.wunsch_farbe ? `<span class="text-xs-secondary">${_esc(e.wunsch_farbe)}</span>` : ''}
</div>
<div style="display:flex;gap:var(--space-4);flex-wrap:wrap;font-size:var(--text-xs);color:var(--c-text-secondary)">
${e.email ? `<span>${UI.icon('envelope')} ${_esc(e.email)}</span>` : ''}
@ -791,7 +791,7 @@ window.Page_litters = (() => {
</div>
<div style="display:flex;gap:var(--space-1);flex-shrink:0">
<button class="btn btn-ghost btn-xs wl-edit-btn" data-entry-id="${e.id}" title="Bearbeiten">${UI.icon('pencil-simple')}</button>
<button class="btn btn-ghost btn-xs wl-delete-btn" data-entry-id="${e.id}" title="Entfernen" style="color:var(--c-danger)">${UI.icon('trash')}</button>
<button class="btn btn-ghost btn-xs wl-delete-btn" data-entry-id="${e.id}" title="Entfernen" class="text-danger">${UI.icon('trash')}</button>
</div>
</div>`).join('')}
</div>`;
@ -820,12 +820,12 @@ window.Page_litters = (() => {
UI.modal.open({
title: isEdit ? 'Interessent bearbeiten' : 'Interessent eintragen',
body: `
<form id="wl-form" style="display:flex;flex-direction:column;gap:var(--space-3)">
<form id="wl-form" class="flex-col-gap-3">
<div class="form-group">
<label class="form-label">Name *</label>
<input class="form-control" name="name" required value="${_esc(v.name || '')}">
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">E-Mail</label>
<input class="form-control" type="email" name="email" value="${_esc(v.email || '')}">
@ -835,7 +835,7 @@ window.Page_litters = (() => {
<input class="form-control" name="telefon" value="${_esc(v.telefon || '')}">
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">Wunsch Geschlecht</label>
<select class="form-control" name="wunsch_geschlecht">
@ -853,7 +853,7 @@ window.Page_litters = (() => {
<label class="form-label">Nachricht des Interessenten</label>
<textarea class="form-control" name="nachricht" rows="2" placeholder="Was hat der Interessent geschrieben?">${_esc(v.nachricht || '')}</textarea>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">Status</label>
<select class="form-control" name="status">
@ -922,7 +922,7 @@ window.Page_litters = (() => {
return `<option value="${h.id}" data-name="${_esc(h.name)}" ${currentId == h.id ? 'selected' : ''}>${_esc(label)}</option>`;
}).join('');
return `
<select class="form-control" name="${idName}" id="${idName}-sel" style="margin-bottom:var(--space-2)">
<select class="form-control" name="${idName}" id="${idName}-sel" class="mb-2">
<option value=""> ${placeholder} </option>
${opts}
</select>
@ -953,7 +953,7 @@ window.Page_litters = (() => {
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">Vater</label>
${buildSelect('vater_name', 'vater_id', maennlich, v.vater_id, v.vater_name, 'Aus Zuchtkartei')}
@ -979,7 +979,7 @@ window.Page_litters = (() => {
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">Welpen gesamt</label>
<input class="form-control" type="number" name="welpen_gesamt" min="0"
@ -1009,13 +1009,13 @@ window.Page_litters = (() => {
</div>
<div class="form-group">
<label class="form-label">Beschreibung <span style="color:var(--c-text-secondary)">(optional)</span></label>
<label class="form-label">Beschreibung <span class="text-secondary">(optional)</span></label>
<textarea class="form-control" name="beschreibung" rows="3"
placeholder="Elternlinie, Besonderheiten, Charakter…">${_esc(v.beschreibung || '')}</textarea>
</div>
<div class="form-group">
<label class="form-label">Gesundheitstests <span style="color:var(--c-text-secondary)">(optional)</span></label>
<label class="form-label">Gesundheitstests <span class="text-secondary">(optional)</span></label>
<textarea class="form-control" name="gesundheitstests" rows="2"
placeholder="HD, ED, Gentest, Augenkontrolle…">${_esc(v.gesundheitstests || '')}</textarea>
</div>
@ -1028,7 +1028,7 @@ window.Page_litters = (() => {
</div>
<div class="form-group">
<label class="form-label">Sichtbar bis <span style="color:var(--c-text-secondary)">(optional)</span></label>
<label class="form-label">Sichtbar bis <span class="text-secondary">(optional)</span></label>
<input class="form-control" type="date" name="sichtbar_bis"
value="${_esc(v.sichtbar_bis || '')}">
</div>
@ -1134,9 +1134,9 @@ window.Page_litters = (() => {
const body = `
<form id="puppy-form" autocomplete="off">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">Name <span style="color:var(--c-text-secondary)">(optional)</span></label>
<label class="form-label">Name <span class="text-secondary">(optional)</span></label>
<input class="form-control" type="text" name="name"
value="${_esc(v.name || '')}" placeholder="z. B. Max">
</div>
@ -1165,7 +1165,7 @@ window.Page_litters = (() => {
</select>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)">
<div class="grid-2">
<div class="form-group">
<label class="form-label">Chip-Nr.</label>
<input class="form-control" type="text" name="chip_nr"
@ -1186,7 +1186,7 @@ window.Page_litters = (() => {
</div>
<div class="form-group">
<label class="form-label">Notiz <span style="color:var(--c-text-secondary)">(intern)</span></label>
<label class="form-label">Notiz <span class="text-secondary">(intern)</span></label>
<textarea class="form-control" name="notiz" rows="2"
placeholder="Interne Notizen…">${_esc(v.notiz || '')}</textarea>
</div>
@ -1249,22 +1249,22 @@ window.Page_litters = (() => {
const body = `
<form id="contract-form" autocomplete="off">
<div class="form-group">
<label class="form-label">Name des Käufers <span style="color:var(--c-danger)">*</span></label>
<label class="form-label">Name des Käufers <span class="text-danger">*</span></label>
<input class="form-control" type="text" name="kaeufer_name" required
placeholder="Vor- und Nachname">
</div>
<div class="form-group">
<label class="form-label">Adresse des Käufers <span style="color:var(--c-danger)">*</span></label>
<label class="form-label">Adresse des Käufers <span class="text-danger">*</span></label>
<textarea class="form-control" name="kaeufer_adresse" rows="2" required
placeholder="Straße, PLZ, Ort"></textarea>
</div>
<div class="form-group">
<label class="form-label">E-Mail des Käufers <span style="color:var(--c-text-secondary)">(optional)</span></label>
<label class="form-label">E-Mail des Käufers <span class="text-secondary">(optional)</span></label>
<input class="form-control" type="email" name="kaeufer_email"
placeholder="kaeufer@beispiel.de">
</div>
<div class="form-group">
<label class="form-label">Kaufpreis <span style="color:var(--c-text-secondary)">(optional)</span></label>
<label class="form-label">Kaufpreis <span class="text-secondary">(optional)</span></label>
<input class="form-control" type="text" name="preis"
placeholder="z. B. 1.500 €">
</div>
@ -1317,11 +1317,11 @@ window.Page_litters = (() => {
const visOrder = ['public', 'inquiry', 'private'];
const body = `
<div id="${galleryId}" style="margin-bottom:var(--space-4)">
<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Lädt</p>
<div id="${galleryId}" class="mb-4">
<p class="text-sm-muted">Lädt</p>
</div>
<hr style="margin:var(--space-3) 0;border:none;border-top:1px solid var(--c-border)">
<form id="${uploadFormId}" style="display:flex;flex-direction:column;gap:var(--space-2)">
<form id="${uploadFormId}" class="flex-col-gap-2">
<label style="font-size:var(--text-sm);font-weight:var(--weight-semibold)">
${UI.icon('upload-simple')} Foto hochladen
</label>
@ -1348,7 +1348,7 @@ window.Page_litters = (() => {
try {
const photos = await API.breederPhotos.list(entityType, entityId);
if (!photos.length) {
el.innerHTML = `<p style="color:var(--c-text-muted);font-size:var(--text-sm)">Noch keine Fotos vorhanden.</p>`;
el.innerHTML = `<p class="text-sm-muted">Noch keine Fotos vorhanden.</p>`;
return;
}
el.innerHTML = `
@ -1464,13 +1464,13 @@ window.Page_litters = (() => {
const issueHTML = (welfare.issues || []).map(i => `
<div style="display:flex;gap:8px;padding:8px 0;border-bottom:1px solid rgba(0,0,0,.06)">
<span style="color:${color};flex-shrink:0">${UI.icon('warning')}</span>
<span style="font-size:var(--text-sm)">${_esc(i.text)}</span>
<span class="text-sm">${_esc(i.text)}</span>
</div>`).join('');
const okHTML = (welfare.ok_points || []).map(p => `
<div style="display:flex;gap:8px;padding:4px 0">
<span style="color:#16a34a;flex-shrink:0">${UI.icon('check')}</span>
<span style="font-size:var(--text-sm);color:var(--c-text-secondary)">${_esc(p)}</span>
<span class="text-sm-secondary">${_esc(p)}</span>
</div>`).join('');
const isProblematic = welfare.level === 'warning' || welfare.level === 'critical';
@ -1500,7 +1500,7 @@ window.Page_litters = (() => {
Trotzdem fortfahren
</button>
</div>` : `
<button class="btn btn-primary" data-modal-close style="width:100%">
<button class="btn btn-primary" data-modal-close class="w-full">
${UI.icon('check')} Verstanden
</button>`,
});
@ -1540,7 +1540,7 @@ window.Page_litters = (() => {
} catch (err) {
UI.modal.open({
title: `${UI.icon('sparkle')} KI-Wurfankündigung`,
body: `<p style="color:var(--c-danger)">${_esc(err.message || 'Fehler beim Generieren.')}</p>`,
body: `<p class="text-danger">${_esc(err.message || 'Fehler beim Generieren.')}</p>`,
footer: `<button class="btn btn-secondary" data-modal-close>Schließen</button>`,
});
return;