/* Artbase 1.0.196 | public/assets/css/addon-b.css
   Styles für das Artbase-Addon (addon_b). Wird via stylesheets.css eingebunden
   (@import-Zeile setzt der Installer idempotent).

   Präfix `.ab-` (Artbase) – keine Kollision mit main.css oder addon-a.css.
   Farben ausschließlich über die :root-Tokens (--c-*) aus main.css, damit die
   Skins greifen. Anders als bei Art 2.0 gibt es hier KEINE skin-unabhängige
   Ausnahme: die Artbase-Seiten sind Text-/Tabellenseiten, keine Galeriewand. */

/* ── Knopfleiste der Artbase-Seiten (_ab_nav.php) ─────────────────────────────
   Nutzt bewusst die Basis-Klassen `.admin-nav` / `.admin-nav__item` / `.is-active`
   (wie `admin_nav.php` und `legal_nav.php`), damit Optik und aktiver Zustand
   überall identisch sind. Hier steht nur die Handy-Anpassung: vier gleich breite
   Buttons im 2×2-Raster statt einer gequetschten Linkreihe – dieselbe Regel, die
   main.css für `.admin-nav--legal` mitbringt. */
@media (max-width: 500px) {
    .admin-nav--artbase .admin-nav__item {
        flex: 1 1 calc(50% - var(--sp-2));
        justify-content: center;
        text-align: center;
    }
}

/* Bestandszahl im Knopf – etwas zurückgenommen, damit der Name führt. */
.ab-nav__count { opacity: .7; font-weight: 400; }

/* ── Filterleiste (Suche + Selects) ───────────────────────────────────────── */
.ab-filters {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
    margin: .75rem 0 1rem;
}
/* Suchfeld + Knopf sind EINE Einheit (Knopf immer rechts neben dem Feld, auch auf
   dem Handy). Das Nebeneinander macht die BASIS-Klasse `.search-form` aus main.css
   – dieselbe, die auch die Volltextsuche der Basis nutzt:
       .search-form { display: flex; gap: … }  .search-form input { flex: 1 }
   Bewusst so, statt hier eine eigene Flex-Box zu bauen: main.css ist immer geladen,
   der Knopf sitzt also selbst dann richtig, wenn addon-b.css (noch) nicht greift –
   etwa weil der Browser die alte Fassung zwischenspeichert. Aus demselben Grund
   trägt das Suchfeld KEIN `form-input`: dessen `width: 100%` würde die Zeile füllen
   und den Knopf umbrechen; `.search-form input` bringt sein eigenes Styling mit.

   `.ab-search` steuert daher nur noch, wie breit die Gruppe in der Filterzeile
   werden darf; die Selects (Stadt/Bezirk/Jahr) brechen frei darunter um. */
.ab-search { flex: 1 1 18rem; max-width: 30rem; }
.ab-search .btn { flex: 0 0 auto; }

.ab-select {
    padding: .35rem .5rem; border: 1px solid var(--c-gray-300); border-radius: 4px;
    font-size: .9rem; background: var(--c-white); color: var(--c-gray-800); cursor: pointer;
    max-width: 14rem;
}
.ab-select:focus { outline: none; border-color: var(--c-accent); box-shadow: 0 0 0 3px var(--c-focus-ring); }

.ab-inline {
    display: inline-flex; align-items: center; gap: .4rem;
    margin-right: 1rem; font-size: .9rem; color: var(--c-gray-700);
}
.ab-inline .form-input { width: auto; }

.ab-muted { color: var(--c-text-muted); font-size: .875rem; }

/* ── Fakten-Liste (Künstler-/Galerie-Kopf) ────────────────────────────────── */
.ab-facts {
    display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem;
    margin: 0 0 .75rem;
}
.ab-facts dt { font-weight: 600; color: var(--c-gray-600); }
.ab-facts dd { margin: 0; color: var(--c-text); overflow-wrap: anywhere; }

/* `white-space: pre-line`: getippte Zeilenumbrüche im Klartext-Feld `notes` (bzw.
   im Ausstellungs-`comment`) bleiben erhalten, aufeinanderfolgende Leerzeichen
   werden weiter zusammengefasst. Für gesetzten Mehrabsatz-Text ist der
   Recherche-Abschnitt (BBCode) da – das hier ist nur die Kurznotiz. */
.ab-notes { margin: .5rem 0 0; color: var(--c-text); white-space: pre-line; }

/* ── Kartenliste (Künstler-Übersicht) ─────────────────────────────────────── */
.ab-cards { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
@media (min-width: 45rem) { .ab-cards { grid-template-columns: repeat(2, 1fr); } }

/* Box (Rahmen/Radius/Hintergrund) kommt aus main.css .card-tile/.card-tile--pad,
   im Markup neben .ab-card gesetzt – hier nur noch die Kind-Klassen. */
/* Kategorie-Badge „Group show" (ab 1.0.130): ein reines Abgrenzungs-Detail, kein
   Zustandshinweis – deshalb helles Blau (dieselben Tokens wie `.alert--info` in
   main.css) statt des ockergelben `.badge--pending`. Fällt der @import auf diese
   Datei weg, bleibt es ein schmuckloses `.badge`. */
.ab-badge-cat { background: var(--c-accent-light); color: var(--c-accent-dark); }

.ab-card__title { margin: 0 0 .25rem; font-size: 1.05rem; }
.ab-card__meta  { margin: 0 0 .35rem; font-size: .85rem; color: var(--c-text-muted); }
.ab-card__text  { margin: 0; font-size: .9rem; }

/* ── Bildmaterial (Referenz- und freigegebene Bilder) ──────────────────────────────── */
.ab-imggrid {
    list-style: none; margin: .75rem 0 0; padding: 0;
    display: grid; gap: .75rem;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
/* Box (Rahmen/Radius/Hintergrund/overflow) kommt aus main.css .card-tile,
   im Markup neben .ab-imgcard gesetzt. */
.ab-imgcard { display: flex; flex-direction: column; }
/* Gesperrt = private Recherchekopie. Gestrichelter Rahmen macht sofort sichtbar,
   dass hier bewusst kein Bild steht (statt „Bild kaputt"). */
.ab-imgcard--blocked { border-style: dashed; border-color: var(--c-gray-400); }

/* Vorschaubild ist ab 1.0.5 ein Link auf die volle Größe (Basis-Lightbox über
   `a.content-thumb`). `line-height: 0` verhindert die Textzeilen-Lücke, die ein
   Inline-Bild in einem Block-Link sonst darunter erzeugt. Der Fokus-Ring muss sichtbar
   bleiben – der Link ist tastaturbedienbar, das Bild füllt ihn randlos aus. */
.ab-imgcard__link { display: block; line-height: 0; }
.ab-imgcard__link:focus-visible { outline: 2px solid var(--c-accent); outline-offset: -2px; }

.ab-imgcard__img { display: block; width: 100%; height: auto; background: var(--c-gray-100); }
.ab-imgcard__ph {
    display: flex; align-items: center; justify-content: center; text-align: center;
    min-height: 8rem; padding: 1rem;
    background: var(--c-gray-100); color: var(--c-text-muted);
    font-size: .85rem;
}
.ab-imgcard__body { padding: .6rem .75rem; font-size: .875rem; }
.ab-imgcard__body p { margin: .25rem 0 0; overflow-wrap: anywhere; }

/* ── Werk-Thumbnail in der Werkliste (B-31) ───────────────────────────────────
   main.css hat `.content-thumb` (voll-breit) und `.card-tile` (Grid-Kachel) –
   beides passt nicht für eine feste Mini-Vorschau in einer `.data-table`-Zelle. */
.ab-work-thumb-col { width: 4rem; }
.ab-work-thumb {
    display: block; width: 3.25rem; height: 3.25rem;
    border-radius: 4px; overflow: hidden; background: var(--c-gray-100);
}
.ab-work-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ab-work-thumb:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
.ab-work-thumb--ph { border: 1px dashed var(--c-gray-400); }
.ab-work-thumb-n {
    display: block; width: 3.25rem; margin-top: .15rem;
    text-align: center; font-size: .75rem; color: var(--c-text-muted);
}

/* ── Bildrechte-Editor (Admin) ────────────────────────────────────────────── */
.ab-rights {
    border: 1px solid var(--c-gray-200); border-radius: 6px;
    margin-bottom: .4rem; background: var(--c-surface);
}
.ab-rights__head {
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
    padding: .5rem .75rem; cursor: pointer; list-style: none;
}
.ab-rights__head::-webkit-details-marker { display: none; }
.ab-rights__head::before { content: '▸'; color: var(--c-text-muted); }
.ab-rights[open] > .ab-rights__head::before { content: '▾'; }
.ab-rights__title { flex: 1 1 16rem; min-width: 0; font-weight: 600; }
.ab-rights__form {
    padding: .25rem .75rem .75rem;
    border-top: 1px solid var(--c-gray-200);
    display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: flex-end;
}
/* Freigabe-Block optisch absetzen: hier entsteht die Veröffentlichungs-Entscheidung. */
.ab-rights__consent {
    flex: 1 1 100%;
    display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: flex-end;
    padding: .5rem .75rem; border-radius: 4px;
    background: var(--c-gray-100); border: 1px solid var(--c-gray-200);
}
.ab-inline--wide { flex: 1 1 20rem; }
.ab-inline--wide .form-input { width: 100%; }

/* ── Recherche-Stränge: öffentliche Liste (B-20, ab 1.0.56) ────────────────
   Nur Aufzählungszeichen weg und etwas Luft. Fällt das Addon-CSS aus, steht dort
   eine gewöhnliche <ul> – lesbar, nur mit Punkten davor. */
.ab-topics { list-style: none; margin: .5rem 0 0; padding: 0; }
.ab-topics li { padding: .35rem 0; border-bottom: 1px solid var(--c-gray-200); }
.ab-topics li:last-child { border-bottom: 0; }

/* ── Sammelfreigabe (B-11, ab 1.0.43) ─────────────────────────────────────── */
.ab-bulk { margin: 0 0 1rem; }

/* Einzelbearbeitung: zugeklappt, weil sie dieselben Bilder ein zweites Mal listet.
   Nur ein Aufklapper – ohne dieses CSS steht er offen da und bleibt bedienbar. */
.ab-rights-single { margin: 1rem 0 0; }
.ab-rights-single__head {
    cursor: pointer; padding: .4rem 0; font-weight: 600;
    color: var(--c-gray-700); list-style: none;
}
.ab-rights-single__head::-webkit-details-marker { display: none; }
.ab-rights-single__head::before { content: '▸ '; color: var(--c-text-muted); }
.ab-rights-single[open] > .ab-rights-single__head::before { content: '▾ '; }

/* ── Bestätigungsschritt vor einer Rechteänderung (B-11) ───────────────────
   Absichtlich auffällig: hier wird ein fremdes Werk öffentlich gestellt. Die
   Farben kommen aus den :root-Tokens, damit der Skin greift (Regel P14). */
.ab-confirm {
    border: 2px solid var(--c-warning-text); border-radius: 6px;
    background: var(--c-warning-bg); padding: .75rem 1rem; margin: 0 0 1rem;
}
.ab-confirm h3 { margin: 0 0 .5rem; color: var(--c-warning-text); }

/* ── Historie-Kasten beim Überfahren (B-11) ────────────────────────────────
   BEWUSST addon-eigen und nicht in main.css: die Basis bringt kein Tooltip-
   Primitiv mit (geprüft), und ein Addon fasst keine Basis-Datei an
   (DOK/ADDON-KONVENTIONEN.md, „Kein Eingriff in Basis-Dateien"). Kommt je ein
   zweiter Nutzer dazu, gehört das Muster in eine Basis-Lieferung, nicht
   dupliziert.
   Ohne JavaScript: :hover für die Maus, :focus-within für die Tastatur. Fällt das
   Addon-CSS aus (Basis-Upload überschreibt stylesheets.css), steht der Kasten
   schlicht immer offen – lesbar, nur unschön. Kein Grundlayout hängt daran. */
.ab-hist { position: relative; display: inline-block; cursor: help; }
.ab-hist__box {
    display: none; position: absolute; right: 0; top: 1.6rem; z-index: 20;
    width: 22rem; max-width: 70vw; max-height: 18rem; overflow-y: auto;
    padding: .5rem .75rem; text-align: left; white-space: normal;
    font-size: .8rem; line-height: 1.45;
    background: var(--c-surface); color: var(--c-text);
    border: 1px solid var(--c-gray-300); border-radius: 6px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
}
.ab-hist:hover .ab-hist__box,
.ab-hist:focus-within .ab-hist__box { display: block; }
.ab-hist__row { display: block; padding: .3rem 0; }
.ab-hist__row + .ab-hist__row { border-top: 1px solid var(--c-gray-200); }

/* ── Übersetzungs-Karte (B-22, ab 1.0.60) ─────────────────────────────────
   AUSSCHLIESSLICH Kosmetik. Jedes Feld trägt die Basis-Klassen `.form-group`/
   `.form-label`/`.form-input`; fällt das Addon-CSS aus, stehen Grundtext und
   Eingabefeld schlicht untereinander – voll bedienbar, nur ohne Absetzung.
   Kein Grundlayout hängt daran (Addon-Regel 2). */
.ab-i18n__field + .ab-i18n__field {
    margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--c-gray-200);
}

/* ── Sammel-Textbearbeitung der Recherche-Abschnitte (1.0.98) ──────────────
   Nur Absetzung von der Tabelle darüber. Kein Grundlayout hängt daran
   (Addon-Regel 2): fällt das Addon-CSS aus, steht der Block schlicht darunter. */
.ab-secbulk { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--c-gray-200); }
.ab-secbulk textarea.form-input { resize: vertical; }
/* Noch nicht angelegte Abschnittstypen: eingeklappt, damit die Liste nicht zuwuchert.
   Ohne CSS ist es ein offenes <details> – voll bedienbar. */
.ab-newsec > summary { cursor: pointer; list-style: none; }
.ab-newsec > summary::-webkit-details-marker { display: none; }
.ab-newsec > summary::before { content: "▸\00A0"; color: var(--c-text-muted); }
.ab-newsec[open] > summary::before { content: "▾\00A0"; }
.ab-newsec > textarea.form-input { margin-top: .35rem; }
/* Der Grundtext ist Anzeige, keine Eingabe – deshalb abgesetzt und nicht als Feld.
   Ohne ihn müsste man beim Übersetzen zwischen zwei Karten hin- und herspringen. */
.ab-i18n__src {
    margin: .2rem 0 .5rem; padding: .45rem .6rem;
    background: var(--c-gray-100); border-left: 3px solid var(--c-gray-300);
    border-radius: 4px; font-size: .9rem; line-height: 1.5;
    white-space: pre-wrap; overflow-wrap: anywhere;
    /* Ein Abschnitts-Text kann seitenlang sein – gedeckelt, sonst schiebt die
       Vorlage das Eingabefeld aus dem Bild. */
    max-height: 16rem; overflow-y: auto;
}
.ab-i18n__row { display: flex; align-items: flex-start; gap: .5rem; }
.ab-i18n__row + .ab-i18n__row { margin-top: .4rem; }
.ab-i18n__row .form-input { flex: 1 1 auto; width: 100%; }
/* Feste Breite, damit Sprachkürzel und Text bei mehreren Zeilen bündig stehen. */
.ab-i18n__lang {
    flex: 0 0 2.2rem; padding-top: .45rem;
    font-size: .75rem; font-weight: 600; letter-spacing: .06em;
    color: var(--c-text-muted);
}
.ab-i18n__src .ab-i18n__lang { padding-top: 0; margin-right: .35rem; }
/* Der Hinweis am FELD (ab 1.0.61). Kursiv abgesetzt, weil er neben einem
   inhaltlichen Hinweis stehen kann und nicht mit ihm verschmelzen soll. Ohne
   Addon-CSS bleibt er eine gewöhnliche `.form-hint` – lesbar, nur nicht abgesetzt. */
.ab-i18n__mark { display: block; font-style: italic; opacity: .85; }

/* ── Pflege-Oberfläche (Datenpflege, ab 1.0.4) ─────────────────────────────
   AUSSCHLIESSLICH Kosmetik: zwei Spalten statt untereinander. Jedes Feld trägt
   die Basis-Klassen `.form-group`/`.form-label`/`.form-input` aus main.css und ist
   auch allein voll benutzbar – fällt der @import in der Basis-Datei
   stylesheets.css bei einem Basis-Upload weg, stehen die Felder einfach gestapelt.
   Kein Grundlayout hängt an `.ab-grid`. */
.ab-grid { display: grid; gap: 0 1rem; }
@media (min-width: 40rem) {
    .ab-grid { grid-template-columns: 1fr 1fr; }
    /* Lange Felder (Notizen, Nachweise, Freitext-Zeitraum) über beide Spalten. */
    .ab-grid__wide { grid-column: 1 / -1; }
}

/* Ausgeblendetes Feld, das seinen Rasterplatz behält – nichts rückt nach. */
.ab-slot--off { visibility: hidden; }

/* Deutliche Trennlinie in einer Maske – verstärkt die Basis-`.form-divider`. */
.ab-divider { border-top: 2px solid var(--c-gray-400); margin: var(--sp-4) 0; }

/* ── Galerie-Maske: Label NEBEN dem Feld (ab 1.0.18) ────────────────────────
   Das Nebeneinander macht die BASIS-Klasse `.form--two-col` aus main.css – die ist
   immer geladen, also steht die Maske auch dann richtig, wenn der @import auf diese
   Datei aus stylesheets.css verschwunden ist (etwa nach einem Basis-Upload). Hier
   stehen ausschließlich Verfeinerungen für die halbbreite Spalte. Muster: die
   `.art-form2`-Maske in addon-a.

   ── MERKREGEL für alles, was hier ein Eingabefeld umstylt ──────────────────
   Die Feld-Regeln der Basis lauten `.form-group input[type="text"], …` bzw.
   `.form--two-col .form-group input[type="text"]`. Ein **Attribut**-Selektor wie
   `[type="text"]` zählt wie eine Klasse – die Regeln wiegen also (0,2,1) bzw.
   (0,3,1), nicht (0,1,1)/(0,2,1). Ein Überschreiber braucht deshalb **mindestens
   drei bzw. vier Klassen**. Zweimal in Folge übersehen (Maxbreite 1.0.21,
   Feld-Markierung 1.0.24) – beide Male sah die Regel richtig aus und tat nichts. */

/* Die Basis rechnet mit 12rem Label-Spalte über die volle Breite. In einer der
   beiden `.ab-grid`-Spalten bleibt davon zu wenig fürs Eingabefeld übrig. */
@media (min-width: 40rem) {
    .ab-form2.form--two-col .form-group {
        grid-template-columns: 8.5em 1fr;
        column-gap: .6rem;
    }
}

/* Hinweistext unter das EINGABEFELD statt (wie in der Basis) unter das Label:
   in einer 8.5em schmalen Label-Spalte wird aus einem ganzen Satz sonst ein
   Textband von zwei Wörtern Breite. Höhere Spezifität als die Basis-Regel, damit
   die Reihenfolge der @import-Zeilen keine Rolle spielt. */
.ab-form2.form--two-col .form-group > .form-hint { grid-column: 2; }

/* Zwei Eingaben hinter EINEM Label (PLZ/Ort, Breite/Länge). Ohne diese Datei
   stehen sie untereinander – unschön, aber vollständig bedienbar. */
.ab-duo { display: flex; gap: .5rem; width: 100%; }
.ab-duo > .form-input { flex: 1 1 0; min-width: 0; }

/* Die Basis deckelt Felder im Zwei-Spalten-Formular auf 24rem. Über die volle
   Seitenbreite gedacht stimmt das – in der halben Spalte entsteht dadurch aber
   rechts neben JEDEM Feld ein toter Streifen, und die beiden Spalten stehen
   optisch weit auseinander. Hier füllt das Feld seine Zelle.

   KEINE Maxbreite auf `.ab-form2` (1.0.19 hatte 56rem – falsch): die Maske sitzt
   in einer `.content-card`, die auf einem breiten Monitor deutlich mehr hergibt.
   Der Deckel ließ rechts einen handbreiten Streifen leer und schnürte zugleich die
   Spalten so ein, dass schon kurze Beschriftungen umbrachen – und die
   seitenbreiten Felder (Schwerpunkt, Notizen) endeten mitten in der Karte. Die
   Breite gibt die Karte vor, nicht diese Datei.

   SPEZIFITÄT – hier lag der Fehler von 1.0.19/1.0.20: die Basis-Regel lautet
   `.form--two-col .form-group input[type="text"]`. Ein **Attribut**-Selektor wie
   `[type="text"]` zählt in derselben Gruppe wie eine Klasse, die Regel wiegt also
   (0,3,1) und nicht (0,2,1). Der Überschreiber mit drei Klassen (0,3,0) verlor
   damit – die 24rem blieben stehen, unsichtbar nur solange die Spalte ohnehin
   schmaler als 24rem war (das war der Fall, als die Maske noch auf 56rem gedeckelt
   war; deshalb sah 1.0.19 richtig aus). Vier Klassen (0,4,0) schlagen (0,3,1). */
.ab-form2.form--two-col .form-group .form-input { max-width: none; }

/* Eine Feldgruppe darf NICHT auf die Höhe ihrer Nachbarin gedehnt werden.
   Sonst dehnt sich ihre einzige Rasterzeile mit (`align-content: stretch` ist
   Vorgabe), und das laut Basis mittig ausgerichtete Eingabefeld rutscht in dieser
   überhohen Zeile nach unten. Sichtbar in der Zeile Telefon | Koordinaten: nur die
   rechte Gruppe trägt einen Hinweistext, also stand nur das Telefon-Feld tiefer.
   Damit liegen Label und Eingabefeld beider Gruppen auf einer Linie – unabhängig
   davon, ob eine von ihnen einen Hinweistext hat. */
.ab-form2 .form-group { align-self: start; align-content: start; }

/* Die Basis gibt jeder Textarea 90px Mindesthöhe – damit wäre ein leeres
   Notizfeld immer vier Zeilen hoch, obwohl `rows` zwei sagt. Gezogen werden kann
   es weiterhin (`resize: vertical` bleibt aus der Basis). */
.ab-form2 .form-group textarea { min-height: 0; }

/* Bewusst leer gelassene Rasterzelle (rechts neben Straße bzw. Land). Einspaltig
   gibt es keine Zelle freizuhalten – dort ganz weg, sonst entstünde eine Lücke. */
.ab-form2__gap { display: none; }
@media (min-width: 40rem) { .ab-form2__gap { display: block; } }

/* Häkchen in der Maske: sitzt in der Eingabespalte, nicht in der Label-Spalte
   (Begründung im Feld-Helfer `$abF2`). Ohne diese Datei stehen Kästchen und Text
   schlicht nebeneinander in der Zeile – ebenfalls bedienbar. */
.ab-check { display: flex; align-items: center; gap: .4rem; }
.ab-check input { width: auto; }

/* ── Gesperrte Stammdaten (B-13, ab 1.0.22) ────────────────────────────────
   Name, Adresse und Kurzname sind normalerweise nur ANZEIGE. Der Block ist
   deutlich abgesetzt, damit auf einen Blick klar ist, dass hier nichts einzutippen
   ist und die Änderung woanders hingehört. Rein farblich – fällt diese Datei weg,
   steht derselbe Text ohne Kasten da, der Freischalt-Knopf bleibt erreichbar. */
.ab-locked {
    border: 1px solid var(--c-warning-text); border-radius: 6px;
    background: var(--c-warning-bg); color: var(--c-warning-text);
    padding: .75rem 1rem; margin: 0 0 1rem;
}
.ab-locked > :first-child { margin-top: 0; }
.ab-locked > :last-child  { margin-bottom: 0; }
.ab-locked h3 { font-size: 1rem; margin-bottom: .4rem; }
.ab-locked .ab-facts dt,
.ab-locked .ab-facts dd { color: inherit; }
/* Knöpfe, die zum Sperr-/Warnkasten gehören, tragen dessen Farben (invertiert) –
   als graue Sekundär-Knöpfe standen sie beziehungslos daneben. Betrifft den
   Freischalt-Knopf IM Kasten und den Knopf „Sperre wieder schließen", der unten in
   der Knopfleiste zwischen Speichern und Abbrechen sonst nicht als Gegenstück zum
   Warnkasten darüber zu erkennen war. Die Knopf-Form kommt weiter aus `.btn`.
   `.btn.ab-btn--warn` statt nur `.ab-btn--warn`: gleiche Spezifität wie
   `.btn--secondary` würde nur über die Reihenfolge der @import-Zeilen gewinnen. */
.ab-locked .btn,
.btn.ab-btn--warn {
    background: var(--c-warning-text);
    border-color: var(--c-warning-text);
    color: var(--c-warning-bg);
}
.ab-locked .btn:hover,
.btn.ab-btn--warn:hover { filter: brightness(1.15); }

/* Aus dem bisherigen Zustand ÜBERNOMMENER Wert: sieht richtig aus, gilt für den
   neuen Zustand aber vielleicht nicht mehr. Die Markierung ist eine Prüfliste –
   das Skript am Ende von `_ab_edit.php` nimmt sie weg, sobald das Feld angefasst
   wurde. Fällt diese Datei weg, steht der erklärende Satz trotzdem über der Maske.

   DREI Klassen, und das ist kein Zufall: Hintergrund und Rahmen der Felder kommen
   in der Basis aus `.form-group input[type="text"]`, und das wiegt (0,2,1) – siehe
   die Merkregel oben. Mit nur `.ab-carried` (0,1,0) blieb die Markierung unsichtbar
   (1.0.24, derselbe Fehler wie bei der Maxbreite in 1.0.21). */
.ab-form2 .form-group .ab-carried {
    background: var(--c-warning-bg);
    border-color: var(--c-warning-text);
}

/* main.css kennt nur `--error/--success/--info`; die Warn-Variante fehlt dort.
   Der Kasten selbst kommt aus der Basis-Klasse `.alert`, hier nur die Farbe. */
.ab-alert--warn {
    background: var(--c-warning-bg); color: var(--c-warning-text);
    border-color: var(--c-warning-text);
}

/* Tätigkeiten-Häkchen in der Personen-Maske (B-40): nebeneinander, umbrechend.
   Ohne diese Regel stehen sie untereinander – voll bedienbar. */
.ab-roles { display: flex; flex-wrap: wrap; gap: .25rem 1.25rem; }

/* „Anlassfälle"-Liste über dem Anlege-Knopf in den Listenansichten (ab 1.0.91):
   geflaggte Galerien/Künstler, ein Klick zur Bearbeitung. Warn-Farben wie
   der Badge, damit der Zusammenhang klar ist. */
.ab-anlass {
    border-left: 3px solid var(--c-warning-text);
    background: var(--c-warning-bg);
    padding: .55rem .8rem; margin: 0 0 1rem; border-radius: 4px;
}
.ab-anlass > strong { display: block; margin-bottom: .3rem; }
.ab-anlass__list { margin: 0; padding-left: 1.2rem; }
.ab-anlass__list li { margin: .15rem 0; }
.ab-anlass__list .ab-muted { font-size: .875rem; }

.ab-edit__crumb  { margin: 0 0 .75rem; }
.ab-edit__delete { margin: 0; }

/* ── Standort-Chronologie: Ziehen (B-14, ab 1.0.84) ──────────────────────────
   Die Zeilen der Tabelle „Geschichte des Hauses" werden per Ziehgriff sortiert;
   ohne JavaScript ist die Karte reine Anzeige. Reines Kosmetik-CSS – der Server
   ordnet nach den übermittelten `chrono_pos`-Werten. */
.ab-chrono-table .ab-chrono-grip { width: 1.5rem; text-align: center; cursor: grab; }
.ab-chrono-table .ab-chrono-grip:active { cursor: grabbing; }
.ab-chrono-handle { color: var(--c-text-muted); user-select: none; font-size: 1.1rem; line-height: 1; pointer-events: none; }
.ab-chrono-table tr.is-dragging { opacity: .4; }
.ab-chrono-table tr.ab-chrono-dragover { outline: 2px dashed var(--c-accent); outline-offset: -2px; }
.ab-chrono-table [hidden],
[data-chrono-save][hidden] { display: none; }

/* ── Ausstellungsliste (Galerie-Detail) ───────────────────────────────────── */
.ab-exlist { list-style: none; margin: .75rem 0 0; padding: 0; }
.ab-ex {
    display: flex; flex-wrap: wrap; gap: .25rem 1rem;
    padding: .6rem 0; border-top: 1px solid var(--c-gray-200);
}
.ab-ex:first-child { border-top: 0; }
.ab-ex__date { flex: 0 0 12rem; color: var(--c-text-muted); font-size: .875rem; }
.ab-ex__main { flex: 1 1 18rem; min-width: 0; }
.ab-ex__main > div { margin-top: .15rem; }
/* Anker-Sprung aus der Ausstellungsliste/vom Resolver: Ziel nicht unter einer
   sticky Leiste verstecken. */
.ab-ex:target { scroll-margin-top: 5rem; background: var(--c-warning-bg); }

/* ── Karten-Platzhalter (bis Leaflet/OSM kommt) ───────────────────────────── */
.ab-mapstub {
    display: flex; align-items: center; justify-content: center;
    min-height: 10rem; margin-top: .75rem;
    border: 1px dashed var(--c-gray-400); border-radius: 6px;
    background: var(--c-gray-100); color: var(--c-text-muted);
}
.ab-mapstub__coords { font-size: .875rem; }

/* ── Addon-übergreifende Verweise ─────────────────────────────────────────── */
.ab-links { list-style: none; margin: .5rem 0 0; padding: 0; }
.ab-links__item { padding: .3rem 0; display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; }

/* ── Konflikte lösen (Verdachtsfälle, ab 1.0.78) ──────────────────────────────
   Die Gegenüberstellung zweier Konfliktparteien ist ECHTES addon-spezifisches UI,
   kein wiederverwendbares Primitiv: `.form--two-col` (Label|Feld) und `.ab-grid`
   (Formularfelder) meinen etwas anderes. Ohne diese Klasse stehen die beiden Seiten
   untereinander – voll bedienbar (Regel 2). Farben nur über :root-Tokens. */
.ab-conflict { display: grid; gap: 1rem; }
@media (min-width: 55rem) {
    .ab-conflict { grid-template-columns: 1fr 1fr; align-items: start; }
}
.ab-conflict__side { margin: 0; }

/* Ein Abschnitt je Seite: Überschrift, Text, darunter Stufe + Reihenfolge. */
.ab-conflict__sec {
    border: 1px solid var(--c-gray-200); border-radius: 6px;
    padding: .6rem; margin: 0 0 .6rem;
}
.ab-conflict__sec > * { margin-bottom: .4rem; }
.ab-conflict__sec > *:last-child { margin-bottom: 0; }
.ab-conflict__secmeta { display: flex; flex-wrap: wrap; gap: .5rem; }
.ab-conflict__secmeta .form-input { width: auto; flex: 0 1 12rem; }

/* Kennung der Seite im Kartenkopf – Kurzname (Künstler) bzw. „#id" (Ausstellung),
   ab 1.0.167. Sie ist das EINZIGE, was die beiden Karten sicher unterscheidet: bei
   einer Zusammenführung tragen beide fast immer denselben Klartextnamen. Deshalb
   farbig statt `ab-muted`.
   Der Ton kommt über `--c-danger-text` – der einzige rote, den JEDER Skin führt und
   der dort auf dem Kartengrund lesbar bleibt (hell #a83228, dunkel #f0a59c); ein
   fest eingetragenes Weinrot wäre auf den dunklen Skins nicht mehr zu lesen und
   verstieße gegen die Regel im Kopf dieser Datei. Die Zwischenvariable steht dafür,
   dass es hier KEIN Fehlerhinweis ist, sondern eine Hervorhebung – wird der Ton je
   anders gewünscht, ist er an genau einer Stelle zu ändern. */
:root { --ab-slug: var(--c-danger-text); }
.ab-conflict__slug { color: var(--ab-slug); font-weight: 600; }

/* Kartenkopf mit Knopf rechts (ab 1.0.173): links Bezeichnung und Kennung, rechts
   der Sprung auf die öffentliche Ansicht. `baseline` statt `center`, damit der
   Knopf auf der Schriftlinie der Überschrift sitzt; `wrap`, damit er auf schmalen
   Fenstern darunter rutscht statt die Kennung zu quetschen. */
.ab-conflict__head {
    display: flex; flex-wrap: wrap; align-items: baseline;
    justify-content: space-between; gap: .5rem;
}

/* Fest angezeigte (nicht editierbare) Entität im Abschnitts-Editor. */
.ab-fixed-val { margin: 0; color: var(--c-text); font-weight: 600; }

/* ── Galerien-Liste der Datenpflege (?ed=galleries) ─────────────────────────
   Der Kurzname unter dem Galerienamen soll NICHT umbrechen: ein 30-Zeichen-
   Slug riss die Namensspalte sonst auf drei bis vier Zeilen. `min-width` gibt
   dem Namen zusätzlich Luft, damit auch er möglichst einzeilig bleibt. Platz
   dafür kommt aus der zusammengelegten Spalte Stadt/Bezirk. Reine Kosmetik –
   ohne diese Datei bricht der Slug wieder um, die Liste bleibt lesbar. */
.ab-gname { min-width: 13rem; }
.ab-gname code { white-space: nowrap; }

/* ── Namensteile prüfen (B-37) ─────────────────────────────────────────────────
   Eine Zeile je Kontrollfall, jede ein eigenes <form> mit eigenem Speichern-Knopf
   (kein Sammel-Knopf – jede Bestätigung lernt ins Lexikon). Bewusst KEINE Tabelle:
   ein <form> darf nicht in <tr> stehen, und zwei Zeilen je Fall (Vollform oben,
   Eingabefelder darunter) lesen sich bei ~80 Fällen ohnehin besser als eine
   siebenspaltige Tabelle. Beschriftung der Felder über `placeholder` + aria-label
   statt einer Kopfzeile – der Platzhalter steht genau dann da, wenn man ihn
   braucht: solange das Feld leer ist. */
.ab-np__row { padding: .7rem 0; border-top: 1px solid var(--c-gray-200); }
.ab-np__row:first-child { border-top: 0; }

.ab-np__full {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .6rem;
    margin-bottom: .4rem;
}
.ab-np__full code { white-space: nowrap; font-size: .875rem; }

/* Zusatz im Original großgeschrieben („Van der" gegen `van der`) – der Vergleich
   ist bei `particle` case-sensitiv, deshalb liegt die Zeile überhaupt hier. */
.ab-np__caps {
    padding: .1rem .4rem; border-radius: 4px; font-size: .8125rem;
    background: var(--c-warning-bg); color: var(--c-warning-text);
}

.ab-np__fields {
    display: grid; gap: .4rem; align-items: center;
    grid-template-columns: 5rem 1fr 6rem 1fr 9rem auto auto;
}
.ab-np__nokind { text-align: center; }
.ab-np__syn { display: flex; align-items: center; gap: .3rem; white-space: nowrap; font-size: .875rem; }

/* Doppelnamen-Haken (B-37): sitzt IN der Feldzelle (Feld oben, Haken darunter),
   damit das Raster darüber unverändert eine Zelle je Feld behält. `min-width: 0`,
   sonst sprengt das Eingabefeld die 1fr-Spalte. */
.ab-np__cell { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.ab-np__chain { display: flex; align-items: center; gap: .3rem; font-size: .8125rem; }
.ab-np__chain[hidden] { display: none; }

/* Feld ohne Lexikon-Treffer: genau darum liegt die Zeile in der Karte. */
.ab-np--nomatch {
    border-color: var(--c-warning-text);
    background: var(--c-warning-bg);
}

@media (max-width: 60rem) {
    .ab-np__fields { grid-template-columns: 1fr 1fr; }
    .ab-np__syn, .ab-np__nokind { grid-column: 1 / -1; }
}

/* ── Schmale Viewports: Tabellen bleiben scrollbar (.table-wrap aus main.css),
      die zweispaltige Faktenliste klappt auf eine Spalte um. ─────────────── */
@media (max-width: 30rem) {
    .ab-facts { grid-template-columns: 1fr; gap: .1rem; }
    .ab-facts dd { margin-bottom: .4rem; }
    .ab-ex__date { flex: 1 1 100%; }
    .ab-np__fields { grid-template-columns: 1fr; }
}
