/* button.css — v2 Button-Primitives (.btn / .btn-primary / .btn-outline)

 Quelle: extrahiert aus app.css ("Buttons"-Block). Inhalt 1:1 uebernommen.
 Konsumenten: alle .app-scope-Bereiche (Drawer-Footer, Cards, Toolbars).
 Kleine Footer-Varianten (.btn-primary-sm, .btn-outline-sm, .btn-danger-sm)
 leben in primitives/button-sm.css NICHT — diese Kleinvarianten stehen
 ihrem Konsumenten-Modul (drawer-fields.css) am naechsten und bleiben dort.
 ========================================================================== */

.app-scope .btn {
 display: inline-flex; align-items: center; gap: var(--space-1-5);
 padding: var(--space-1-5) var(--space-3); border-radius: var(--radius-md);
 font-size: 13px; font-weight: var(--fw-semibold);
 /* Paint-only statt `transition: all` — die Liste deckt alle .btn*-Zustaende ab
    (hover: background/color/border-color/filter · :active: transform ·
    focus-visible: box-shadow). `all` animierte zusaetzlich width/padding: die
    Tier-Regeln der Toolbar und `is-primary-iconly` des Page-Headers setzen
    genau diese, und eine synchrone intrinsische Messung (ToolbarResponsive,
    Header-Kette) liest waehrend so einer Animation eingefrorene Zwischenwerte —
    der Mess-Schutz `data-tb-messung` bleibt als zweite Schicht, aber ein
    Primitive, das Layout-Properties animiert, ist die Ursache, nicht der Rand. */
 transition-property: background, border-color, color, box-shadow, transform, filter, opacity;
 transition-duration: var(--motion-fast);
 transition-timing-function: var(--ease-enter);
 white-space: nowrap;
}
/* Groessen-Variante — aus demselben Grund hier wie .btn-secondary/.btn-danger
   unten: die ungescopte `.btn-sm`-Deklaration in base.css (0-1-0) verliert gegen
   den app-scope-Button-Reset (0-1-1), also greift ihr KLEINERES Padding nicht und
   ein `.btn.btn-sm` ist im app-scope genauso gross wie ein normaler `.btn`.
   Gemessen 28.07. mit `node scripts/audits/audit-button-reset.js`: 40 Knoepfe in
   den Einstellungen. Werte gespiegelt aus base.css `.btn-sm`. */
.app-scope .btn-sm {
 padding: var(--space-1) var(--space-3);
 font-size: var(--font-size-sm);
 gap: var(--space-1-5);
 line-height: 1;
}
/* ── RAHMEN-PARITÄT (Vertrag für die ganze .btn*-Familie) ──────────────────
   Jede GEFÜLLTE Variante trägt `border: 1px solid transparent`, jede Outline-
   Variante einen sichtbaren 1px-Rahmen. Nur so sind zwei Knöpfe nebeneinander
   gleich hoch — der Rahmen zählt bei `box-sizing: border-box` in die Höhe.

   base.css führt diese Konvention bereits vollständig (`.btn-primary`,
   `.btn-danger`, `.btn-schule` haben alle den transparenten Rahmen). Innerhalb
   von `.app-scope` nimmt der Reset `.app-scope button` (0,1,1) sie jedoch weg,
   und die Wiederholungen hier unten hatten sie nur für `.btn-danger` und die
   Outline-Varianten nachgezogen — `.btn-primary`, `.btn-primary-sm` und
   `.btn-danger-sm` blieben randlos.

   WAS DAVON GEMESSEN IST (29.07., echter Browser, Drawer-Footer + RP-Drawer):
   `.btn-primary-sm` war 28px neben `.btn-outline-sm` mit 30px; mit dem Rahmen
   sind beide 30px, und über 11 Routen und 3 Drawer-Footer war danach kein
   gefüllt/umriss-Paar mehr ungleich hoch (4 Paare, 0 ungleich, kein Knopf läuft
   aus seinem Container). Das betraf jedes Speichern/Abbrechen-Paar und jedes
   ConfirmModal — die häufigsten Knopf-Paare der App.

   WAS VERTRAG IST, NICHT MESSUNG: bei `.btn-primary` ändert der Rahmen heute
   NICHTS. Alle gerenderten Instanzen sind die Legacy-Kombi
   `btn btn-primary app-cta-btn` aus der PageToolbar, die eine FESTE `height`
   mitbringt (36px, padding 0) — die Höhe hängt dort nicht am Rahmen, per
   Positiv-Kontrolle bestätigt (Rahmen zur Laufzeit entfernt → unverändert
   36px). Die Deklaration steht trotzdem hier, weil sie base.css spiegelt: die
   erste padding-getriebene Nutzung von `.btn btn-primary` neben
   `.btn btn-outline` hätte sonst denselben 2px-Versatz wieder, und zwar
   lautlos. `.btn-danger` (schon vorher korrekt), `.btn-danger-sm` und
   `.btn-secondary` waren in den vermessenen Flächen nicht gerendert — für sie
   gilt der Vertrag, nicht ein Messwert.

   Wer eine neue gefüllte Variante ergänzt, gibt ihr denselben transparenten
   Rahmen — sonst kippt die Parität an genau dieser Stelle wieder.

   `.app-cta-btn` ist hiervon ausgenommen und braucht es nicht: die Variante hat
   eine FESTE `height` plus `box-sizing: border-box`, ihre Höhe hängt also nicht
   am Rahmen. Das ist der robustere Weg — die `.btn*`-Familie ist dagegen
   padding-getrieben und deshalb auf die Parität angewiesen. */
.app-scope .btn-primary { background: var(--lod-darkblue); color: #fff; border: 1px solid transparent; }
.app-scope .btn-primary:hover { background: var(--lod-turquoise); color: var(--lod-darkblue-900); }
.app-scope .btn-outline { background: var(--color-surface); color: var(--lod-gray-700); border: 1px solid var(--lod-gray-200); }
.app-scope .btn-outline:hover { border-color: var(--lod-darkblue-300); color: var(--lod-darkblue); }
/* Secondary + Danger MUESSEN hier (unter .app-scope) stehen: der globale .app-scope-
   button-Reset (app-scope.css: background/border/padding:none, Spezifitaet 0-1-1) schlaegt
   sonst die ungescopte .btn-secondary/.btn-danger-Deklaration (0-1-0) und plaettet den
   Button — Grund + Rahmen weg, bei Danger weisser Text auf hellem Grund unsichtbar.
   Werte gespiegelt aus base.css .btn-secondary bzw. der .btn-danger-sm-Variante. */
.app-scope .btn-secondary { background: var(--color-surface); color: var(--color-text); border: 1px solid var(--color-border-hover); }
.app-scope .btn-secondary:hover { background: var(--color-bg); border-color: var(--color-border-pressed); }
.app-scope .btn-danger { background: var(--lod-danger); color: #fff; border: 1px solid transparent; }
.app-scope .btn-danger:hover { filter: brightness(0.95); }
/* Icon in gefuellten (dunklen) Buttons weiss halten: der .ui-ico-Default-Filter ist
   dunkelblau und verschwindet sonst auf --lod-darkblue/--lod-danger (dasselbe Problem
   loest .btn-primary-sm bereits fuer die Footer-Variante). */
.app-scope .btn-primary .ui-ico img,
.app-scope .btn-danger .ui-ico img { filter: brightness(0) invert(1); }
/* Primary-Hover kippt auf tuerkisen Grund mit dunklem Text → Icon ebenfalls dunkel. */
.app-scope .btn-primary:hover .ui-ico img { filter: none; }
/* Press-Feedback (haptisch, Charakter B) — Basis-Buttons hatten bisher KEIN
 :active-Feedback (Snap). scale(0.96) gibt sofortige taktile Rueckmeldung. */
.app-scope .btn:active { transform: scale(0.96); }

/* Buttons (klein, für Modals + Toolbars) */
.app-scope .btn-primary-sm {
 display: inline-flex; align-items: center; gap: 5px;
 padding: var(--space-1-5) var(--space-3);
 font-size: 12.5px; font-weight: var(--fw-semibold);
 background: var(--lod-darkblue);
 color: #fff;
 border: 1px solid transparent;   /* Rahmen-Paritaet — siehe Vertrag oben */
 border-radius: var(--radius-md);
 transition: var(--duration-quick);
 white-space: nowrap;
}
/* 2026-05-04 Paket EXTERN-DRAWER-MIGRATION 4a: disabled-Styles fuer
 Drawer-Footer-Buttons (z.B. Setup-Wizard "Weiter" wenn Pflichtfelder
 fehlen). Greift auch fuer alle anderen Konsumenten der btn-*-sm-Klassen
 wenn `a.disabled === true` in footerActions gesetzt wird. */
.app-scope .btn-primary-sm:disabled,
.app-scope .btn-outline-sm:disabled,
.app-scope .btn-danger-sm:disabled {
 opacity: 0.45;
 cursor: not-allowed;
 pointer-events: none;
 box-shadow: none;
 transform: none;
}
/* Hover: Turquoise-Highlight mit leichtem Lift - gleiches Muster wie der
 Primary-Button im Header. */
.app-scope .btn-primary-sm:hover {
 background: var(--lod-turquoise);
 color: var(--lod-darkblue-900);
 box-shadow: 0 2px 8px color-mix(in srgb, var(--lod-darkblue-900) 15%, transparent);
 transform: translateY(-1px);
}
.app-scope .btn-primary-sm:hover > .btn-icon,
.app-scope .btn-primary-sm:hover > img {
 /* bei Hover: Icon wieder als dunkles Original, damit es auf Turquoise sichtbar ist */
 filter: none;
}
.app-scope .btn-primary-sm:active {
 transform: translateY(0);
 box-shadow: 0 1px 3px color-mix(in srgb, var(--lod-darkblue-900) 20%, transparent);
}
/* Icon im Primary-Footer-Button immer weiss (matches color) - Default-SVG ist
 schwarz und wuerde auf Darkblue-BG unsichtbar werden. */
.app-scope .btn-primary-sm > .btn-icon,
.app-scope .btn-primary-sm > img {
 filter: brightness(0) invert(1);
 margin-right: var(--space-1-5);
 vertical-align: middle;
}
.app-scope .btn-outline-sm > .btn-icon,
.app-scope .btn-outline-sm > img,
.app-scope .btn-danger-sm > .btn-icon,
.app-scope .btn-danger-sm > img {
 margin-right: var(--space-1-5);
 vertical-align: middle;
}
.app-scope .btn-danger-sm > .btn-icon,
.app-scope .btn-danger-sm > img { filter: brightness(0) invert(1); }
.app-scope .btn-outline-sm {
 display: inline-flex; align-items: center; gap: 5px;
 padding: var(--space-1-5) var(--space-3);
 font-size: 12.5px; font-weight: var(--fw-medium);
 background: #fff;
 color: var(--lod-gray-700);
 border: 1px solid var(--lod-gray-200);
 border-radius: var(--radius-md);
 transition: var(--duration-quick);
 white-space: nowrap;
}
.app-scope .btn-outline-sm:hover {
 border-color: var(--lod-darkblue-300);
 color: var(--lod-darkblue);
 background: var(--lod-gray-50);
 box-shadow: 0 2px 8px color-mix(in srgb, var(--lod-darkblue-900) 8%, transparent);
 transform: translateY(-1px);
}
.app-scope .btn-outline-sm:active {
 transform: translateY(0);
 box-shadow: none;
}
.app-scope .btn-danger-sm {
 display: inline-flex; align-items: center; gap: 5px;
 padding: var(--space-1-5) var(--space-3);
 font-size: 12.5px; font-weight: var(--fw-semibold);
 background: var(--lod-danger);
 color: #fff;
 border: 1px solid transparent;   /* Rahmen-Paritaet — siehe Vertrag oben */
 border-radius: var(--radius-md);
 transition: var(--duration-quick);
 white-space: nowrap;
}
.app-scope .btn-danger-sm:hover { filter: brightness(0.95); }

/* Focus-Ring ueber Token fuer alle kleinen Buttons. Kein Browser-Default
 (system-abhaengig dick), sondern tuerkiser 3px-Ring aus --lod-shadow-focus.
 Gueltig auch fuer .btn-primary / .btn-outline. */
.app-scope .btn-primary-sm:focus-visible,
.app-scope .btn-outline-sm:focus-visible,
.app-scope .btn-danger-sm:focus-visible,
.app-scope .btn-primary:focus-visible,
.app-scope .btn-outline:focus-visible {
 outline: none;
 box-shadow: var(--lod-shadow-focus);
}

/* ══════════════════════════════════════════════════════════════════════
 CTA-Button-SSOT (.app-cta-btn) innerhalb .app-scope
 ──────────────────────────────────────────────────────────────────────
 Die :where()-Basis in components/toolbar/toolbar.css (0,1,0) verliert
 INNERHALB von .app-scope gegen den globalen Reset `.app-scope button`
 (0,1,1) — .app-cta-btn war dort "geplaettet" und jede Section hat sich
 eine eigene Kopie gestylt (Drift: 28/30/32/34px allein im Postfach).
 Diese Regeln sind die verbindliche Basis im App-Scope.

 :not(.btn)-Guard: Legacy-Kombis `btn btn-primary app-cta-btn`
 (page-toolbar.js) nutzen .app-cta-btn nur als Icon-Only-Marker der
 Toolbar-Tiers und behalten bewusst ihre .btn-Optik. Standalone-Nutzung
 (ohne .btn) bekommt hier den echten CTA-Look.

 Groessen:  Default 36px · .btn-sm 32px · .btn-xs 28px
 Varianten: gefuellt (primaer) · .btn-outline (quiet) · .btn-ghost (leise)
 Icon-only: .btn-icononly (quadratisch; title/aria-label am Callsite Pflicht)
 ========================================================================== */
.app-scope button.app-cta-btn:not(.btn) {
 display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1-5);
 height: 36px; padding: 0 var(--space-3-5); box-sizing: border-box;
 border: none; border-radius: var(--radius-lg);
 background: var(--lod-darkblue); color: var(--lod-white);
 font-size: var(--fs-body); font-weight: var(--fw-semibold);
 cursor: pointer; white-space: nowrap; flex-shrink: 0;
}
.app-scope button.app-cta-btn:not(.btn) img { filter: brightness(0) invert(1); }
.app-scope button.app-cta-btn:not(.btn):hover { background: var(--lod-turquoise); color: var(--lod-darkblue-900); }
.app-scope button.app-cta-btn:not(.btn):hover img { filter: none; }
.app-scope button.app-cta-btn:not(.btn):focus-visible { outline: none; box-shadow: var(--lod-shadow-focus); }
.app-scope button.app-cta-btn:not(.btn):disabled,
.app-scope button.app-cta-btn.is-busy:not(.btn) { opacity: .55; cursor: default; pointer-events: none; }

/* Quiet-Variante (Outline): heller Grund, Icon im Original. */
.app-scope button.app-cta-btn.btn-outline:not(.btn) {
 background: var(--card-bg, #fff); color: var(--lod-darkblue-900);
 border: 1px solid var(--color-border);
}
.app-scope button.app-cta-btn.btn-outline:not(.btn) img { filter: none; }
.app-scope button.app-cta-btn.btn-outline:not(.btn):hover {
 background: var(--bg-secondary, #f6f7f9); border-color: var(--color-border-hover);
 color: var(--lod-darkblue-900);
}

/* Ghost-Variante (randlos, fuer Meta-/Icon-Aktionen in Kopfzeilen). */
.app-scope button.app-cta-btn.btn-ghost:not(.btn) {
 background: transparent; color: var(--color-text-muted); border: none;
}
.app-scope button.app-cta-btn.btn-ghost:not(.btn) img { filter: none; opacity: .65; }
.app-scope button.app-cta-btn.btn-ghost:not(.btn):hover { background: var(--bg-secondary, #f6f7f9); color: var(--lod-darkblue-900); }
.app-scope button.app-cta-btn.btn-ghost:not(.btn):hover img { opacity: 1; filter: none; }

/* Groessen. */
/* WICHTIG: hier stand `--fs-caption` — dieser Token ist 10px (tokens.css:
   --fs-caption: var(--font-size-xs)). Damit trug JEDER kleine CTA-Knopf der App
   10px Schrift; im Browser gemessen und als „unordentlich" gemeldet. 10px liegt
   unter jeder Lesbarkeitsgrenze fuer Bedienelemente. Jetzt --fs-meta (12px);
   die Knopfhoehe bleibt 32px, das Layout aendert sich nicht. */
.app-scope button.app-cta-btn.btn-sm:not(.btn) { height: 32px; padding: 0 var(--space-3); font-size: var(--fs-meta); }
.app-scope button.app-cta-btn.btn-xs:not(.btn) { height: 28px; padding: 0 var(--space-2-5); font-size: var(--fs-caption); }

/* Icon-only (quadratisch). */
.app-scope button.app-cta-btn.btn-icononly:not(.btn) { width: 36px; padding: 0; }
.app-scope button.app-cta-btn.btn-sm.btn-icononly:not(.btn) { width: 32px; }
.app-scope button.app-cta-btn.btn-xs.btn-icononly:not(.btn) { width: 28px; }

/* Touch-Targets ≥38px auf Tablet/Mobile (Responsive-Audit-Regel 4). */
@media (max-width: 999px) {
 .app-scope button.app-cta-btn.btn-sm:not(.btn),
 .app-scope button.app-cta-btn.btn-xs:not(.btn) { height: 38px; }
 .app-scope button.app-cta-btn.btn-sm.btn-icononly:not(.btn),
 .app-scope button.app-cta-btn.btn-xs.btn-icononly:not(.btn) { width: 38px; }
}
