/* ============================================================
   Winterbricks Inventar – Stylesheet (Dark Mode, Material Design 3)
   Markenidentität: Globus aus LEGO-Steinen in Blautönen, das als
   Primärakzent auf neutralen Grau-Oberflächen sitzt (M3 "surface"-
   Farbrollen). Ton-Stufen statt Navy-Einfärbung sorgen für die
   Elevation zwischen Hintergrund, Karten und Eingabefeldern.
   ============================================================ */

:root {
    /* --- Neutrale Oberflächen (M3 surface tones, Tonstufen statt Schatten
       tragen die Elevation-Hierarchie - dunkles M3-Theme) --- */
    --color-bg: #131313;                      /* surface */
    --color-panel: #1e1e20;                   /* surface-container-low - Panels/Karten/Sidebar */
    --color-panel-raised: #29292b;            /* surface-container-high - Inputs, Tabellenkopf */
    --color-surface-container-high: #333335;  /* surface-container-highest - Hover/Dropdown/Menü */
    --color-outline-variant: #2b2b2e;         /* dezenter Rahmen für Karten (Ton trägt die Trennung) */
    --color-line: #3a3a3d;                    /* Trennlinien, Tabellen-Rahmen */
    --color-line-soft: #2a2a2c;               /* dezente Zeilentrenner */
    --color-table: #18181a;                   /* Datentabellen-Fläche - bewusst dunkler als
                                                 --color-panel, damit die Tabelle als eigene Karte
                                                 im Panel liegt, aber heller als --color-bg */

    --color-ink: #ececed;             /* Haupttext (on-surface) */
    --color-ink-soft: #9b9ba0;        /* Sekundärtext (on-surface-variant) */
    --color-ink-faint: #6c6c70;       /* Tertiär-/Platzhaltertext */

    /* --- Direkt aus dem Winterbricks-Logo/-Icon: Markenfarben bleiben erhalten --- */
    --color-brick: #39a6fe;           /* Primärakzent - das helle Steinblau */
    --color-brick-dark: #0e6dcf;      /* gedrückt/hover - das satte Steinblau */
    --color-stud: #9fd6ff;            /* Zweitakzent - das helle Steinblau der obersten Logostufe */

    /* M3-Rollen, auf Markenfarben gemappt */
    --color-primary: var(--color-brick);
    --color-border: var(--color-line);
    --color-surface: var(--color-panel-raised);
    --color-primary-container: #0a2436;   /* das ursprüngliche Icon-Navy, jetzt als Ton-Fläche für Auswahl/aktive Zustände */
    --color-on-primary-container: #9fd6ff;

    --color-ok: #3fc488;
    --color-warn: #e0a83e;
    --color-danger: #f0625e;

    --font-display: Roboto, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    --font-body: Roboto, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    --font-mono: Roboto, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;

    /* --- M3-Formskala --- */
    --radius: 12px;      /* Karten/Panels ("medium") */
    --radius-sm: 8px;    /* Eingabefelder, kleine Bausteine */
    --radius-lg: 20px;   /* große Flächen (Login-Box) */
    --radius-pill: 100px;/* Buttons/Chips ("full") */

    /* M3-Elevation: dezente Doppel-Schatten, die Tonstufe trägt den Großteil der Wirkung */
    --elevation-1: 0 1px 2px rgba(0,0,0,0.3), 0 1px 3px 1px rgba(0,0,0,0.18);
    --elevation-2: 0 1px 2px rgba(0,0,0,0.3), 0 2px 8px 2px rgba(0,0,0,0.24);
    --elevation-3: 0 1px 3px rgba(0,0,0,0.32), 0 4px 12px 3px rgba(0,0,0,0.28);

    --state-hover: rgba(57,166,254,0.08);
    --state-focus: rgba(57,166,254,0.25);
    --state-selected: rgba(57,166,254,0.14);

    /* App ist ausschließlich dunkel gestaltet, aber ohne dies bleiben native
       Browser-Widgets (Select-Popups, Scrollbars, Datepicker) auf dem
       OS-hellen Standard - macht sich am sichtbarsten als weiße Dropdown-Liste
       hinter einem dunkel gestylten <select>. */
    color-scheme: dark;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font-body);
    background: var(--color-bg);
    color: var(--color-ink);
    font-size: 15px;
    line-height: 1.5;
}

/* --- Layout --- */
.app-shell {
    display: grid;
    grid-template-columns: 220px 1fr;
    min-height: 100vh;
}

/* Mobile Top-App-Bar (M3): nur < 880px sichtbar, siehe Media Query weiter unten */
.topbar {
    display: none;
}
.topbar .brand-mark {
    display: flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    color: inherit;
}
.topbar img {
    height: 22px;
    width: auto;
    display: block;
}
.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border: none;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-ink);
    cursor: pointer;
    padding: 0;
}
.nav-toggle:hover { background: rgba(57,166,254,0.12); }
.nav-toggle svg { display: block; }

/* Seitentitel in der mobilen App-Bar: dieselbe Angabe wie im <title>, damit
   nach dem Hochscrollen erkennbar bleibt, wo man ist - die <h1> im Inhalt
   ist dann schon aus dem Bild. Nimmt den freien Platz zwischen Markenzeichen
   und Aktionen ein und wird bei Bedarf abgeschnitten statt umzubrechen. */
.topbar-title {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 700;
    color: #ffffff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Suche, Glocke und Nutzermenü - dieselben Bausteine wie in der
   Desktop-Leiste .app-toolbar (siehe "Leiste oben rechts" weiter unten). */
.topbar-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
    margin-left: auto;
}
/* Schließen-Knopf im Kopf der Schublade - nur mobil sichtbar (siehe Media
   Query unten), auf dem Desktop ist die Sidebar ohnehin dauerhaft da. */
.sidebar-close {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    padding: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-soft);
    cursor: pointer;
}
.sidebar-close:hover { background: var(--state-hover); color: var(--color-ink); }

/* Hülle des Zellinhalts in Karten-Tabellen (siehe .table-cards weiter unten
   und das Skript in includes/layout_footer.php). display:contents heißt: auf
   breiten Viewports erzeugt sie keine eigene Box und ist damit vollständig
   layout-neutral - erst in der Kartenansicht wird sie zum Wertblock. */
.card-val { display: contents; }

.sidebar-backdrop { display: none; }

.sidebar {
    background: var(--color-panel);
    color: var(--color-ink);
    padding: 24px 12px;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    /* Reserviert die Scrollbar-Breite symmetrisch auf beiden Seiten, damit
       das mittig zentrierte Logo nicht durch eine nur rechts einschneidende
       Scrollbar (bei vielen Nav-Einträgen/kleiner Fensterhöhe) nach links
       verschoben aussieht. */
    scrollbar-gutter: stable both-edges;
}

.sidebar .brand {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 24px;
}
.sidebar .brand .brand-link {
    display: block;
    line-height: 0;
    border-radius: var(--radius-sm, 6px);
    text-decoration: none;
}
.sidebar .brand .brand-link:hover img,
.sidebar .brand .brand-link:focus-visible img {
    opacity: 0.8;
}
.sidebar .brand img {
    height: 28px;
    width: auto;
    display: block;
    transition: opacity 0.15s ease;
}
.sidebar .tagline {
    color: var(--color-ink-faint);
    font-size: 0.74rem;
    letter-spacing: 0.02em;
    margin: 6px 0 32px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--color-line);
}

.sidebar nav a {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--color-ink-soft);
    text-decoration: none;
    padding: 12px 16px;
    border-radius: var(--radius-pill);
    font-size: 0.9rem;
    font-weight: 500;
    margin-bottom: 2px;
    transition: background-color 0.15s, color 0.15s;
}
.sidebar nav a svg {
    flex-shrink: 0;
}
.sidebar nav a:hover {
    background: var(--state-hover);
    color: var(--color-ink);
}
.sidebar nav a.active {
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    font-weight: 700;
}

main {
    padding: 32px 40px;
    max-width: 1400px;
    width: 100%;
    /* Grid-Item: ohne das wächst die 1fr-Spalte auf die Mindestbreite des
       Inhalts, und z.B. die scrollbare Reiterzeile in settings.php schob
       bei schmalem Fenster die ganze Seite (samt Leiste oben rechts) über
       den Rand. Mobil gilt dasselbe schon für alle Rasterkinder. */
    min-width: 0;
}

/* ============================================================
   Leiste oben rechts: Suche, Sync-Punkt, Glocke, Nutzermenü
   (includes/layout_header.php, Skript in includes/layout_footer.php).
   Desktop: .app-toolbar als erste Zeile in <main>. Mobil (< 880px) ist sie
   ausgeblendet, dort stecken Suche/Glocke/Menü in der App-Bar (.topbar).
   ============================================================ */
.app-toolbar {
    /* drei Spalten (Zurück | Suche | Icons), damit die Suche mittig steht.
       Die Suche (max. 400px, mittig in ihrer Spalte) schrumpft bis 180px. */
    display: grid;
    grid-template-columns: minmax(max-content, 1fr) minmax(180px, 1.4fr) minmax(max-content, 1fr);
    align-items: center;
    gap: 20px;
    /* läuft über das Padding von main bis an Sidebar und Oberkante */
    margin: -32px -40px 28px;
    padding: 12px 40px;
    position: relative;
    z-index: 20;
}
/* Sidebar und Leiste bilden einen gemeinsamen Rahmen in Panel-Farbe, der
   Seiteninhalt liegt dunkler als "eingelassene Karte" darin.
   Fläche als Pseudo-Element: reicht nach rechts bis an den Fensterrand,
   auch wenn main bei breiten Fenstern an max-width endet. Den Überstand
   schneidet .app-shell (overflow-x: clip) ab. */
.app-toolbar::before {
    content: '';
    position: absolute;
    inset: 0 -100vw 0 0;
    z-index: -1;
    background: var(--color-panel);
}
/* Runde Ecke oben links am Inhalt: ein Viertelkreis-Ausschnitt in
   Rahmenfarbe direkt unter der Leiste, bündig an der Sidebar. */
.app-toolbar::after {
    content: '';
    position: absolute;
    left: 0;
    top: 100%;
    width: 16px;
    height: 16px;
    pointer-events: none;
    background: radial-gradient(circle at 100% 100%, transparent 15.5px, var(--color-panel) 16px);
}
.app-shell { overflow-x: clip; }
.tb-start { display: flex; align-items: center; gap: 12px; min-width: 0; }
.tb-end { display: flex; align-items: center; gap: 6px; justify-self: end; }

/* Zurück: runder Knopf ganz links, Ziel steht im Tooltip. Seiten setzen
   $backUrl/$backLabel vor dem Einbinden von includes/layout_header.php. */
.tb-back {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 38px;
    height: 38px;
    border: 1px solid var(--color-line);
    border-radius: 50%;
    background: var(--color-panel);
    color: var(--color-ink-soft);
    text-decoration: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.tb-back:hover { background: var(--state-hover); border-color: var(--color-brick); color: var(--color-brick); }
.tb-back:focus-visible { outline: 2px solid var(--color-brick); outline-offset: 2px; }

/* Desktop: das Skript am Anfang von includes/layout_footer.php setzt den
   Knopf aus der Leiste als randlosen Pfeil vor die <h1> der Seite. Bis dahin
   bleibt er in der Leiste unsichtbar, damit er nicht kurz aufblitzt. */
.app-toolbar .tb-back { visibility: hidden; }
h1 > .tb-back.h1-back {
    width: 36px;
    height: 36px;
    margin: -4px 8px 0 -8px;
    vertical-align: middle;
    border: 0;
    background: transparent;
    color: var(--color-ink-soft);
}
h1 > .tb-back.h1-back:hover { background: var(--state-hover); color: var(--color-ink); }

/* Einheitlicher Tooltip (assets/js/tooltip.js) für data-tip und title im
   ganzen Tool: ein schwebendes Element statt Browser-Tooltip, erscheint
   schneller und im Stil der App. */
.ui-tip {
    position: fixed;
    z-index: 10000;
    max-width: min(320px, calc(100vw - 16px));
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    background: var(--color-surface-container-high);
    border: 1px solid var(--color-line);
    box-shadow: var(--elevation-2);
    color: var(--color-ink);
    font-size: 0.78rem;
    font-weight: 500;
    line-height: 1.35;
    white-space: pre-line;
    overflow-wrap: anywhere;
    pointer-events: none;
    opacity: 0;
    transform: translateY(-2px);
    transition: opacity 0.12s, transform 0.12s;
}
.ui-tip.is-above { transform: translateY(2px); }
.ui-tip.is-visible { opacity: 1; transform: none; }
.tb-search {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    max-width: 400px;
    min-width: 0;
    justify-self: center;
    height: 38px;
    padding: 0 8px 0 14px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    color: var(--color-ink-faint);
    font: inherit;
    font-size: 0.85rem;
    cursor: text;
    transition: border-color 0.15s, background 0.15s;
}
.tb-search:hover { border-color: var(--color-ink-faint); background: var(--color-surface-container-high); }
.tb-search:focus-visible { outline: 2px solid var(--color-brick); outline-offset: 2px; }
.tb-search-label { flex: 1; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tb-search kbd,
.search-palette kbd {
    font: inherit;
    font-size: 0.7rem;
    padding: 2px 7px;
    border-radius: 6px;
    border: 1px solid var(--color-line);
    background: var(--color-panel-raised);
    color: var(--color-ink-soft);
    white-space: nowrap;
}

.tb-sync {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    text-decoration: none;
}
.tb-sync:hover { background: var(--state-hover); }
/* Punkt mit dauerhaftem Puls: der Ring (::after) wächst und blendet aus.
   transform/opacity statt box-shadow, damit der Browser das ohne Neuzeichnen
   der Seite animiert. Farbe über currentColor, damit Punkt und Ring passen. */
.tb-sync-dot {
    position: relative;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    color: var(--color-ok);
    background: currentColor;
}
.tb-sync-dot::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: currentColor;
    animation: tb-sync-pulse 2.4s ease-out infinite;
}
.tb-sync--warn .tb-sync-dot { color: var(--color-warn); }
.tb-sync--error .tb-sync-dot { color: var(--color-danger); }
.tb-sync--error .tb-sync-dot::after { animation-duration: 1.4s; }
@keyframes tb-sync-pulse {
    0% { transform: scale(1); opacity: 0.55; }
    80%, 100% { transform: scale(2.8); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .tb-sync-dot::after { animation: none; opacity: 0.25; transform: scale(1.8); }
}

.tb-icon-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-soft);
    cursor: pointer;
}
.tb-icon-btn:hover,
.tb-icon-btn[aria-expanded="true"] { background: var(--state-hover); color: var(--color-ink); }
.tb-icon-btn.active { color: var(--color-brick); }
.tb-badge {
    position: absolute;
    top: 3px;
    right: 1px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--color-brick);
    color: #04141f;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--color-bg);
    pointer-events: none;
}
.tb-badge.is-warning  { background: var(--color-warn); color: #1a1204; }
.tb-badge.is-critical { background: var(--color-danger); color: #fff; }

/* Glocke läuten: der Körper wiegt sich leicht am Aufhängepunkt, der Klöppel
   schlägt sichtbar hin und her, vom Zähler läuft ein Ring nach außen.
   Ausgelöst per Klasse .is-ringing aus assets/js/app-toolbar.js - beim
   Darüberfahren und alle 10 s, solange Ungelesenes da ist. */
.tb-bell svg { overflow: visible; }
.tb-bell-body,
.tb-bell-clapper { transform-origin: 12px 2.5px; }
.tb-badge::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 2px solid var(--color-brick);
    opacity: 0;
}
.tb-badge.is-warning::after  { border-color: var(--color-warn); }
.tb-badge.is-critical::after { border-color: var(--color-danger); }
.tb-bell.is-ringing .tb-bell-body    { animation: tb-bell-sway 1s ease-in-out; }
.tb-bell.is-ringing .tb-bell-clapper { animation: tb-bell-clap 1s ease-in-out; }
.tb-bell.is-ringing .tb-badge::after { animation: tb-bell-pulse 1.1s ease-out; }
@keyframes tb-bell-sway {
    0%, 100% { transform: rotate(0); }
    20%      { transform: rotate(7deg); }
    45%      { transform: rotate(-6deg); }
    70%      { transform: rotate(3deg); }
}
@keyframes tb-bell-clap {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-3px); }
    50%      { transform: translateX(3px); }
    75%      { transform: translateX(-1.5px); }
}
@keyframes tb-bell-pulse {
    0%   { transform: scale(1);   opacity: .8; }
    100% { transform: scale(2.2); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .tb-bell.is-ringing .tb-bell-body,
    .tb-bell.is-ringing .tb-bell-clapper,
    .tb-bell.is-ringing .tb-badge::after { animation: none; }
}
.topbar .tb-badge { box-shadow: 0 0 0 2px var(--color-panel); }

.tb-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin-left: 4px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
}
/* Hover-Ring 3px: 34px + 2×3px = 40px, so groß wie der Hover-Kreis von
   Sync-Punkt und Glocke. */
button.tb-avatar:hover,
button.tb-avatar[aria-expanded="true"] { box-shadow: 0 0 0 3px var(--state-hover); }
.tb-avatar--lg { width: 40px; height: 40px; margin: 0; font-size: 1rem; }

/* --- Aufklapp-Flächen (Glocke, Nutzermenü) --- */
.tb-pop-anchor { position: relative; }
.tb-pop {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 300;
    background: var(--color-panel-raised);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    box-shadow: var(--elevation-3);
    overflow: hidden;
}
.tb-pop[hidden] { display: none; }
/* Glocke beim ersten Öffnen: unsichtbar, bis die Liste geladen ist (app-toolbar.js). */
.tb-pop.is-pending { visibility: hidden; }

.notif-pop {
    width: 400px;
    max-height: min(560px, calc(100vh - 90px));
    display: flex;
    flex-direction: column;
}
.notif-pop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px 10px;
    border-bottom: 1px solid var(--color-line);
}
.notif-pop-title { font-weight: 700; color: #fff; }
.notif-pop-readall {
    border: 0;
    background: none;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    color: var(--color-brick);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}
.notif-pop-readall:hover { background: var(--state-hover); }
.notif-pop-readall:disabled { color: var(--color-ink-faint); cursor: default; background: none; }
.notif-pop-list {
    overflow-y: auto;
    flex: 1 1 auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px;
}
.notif-pop .notif-item { --notif-card: var(--color-surface-container-high); background: var(--notif-card); }
.notif-pop .notif-item:hover { --notif-card: var(--color-line); }
.notif-pop .notif-check { background: var(--color-panel-raised); }
.notif-pop-empty {
    padding: 36px 20px;
    text-align: center;
    color: var(--color-ink-soft);
    font-size: 0.85rem;
}
.notif-pop-empty svg { display: block; margin: 0 auto; color: var(--color-ok); }
.notif-pop-foot {
    display: block;
    padding: 12px 16px;
    border-top: 1px solid var(--color-line);
    text-align: center;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-brick);
    text-decoration: none;
}
.notif-pop-foot:hover { background: var(--state-hover); }

/* Eine Meldung - im Dropdown und auf notifications.php gleich aufgebaut:
   jede als eigene Karte mit Tonfläche statt Zeilen mit Trennlinie, Icon und
   Haken vertikal mittig. Die Kartenfarbe hängt vom Untergrund ab (Dropdown
   liegt auf panel-raised, die Seite auf bg) und steht deshalb unten je Ort. */
.notif-item {
    display: grid;
    grid-template-columns: 44px 1fr auto;
    gap: 14px;
    align-items: center;
    padding: 12px 12px 12px 14px;
    border-radius: var(--radius);
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}
.notif-icon {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}
.notif-icon svg { width: 22px; height: 22px; }
.notif-item--warning .notif-icon { background: rgba(224, 168, 62, 0.16); color: var(--color-warn); }
.notif-item--critical .notif-icon { background: rgba(240, 98, 94, 0.16); color: var(--color-danger); }
.notif-text { min-width: 0; }
.notif-title {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--color-ink);
    line-height: 1.35;
    overflow-wrap: anywhere;
}
.notif-body {
    margin-top: 2px;
    font-size: 0.8rem;
    color: var(--color-ink-soft);
    line-height: 1.4;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.notif-meta {
    margin-top: 4px;
    font-size: 0.72rem;
    color: var(--color-ink-faint);
}
/* Im Panel steht die Zeile direkt unter dem Titel (kein Nachrichtentext) */
.notif-pop .notif-meta { margin-top: 2px; color: var(--color-ink-soft); }
/* Anzahl zusammengefasster Meldungen - als Zähler am Icon wie an der Glocke
   (.tb-badge), in der Farbe der Schwere. Der Ring nimmt die Kartenfarbe
   (--notif-card) an, damit der Kreis aus dem Icon "ausgestanzt" wirkt. */
.notif-count {
    position: absolute;
    bottom: -4px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--color-brick);
    color: #04141f;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--notif-card, var(--color-panel));
    pointer-events: none;
}
.notif-item--warning .notif-count { background: var(--color-warn); color: #1a1204; }
.notif-item--critical .notif-count { background: var(--color-danger); color: #fff; }
.notif-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--color-surface-container-high);
    color: var(--color-ink-soft);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.12s;
}
.notif-item:hover .notif-check,
.notif-check:focus-visible { opacity: 1; }
.notif-check:hover { background: var(--state-selected); color: var(--color-ok); }
/* Touch-Geräte haben kein Hover - dort den Haken immer zeigen. */
@media (hover: none) { .notif-check { opacity: 1; } }

/* Übersichtsseite notifications.php */
/* Umschalter in derselben randlosen 44px-Tonfläche wie die Auswahlfelder
   daneben (.filter-bar select), damit die Filterzeile aus einem Guss ist. */
.notif-tabs {
    display: inline-flex;
    align-items: center;
    height: 44px;
    padding: 4px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
}
.notif-tabs .notif-tab { height: 36px; display: inline-flex; align-items: center; justify-content: center; }
/* Eine Schrift für die ganze Filterzeile - Reiter, Auswahlmenüs und Knopf
   brachten sonst drei Größen/Stärken (und der Knopf die Browser-Schrift) mit. */
.notif-filter .notif-tab,
.notif-filter .md3-dropdown-trigger,
.notif-filter .colorfilter-trigger,
.notif-filter .btn {
    font-family: inherit;
    font-size: 0.88rem;
    font-weight: 500;
}
.notif-filter .btn {
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
    color: var(--color-ink);
    padding: 0 20px;
}
.notif-filter .btn:hover { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.notif-tab {
    padding: 6px 16px;
    border-radius: var(--radius-pill);
    color: var(--color-ink-soft);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.notif-tab:hover { color: var(--color-ink); }
/* Mobil steht der Umschalter als eigene volle Zeile über den Auswahlmenüs.
   Die Filterleiste gibt jedem Kind sonst eine halbe Zeile und erlaubt
   Umbruch - die drei Reiter stapelten sich dann in einer Blase. */
@media (max-width: 600px) {
    .filter-bar > .notif-tabs {
        flex-basis: 100% !important;
        flex-wrap: nowrap;
    }
    .notif-tabs .notif-tab {
        flex: 1 1 auto;
        text-align: center;
        padding: 9px 10px;
    }
}
.notif-tab.is-active { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.notif-tab-count {
    display: inline-block;
    min-width: 18px;
    padding: 0 5px;
    margin-left: 4px;
    border-radius: var(--radius-pill);
    background: var(--color-brick);
    color: #04141f;
    font-size: 0.7rem;
    line-height: 18px;
    text-align: center;
}
/* Bestell- und Kundenübersicht (orders.php, customers.php): Filterzeile im
   Stil von notifications.php. Suchbegriff aus der globalen Suche als Chip,
   rechts die Pickprozess-Knöpfe bzw. die Kundenzahl. */
.order-search-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    max-width: 260px;
    padding: 0 6px 0 16px;
    border-radius: var(--radius-pill);
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    font-size: 0.88rem;
    font-weight: 500;
}
.order-search-chip-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.order-search-chip-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    color: inherit;
}
.order-search-chip-x:hover { background: var(--state-hover); }
/* Trefferzahl rechts in der Filterzeile (customers.php, articles.php): dieselbe 44px-
   Tonpille wie Reiter und Knöpfe daneben statt der hohen Kennzahl-Karte. */
.filter-total {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    margin-left: auto;
    padding: 0 18px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
    color: var(--color-ink-soft);
    font-size: 0.88rem;
    font-weight: 500;
    white-space: nowrap;
}
.filter-total strong { color: var(--color-ink); font-weight: 700; }
.order-pick-actions {
    display: flex;
    gap: 8px;
    margin-left: auto;
}
.order-pick-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--color-surface-container-high);
    color: var(--color-ink);
    cursor: pointer;
    text-decoration: none;
}
.order-pick-btn:hover { background: var(--color-primary-container); color: var(--color-on-primary-container); }
/* Start-Knopf: grau, bis mindestens eine Bestellung markiert ist. */
.order-pick-btn--primary.is-ready { background: var(--color-brick); color: #04141f; }
.order-pick-btn--primary.is-ready:hover { background: var(--color-brick); filter: brightness(1.1); color: #04141f; }
.order-pick-btn:disabled { opacity: 0.4; cursor: not-allowed; filter: none; }
/* Zähler am Knopf (shipping.php: markierte Bestellungen am Label-Knopf). */
.order-pick-btn { position: relative; }
.order-pick-count {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--color-ink);
    color: var(--color-bg);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}
.order-pick-count[hidden] { display: none; }
/* Kundenübersicht: Kasten "Manuelle Prüfung" (customers.php) - offene
   Aufgabe, daher Warnfarbe am Rand; Auswahl + Knöpfe in einer Zeile. */
.customer-review-panel { border-color: rgba(224, 168, 62, 0.4); }
.customer-review-panel h2 { margin-bottom: 4px; }
.customer-review-panel .page-sub { margin-top: 0; }
.customer-review-form { display: flex; align-items: center; gap: 8px; margin: 0; }
.customer-review-form .md3-dropdown { min-width: 220px; }
@media (max-width: 760px) {
    .customer-review-form { flex-wrap: wrap; }
    .customer-review-form .md3-dropdown { flex: 1 1 100%; }
}
/* Versand-Kopfleiste: die Dienstleister-Chips auf die 44px-Pillenhöhe der
   Reiter und Knöpfe daneben, statt als 64px hohe Kacheln herauszuragen. */
.ship-filter .order-summary-bar {
    margin: 0 0 0 auto;
    gap: 8px;
}
.ship-filter .order-summary-stat {
    height: 44px;
    padding: 0 18px 0 4px;
    gap: 10px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
}
.ship-filter .order-summary-icon {
    width: 36px;
    height: 36px;
    background: var(--color-panel-raised);
}
.ship-filter .order-summary-icon svg { width: 18px; height: 18px; }
.ship-filter .order-summary-label { font-size: 0.62rem; line-height: 1.2; }
.ship-filter .order-summary-value { line-height: 1.2; }
.ship-filter .order-summary-bar + .order-pick-actions { margin-left: 8px; }
@media (max-width: 600px) {
    .ship-filter > .order-summary-bar { flex-basis: 100% !important; margin-left: 0; }
}
@media (max-width: 600px) {
    .filter-bar > .order-search-chip { flex-basis: 100% !important; max-width: none; justify-content: space-between; }
    .filter-bar > .filter-total { justify-content: center; margin-left: 0; }
    .filter-bar > .order-pick-actions {
        justify-content: flex-end;
        margin-left: 0;
    }
}

.notif-list-page { display: flex; flex-direction: column; gap: 8px; margin-bottom: 24px; }
.notif-list-page .notif-item {
    cursor: default;
    padding: 14px 16px 14px 20px;
    --notif-card: var(--color-panel);
    background: var(--notif-card);
}
.notif-list-page .notif-item:hover { --notif-card: var(--color-panel-raised); }
.notif-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 40px 20px;
    border-radius: var(--radius);
    background: var(--color-panel);
    color: var(--color-ink-soft);
    font-size: 0.92rem;
}
.notif-empty svg { color: var(--color-ink-faint); }
.notif-list-page .notif-item.is-read { opacity: 0.62; }
.notif-list-page .notif-item.is-read:hover { opacity: 1; }
.notif-list-page .notif-title a { color: inherit; text-decoration: none; }
.notif-list-page .notif-title a:hover { color: var(--color-brick); }
.notif-list-page .pagination { padding: 12px 0 0; }
.notif-body--full { -webkit-line-clamp: unset; display: block; }
.notif-check--visible { opacity: 1; }
.notif-unread-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--color-brick);
    vertical-align: 1px;
}

.user-pop { width: 240px; padding: 6px 0; }
.user-pop-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px 12px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--color-line);
}
.user-pop-name { font-weight: 700; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-pop-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 16px;
    color: var(--color-ink);
    font-size: 0.88rem;
    text-decoration: none;
}
.user-pop-item svg { color: var(--color-ink-soft); flex: none; }
.user-pop-item:hover { background: var(--state-hover); }
.user-pop-item--sep { margin-top: 6px; border-top: 1px solid var(--color-line); padding-top: 11px; }

/* --- Globale Suche (Strg+K) --- */
.search-palette {
    position: fixed;
    inset: 0;
    z-index: 500;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 12vh 16px 16px;
    background: rgba(0, 0, 0, 0.55);
}
.search-palette[hidden] { display: none; }
.search-palette-box {
    width: 100%;
    max-width: 640px;
    max-height: 70vh;
    display: flex;
    flex-direction: column;
    background: var(--color-panel-raised);
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    box-shadow: var(--elevation-3);
    overflow: hidden;
}
.search-palette-field {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 16px;
    border-bottom: 1px solid var(--color-line);
    color: var(--color-ink-soft);
}
.search-palette-field input {
    flex: 1;
    min-width: 0;
    height: 56px;
    border: 0 !important;
    border-radius: 0;
    box-shadow: none !important;
    padding: 0;
    background: transparent !important;
    color: var(--color-ink);
    font: inherit;
    font-size: 1.05rem;
    outline: none;
}
.search-palette-results { overflow-y: auto; padding: 6px 0; }
.search-palette-hint {
    padding: 22px 20px;
    text-align: center;
    font-size: 0.85rem;
    color: var(--color-ink-soft);
}
.search-group-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 10px 16px 4px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-ink-faint);
}
.search-group-label a {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 600;
    color: var(--color-brick);
    text-decoration: none;
}
.search-group-label a:hover { color: #5cb6ff; }
.search-result {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
    color: var(--color-ink);
    text-decoration: none;
}
.search-result.is-active { background: var(--state-selected); }
.search-result-text { flex: 1; min-width: 0; }
.search-palette-field input::-webkit-search-cancel-button { display: none; }
/* Bereichsfilter "Bestellungen" vor dem Suchfeld (M3 filter chip):
   gefüllt = aktiv, nur umrandet = aus. */
.search-scope {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: none;
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-ink-soft);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}
.search-scope:hover { background: var(--state-hover); color: var(--color-ink); }
.search-scope.is-active {
    border-color: transparent;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}
.search-scope-check { display: none; }
.search-scope.is-active .search-scope-check { display: block; }
.search-result-title,
.search-result-sub { display: block; }
.search-result-title { font-size: 0.9rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-result-sub { font-size: 0.76rem; color: var(--color-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-result-badge {
    flex: none;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
    color: var(--color-ink-soft);
    font-size: 0.7rem;
    font-weight: 600;
}
.search-palette-foot {
    display: flex;
    gap: 16px;
    padding: 8px 16px;
    border-top: 1px solid var(--color-line);
    font-size: 0.72rem;
    color: var(--color-ink-faint);
}

@media (max-width: 880px) {
    .app-toolbar { display: none; }
    /* mobil steckt Zurück schon in der App-Bar */
    h1 > .h1-back { display: none !important; }
    .topbar-actions .tb-avatar { width: 32px; height: 32px; margin: 0 2px 0 4px; }
    .topbar .tb-back { width: 36px; height: 36px; border-color: transparent; background: none; }
    /* Mobil hängt das Dropdown nicht am Knopf, sondern läuft über die ganze
       Breite direkt unter der App-Bar. */
    .topbar .tb-pop {
        position: fixed;
        top: calc(60px + env(safe-area-inset-top));
        left: 8px;
        right: 8px;
        width: auto;
    }
    .topbar .notif-pop { max-height: calc(100dvh - 80px - env(safe-area-inset-top)); }
    .topbar .user-pop { left: auto; width: 240px; }
    .search-palette { padding: calc(8px + env(safe-area-inset-top)) 8px 8px; }
    .search-palette-box { max-height: calc(100dvh - 16px); }
    .search-palette-foot { display: none; }
}

/* --- Headings --- */
h1 {
    font-family: var(--font-display);
    font-size: 1.6rem;
    margin: 0 0 20px;
    color: #ffffff;
}
h2 {
    font-family: var(--font-display);
    font-size: 1.15rem;
    margin: 0 0 12px;
    color: #ffffff;
}
.page-sub {
    color: var(--color-ink-soft);
    font-size: 0.9rem;
    margin-bottom: 28px;
}

/* --- Cards / KPIs --- */
.kpi-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 16px;
    margin-bottom: 32px;
}
.kpi-card {
    position: relative;
    background: var(--color-panel);
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    padding: 18px 20px;
    box-shadow: var(--elevation-1);
}
/* Rundes, graues Icon oben rechts in einer kpi-card - z.B. Link vom
   Bestelldetail zu den zugehörigen Kundendaten (order_detail.php). */
.kpi-card-corner-link {
    position: absolute;
    top: 50%;
    right: 14px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: none;
    padding: 0;
    border-radius: 50%;
    background: var(--color-surface-container-high);
    color: var(--color-ink-soft);
    cursor: pointer;
    font: inherit;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
/* Steht das Rund in einer Zeile mit Wert (Name, E-Mail im Bestelldetail),
   läuft ein langer Wert sonst darunter durch. */
:not(.kpi-card):has(> .kpi-card-corner-link, > form > .kpi-card-corner-link) {
    padding-right: 46px;
}
/* E-Mail-Adresse in schmalen Karten (renderEmailAddress() in list_helpers.php):
   Umbruch nur vor dem "@", Domain am Stück, überlanger Lokalteil mit "…". */
.email-split { display: inline-flex; flex-wrap: wrap; max-width: 100%; vertical-align: top; }
.email-local,
.email-domain { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.email-domain { opacity: 0.7; }
/* Einzeilige Variante (Bestelldetail): nur der Lokalteil schrumpft, und das
   um gut 5 Zeichen früher als nötig - so bleibt Luft zum Rund-Icon daneben. */
.email-oneline .email-split { display: flex; flex-wrap: nowrap; max-width: calc(100% - 5ch); }
.email-oneline .email-domain { flex-shrink: 0; }
.kpi-card-corner-link.is-warn { background: rgba(224,168,62,0.16); color: var(--color-warn); }
.kpi-card-corner-link:hover {
    background: var(--color-brick);
    color: #ffffff;
}
.kpi-card .label {
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-ink-soft);
    margin-bottom: 6px;
}
.kpi-card .value {
    font-family: var(--font-display);
    font-size: 1.7rem;
    font-weight: 700;
    color: #ffffff;
}
.kpi-card-hr {
    height: 2px;
    background: var(--color-outline-variant);
    margin: 14px 0;
}
/* --- Schritt-Karten (z.B. Bilder aufbereiten: mehrere Arbeitsschritte
   nebeneinander) - eigene Tonfläche je Schritt statt loser Absätze, mit
   nummeriertem Punkt in Markenfarbe als Blickfang. --- */
.step-cards {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 14px;
}
.step-card {
    flex: 1 1 240px;
    min-width: 220px;
    background: var(--color-panel-raised);
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    padding: 16px 18px;
}
.step-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 4px;
}
.step-card-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--color-brick);
    color: #04141f;
    font-size: 0.78rem;
    font-weight: 700;
}
.step-card strong {
    font-size: 0.9rem;
}
/* M3 "tonal" Icon-Button-Leiste inline in einer kpi-card-Zeile (Adressblock
   in customer_detail.php: Bearbeiten, Maps, Bestätigen, Erneut prüfen) - im
   Gegensatz zu .kpi-card-corner-link nicht absolut positioniert, sondern Teil
   des normalen Textflusses. Runde Fläche auf grauer Tonfarbe (statt nur bei
   Hover eingefärbt), damit die Aktionsleiste als zusammengehörige Gruppe
   erkennbar ist. */
.icon-link-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: none;
    padding: 0;
    background: var(--color-panel-raised);
    color: var(--color-ink-soft);
    cursor: pointer;
    border-radius: 50%;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.icon-link-btn:hover {
    background: var(--color-surface-container-high);
    color: var(--color-brick);
}
/* Korrekturvorschlag-Kasten im Adressblock (customer_detail.php), wenn der
   Adresscheck über OpenStreetMap eine Abweichung meldet - gleiche
   Amber-Farbsprache wie das "Manuelle Prüfung"-Panel auf customers.php. */
.address-suggestion-box {
    margin-top: 12px;
    padding: 10px 12px;
    border: 1px solid rgba(224,168,62,0.35);
    border-radius: var(--radius);
    background: rgba(224,168,62,0.08);
}

/* M3-Stat-Card mit zwei nebeneinander liegenden Kennzahlen, getrennt durch
   eine dezente Outline-Variant-Linie (M3-Divider-Rolle) statt einer zweiten
   eigenständigen Karte - für inhaltlich zusammengehörige Kennzahlenpaare. */
.kpi-card-split {
    display: flex;
    align-items: stretch;
    gap: 20px;
}
.kpi-card-split .kpi-stat {
    flex: 1 1 0;
    min-width: 0;
}
.kpi-card-split .kpi-stat-divider {
    flex: 0 0 auto;
    align-self: stretch;
    width: 1px;
    background: var(--color-outline-variant);
}
.kpi-card-split .value { font-size: 1.3rem; }
@media (max-width: 480px) {
    .kpi-card-split {
        flex-direction: column;
        gap: 14px;
    }
    .kpi-card-split .kpi-stat-divider {
        width: auto;
        height: 1px;
    }
}
a.kpi-link {
    display: block;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}
a.kpi-link:hover {
    border-color: var(--color-brick);
    box-shadow: 0 0 0 1px var(--color-brick);
}

/* --- Bestellung-Detailansicht: Kennzahlen-Leiste über der Artikel-Tabelle
   (M3 Stat-Chips statt eigener KPI-Karten) - alle vier Kennzahlen als
   eigenständige Chips, als Gruppe rechtsbündig ausgerichtet. */
.order-summary-bar {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 12px;
    margin-bottom: 20px;
}
.order-summary-stat {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--color-panel-raised);
    border-radius: var(--radius);
    padding: 10px 18px;
}
.order-summary-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--color-surface-container-high);
    color: var(--color-ink-soft);
}
/* Ist der Kreis ein Link (Deutsche Post -> Versandeinstellungen, siehe
   shipping.php), soll man das auch sehen: sonst unterscheidet ihn nichts von
   den rein anzeigenden Kreisen daneben. */
a.order-summary-icon {
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
a.order-summary-icon:hover {
    background: var(--state-hover);
    color: var(--color-brick);
}
.order-summary-label {
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-ink-soft);
    margin-bottom: 2px;
}
.order-summary-value {
    font-family: var(--font-display);
    font-size: 1.1rem;
    font-weight: 700;
    color: #ffffff;
}
@media (max-width: 640px) {
    .order-summary-bar { justify-content: flex-start; }
    /* Als umbrechende Zeile wurden die Chips unterschiedlich breit (einer
       allein, dann zwei nebeneinander) - im Zweierraster stehen sie bündig. */
    .order-summary-bar:not(.order-summary-bar--stacked) {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
    }
    .order-summary-bar:not(.order-summary-bar--stacked) .order-summary-stat {
        min-width: 0;
        gap: 8px;
        padding: 10px;
    }
    .order-summary-bar:not(.order-summary-bar--stacked) .order-summary-stat > :last-child {
        min-width: 0;
    }
    .order-summary-bar:not(.order-summary-bar--stacked) .order-summary-icon {
        width: 32px;
        height: 32px;
    }
    /* "VERSANDKOSTEN" muss neben dem Icon in eine halbe Handybreite passen. */
    .order-summary-bar:not(.order-summary-bar--stacked) .order-summary-label {
        font-size: 0.64rem;
        letter-spacing: 0.02em;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}
/* --- Kunden-Detailansicht: dieselben Stat-Chips wie order-summary-bar, aber
   untereinander statt nebeneinander und alle gleich breit (Statistik-Panel in
   customer_detail.php) statt rechtsbündig zeilenweise wie im Bestelldetail. */
.order-summary-bar--stacked {
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: flex-start;
}
.order-summary-bar--stacked .order-summary-stat {
    width: 100%;
}

/* --- Bestellung-Detailansicht: Käufer/Rechnungen/Versand als gleichrangige
   Panels in einer Zeile statt großer, voller Blöcke untereinander. */
.order-overview-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 16px;
    align-items: stretch;
    margin-bottom: 24px;
}
.order-overview-row .panel {
    margin-bottom: 0;
}
.order-overview-row .kpi-card {
    padding: 24px;
}

/* --- Bestellung-Detailansicht: Rechnungen-Panel als kompakte Karten statt
   breiter Tabelle - braucht weniger Platz, da eine Bestellung ohnehin
   maximal zwei Rechnungen hat (Regel-/Differenzbesteuerung, siehe §25a UStG). */
.invoice-card-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.invoice-card {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 14px;
    background: var(--color-panel-raised);
    border-radius: var(--radius);
    padding: 14px 18px;
}
.invoice-card-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}
.invoice-card-body { flex: 1 1 auto; min-width: 0; }
/* Ohne Kopfzeile (Versandlabel) ist die Karte ein umbrechender Flex: auf dem
   Handy war der Textblock mit der langen Sendungsnummer breiter als der Rest
   der Zeile, die Knöpfe fielen als senkrechte Pille in eine eigene Zeile. */
@media (max-width: 640px) {
    .invoice-card { flex-wrap: nowrap; }
}
/* Kopf einer Rechnungskarte: Nummer und rechts daneben das Steuerart-Badge
   sowie - bei einer Stornorechnung - das Storno-Badge, alles in einer Zeile.
   Der Kopf laeuft ueber die volle Kartenbreite (flex: 1 0 100% in der
   umbrechenden .invoice-card), weil die Spalte neben den Aktionsknoepfen im
   dreispaltigen Bestellueberblick nur ~173px breit ist. Beide Badges zeigen
   dort nur ihr Icon (renderTaxSchemeBadge($scheme, true) bzw.
   renderStornoBadge()) - mit Text braeuchten Nummer und Badges zusammen ~290px
   und wuerden zwangslaeufig umbrechen. */
.invoice-card-head {
    flex: 1 0 100%;
    display: flex;
    align-items: center;
    gap: 8px;
}
.invoice-card-number { font-weight: 700; }
.invoice-card-badges {
    display: flex;
    align-items: center;
    gap: 6px;
    /* Die Badges gegen die Rechnungsnummer optisch ausrichten, nicht gegen deren
       Zeilenkasten. Der ist 22,5px hoch und enthaelt 4px Unterlaenge, die eine
       Nummer wie "WB-SR0051" (nur Versalien und Ziffern) nie nutzt - mittig im
       Kasten sitzt der Kreis dadurch unter der Mitte der sichtbaren Schrift.
       Der Versatz betraegt 0,5px; -1px ergibt genau das, weil align-items: center
       den Rand beim Zentrieren zur Haelfte wieder herausrechnet. Nachgemessen:
       Badge-Mitte und Mitte der Schriftflaeche liegen danach exakt aufeinander. */
    margin-top: -1px;
}
.invoice-card-badges > .badge { flex: 0 0 auto; }
.badge.invoice-storno-badge {
    text-transform: none;
    letter-spacing: normal;
}
/* Stornierte Menge in der Mengenspalte der Positionstabelle: nur die Zahl in
   Klammern, fett und in der Warnfarbe, damit sie sich auf einen Blick von der
   bestellten Menge daneben abhebt. */
.qty-cancelled {
    font-weight: 700;
    color: var(--color-danger);
}
.invoice-card-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}
.invoice-card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.invoice-card-total {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    color: #ffffff;
    white-space: nowrap;
}
.invoice-card-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 8px;
}
.invoice-card-meta { font-size: 0.78rem; color: var(--color-ink-soft); }
.invoice-card-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    background: var(--color-panel);
    border-radius: var(--radius-pill);
    padding: 3px;
}
.invoice-card-actions form { display: contents; }
.invoice-card-actions .order-action-btn { width: 34px; height: 34px; }
/* Versandlabel: Download und Storno untereinander, der Block bleibt rechts. */
.invoice-card-actions.is-stacked { flex-direction: column; }
/* Rechnungskarte mit Kopfzeile (Nummer + Badges): als Raster statt umbrechendem
   Flex. Im Flex-Umbruch trennte die Kartenluecke (gap: 14px) die Nummer vom
   Betrag darunter, obwohl beide zusammengehoeren, und die Aktionsknoepfe sassen
   nur in der zweiten Zeile mittig - also sichtbar unterhalb der Kartenmitte.
   Im Raster steht die Knopfspalte ueber beide Zeilen und wird gegen die ganze
   Karte zentriert; der Zeilenabstand faellt auf 2px. */
.invoice-card:has(> .invoice-card-head) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 14px;
    row-gap: 2px;
}
.invoice-card:has(> .invoice-card-head) > .invoice-card-head { grid-column: 1; grid-row: 1; }
.invoice-card:has(> .invoice-card-head) > .invoice-card-body { grid-column: 1; grid-row: 2; }
.invoice-card:has(> .invoice-card-head) > .invoice-card-actions {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
}

/* Panel-Kopf mit Icon: ein graues Rund steht mittig neben Überschrift und
   Unterzeile, statt vor jeder Zeile einzeln zu wiederholen. */
.panel-head-with-icon {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}
.panel-head-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--color-surface-container-high);
    color: var(--color-ink-soft);
}

.panel {
    background: var(--color-panel);
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    padding: 24px;
    margin-bottom: 24px;
    box-shadow: var(--elevation-1);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Kopfzeile eines Panels: Überschrift links, ein Steuerelement (z.B. der
   Import-Modus-Umschalter auf import.php) rechtsbündig daneben. */
.panel-head-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px 20px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.panel-head-row > h2 { margin: 0; }

/* --- MD3 Segmented Button (2-Segment-Umschalter, z.B. "Wareneingang" /
   "Vollabgleich" beim XML-Import). Die Radios liegen visuell verborgen
   direkt in .seg, das zugehörige Label folgt als Nachbar - das gewählte
   Segment bekommt über input:checked + label die Auswahl-Tonfläche
   (gleiches Muster wie .ebay-toggle-input:checked ~ ...). --- */
.seg {
    display: inline-flex;
    flex: 0 0 auto;
    gap: 3px;
    padding: 3px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
}
.seg input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.seg label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 6px 16px;
    border-radius: var(--radius-pill);
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-ink-soft);
    white-space: nowrap;
    user-select: none;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.seg label:hover { color: var(--color-ink); }
.seg input:checked + label {
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}
.seg input:focus-visible + label {
    outline: 2px solid var(--color-brick);
    outline-offset: 2px;
}

/* --- Tabs (z.B. Einstellungen) - MD3 Primary Tabs --- */
.settings-tabs {
    display: flex;
    border-bottom: 1px solid var(--color-line);
    margin-bottom: 24px;
    overflow-x: auto;
    scrollbar-width: none;      /* Firefox: schmalen Scrollbalken am Zeilenende ausblenden */
    -ms-overflow-style: none;   /* alte Edge/IE */
}
.settings-tabs::-webkit-scrollbar { display: none; } /* Chrome/Edge/Safari */
.settings-tab {
    appearance: none;
    background: none;
    border: none;
    position: relative;
    color: var(--color-ink-soft);
    font-family: var(--font-body);
    font-size: 0.875rem;
    font-weight: 500;
    height: 48px;
    padding: 0 18px;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.15s ease, background-color 0.15s ease;
}
.settings-tab::after {
    content: "";
    position: absolute;
    left: 8px;
    right: 8px;
    bottom: 0;
    height: 3px;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    background: var(--color-brick);
    opacity: 0;
    transform: scaleX(0.6);
    transition: opacity 0.15s ease, transform 0.15s ease;
}
.settings-tab:hover { color: var(--color-ink); background: var(--state-hover); }
.settings-tab:focus-visible { outline: 2px solid var(--color-brick); outline-offset: -2px; }
.settings-tab.active { color: var(--color-ink); font-weight: 600; }
.settings-tab.active::after { opacity: 1; transform: scaleX(1); }
.settings-tab-panel[hidden] { display: none; }

.settings-subtabs {
    display: flex;
    gap: 6px;
    margin-bottom: 18px;
    flex-wrap: wrap;
}
.settings-subtab {
    appearance: none;
    border: 1px solid var(--color-line);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-ink-soft);
    font-family: var(--font-body);
    font-size: 0.82rem;
    font-weight: 500;
    padding: 6px 14px;
    cursor: pointer;
}
.settings-subtab:hover { color: var(--color-ink); background: var(--state-hover); }
.settings-subtab.active { color: #fff; background: var(--color-brick); border-color: var(--color-brick); }
.settings-subtab-panel[hidden] { display: none; }

/* Zeile, die gerade im Formular darunter bearbeitet wird (?edit_mapping=...) */
tr.is-editing > td { background: var(--state-hover); }
tr.is-editing > td:first-child { box-shadow: inset 3px 0 0 var(--color-brick); }

/* --- Tabellen: eine Designsprache für das ganze Tool -------------------
   Referenz ist die Artikelübersicht (articles.php): eine Tabelle ist eine
   eigene Karte im Panel - eigener, vom .panel abgesetzter dunklerer Ton
   (--color-table), abgerundete Ecken (overflow:hidden clippt die
   Zell-Hintergründe der Rand-Zeilen an die Rundung), Kopfzeile in
   --color-panel-raised mit kräftigerer Trennlinie, dezente Zeilentrenner
   und grauer Zeilen-Hover.

   Diese Grundoptik hängt bewusst am nackten <table>-Element und nicht an
   einer Klasse: so liegt jede Tabelle im Tool - auch jede neu hinzukommende -
   ohne Zutun in derselben Designsprache. Die Tabellenklassen
   (.articles-table, .orders-table, .lots-table, .pick-table, .import-table,
   .bb-table, .order-items-table, .history-table …) sind seither nur noch
   Anker für tabellenspezifische Feinheiten wie Spaltenbreiten oder
   Sonder-Hover, nicht mehr Träger der Optik selbst.

   Ausnahme ist .table-plain (siehe unten) für Tabellen, die reines Layout
   sind - Schlüssel/Wert-Listen ohne Kopfzeile. */
table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
    background: var(--color-table);
    border-radius: var(--radius);
    overflow: hidden;
}
thead tr { background: var(--color-panel-raised); }
th {
    text-align: left;
    color: var(--color-ink-soft);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.01em;
    padding: 12px;
    border-bottom: 1px solid var(--color-line);
}
/* Kopfzeile: etwas größere Schrift als der globale th-Standard (der auch für
   th-Zellen im Tabellenkörper gilt) und eine 2px- statt 1px-Trennlinie,
   damit der Kopf klar vom Tabellenkörper abgesetzt ist. vertical-align
   explizit gesetzt statt sich auf den Browser-Standard zu verlassen, analog
   zum bereits expliziten vertical-align auf td. */
thead th {
    font-size: 0.85rem;
    vertical-align: middle;
    border-bottom-width: 2px;
}
td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-line-soft);
    vertical-align: middle;
}
/* Letzte Zeile ohne eigene Trennlinie - direkt danach kommt ohnehin die
   abgerundete Tabellenkante. */
tbody:last-child tr:last-child td { border-bottom: none; }
/* Grauer statt blauer Zeilen-Hover: Blau ist im übrigen UI für
   Primäraktionen/Fokus reserviert (siehe --state-hover), auf Tabellenzeilen
   selbst wirkte es dagegen wie ein aktiver/ausgewählter Zustand. Dezentes
   Grau ist der Standard für alle Tabellen im Tool. */
tr:hover td { background: rgba(255,255,255,0.05); }
td.num, th.num { text-align: right; font-family: var(--font-mono); }
/* Dichte-Variante derselben Designsprache (gleiche Farben/Struktur, nur
   engere Zellen) für Positionslisten in Formularen. */
.items-table td, .items-table th { padding: 6px 8px; }

/* Layout-Tabellen ohne Kartenoptik: reine Schlüssel/Wert- oder
   Platzhalter-Listen ohne <thead>. Die Kartenfläche wäre dort nur ein
   dunkler Block ohne Kopf und würde wie eine Datentabelle lesen, die keine
   ist. .pg-mini (Preisguide-Kennzahlen in den Zustandskarten der
   Artikelseite) gehört aus demselben Grund dazu: sie sitzt bereits in einer
   Karte und bringt ihre eigene, kompakte Optik mit. */
table.table-plain,
table.pg-mini {
    background: transparent;
    border-radius: 0;
    overflow: visible;
}
table.table-plain thead tr,
table.pg-mini thead tr { background: transparent; }
.table-plain thead th {
    font-size: 0.78rem;
    border-bottom-width: 1px;
}

.thumb {
    width: 56px;
    height: 56px;
    object-fit: contain;
    background: #ffffff;
    border: 1px solid var(--color-line);
    border-radius: 4px;
    vertical-align: middle;
}
.thumb--sm {
    width: 35px;
    height: 35px;
    object-fit: contain;
    background: #ffffff;
    border: 1px solid var(--color-line);
    border-radius: 3px;
    vertical-align: middle;
}

.sku {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--color-ink-soft);
}

.copy-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    margin-left: 2px;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--color-ink-faint);
    cursor: pointer;
    vertical-align: middle;
    transition: background-color 0.15s, color 0.15s;
}
.copy-icon-btn svg { display: block; }
.copy-icon-btn:hover { background: var(--state-hover); color: var(--color-brick); }
.copy-icon-btn.is-copied,
.copy-icon-btn.is-copied:hover { color: var(--color-ok); background: transparent; }
/* Kleine Symbolknöpfe (Kopieren, Schlagwort entfernen, Vorlagen-Stern)
   sind 15-22px groß - für den Finger zu klein. Auf Touch-Geräten wächst nur
   die unsichtbare Trefferfläche, das Aussehen bleibt. */
@media (pointer: coarse) {
    .copy-icon-btn, .tag-chip-remove, .preset-btn, .preset-delete { position: relative; }
    .copy-icon-btn::after, .tag-chip-remove::after, .preset-btn::after, .preset-delete::after {
        content: '';
        position: absolute;
        inset: -10px;
    }
}

/* --- Badges --- */
.badge {
    display: inline-block;
    padding: 2px 9px;
    border-radius: var(--radius-pill);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.badge-part { background: rgba(57,166,254,0.16); color: #7fc4ff; }
.badge-minifigure { background: rgba(240,98,94,0.16); color: #f0908d; }
.badge-set { background: rgba(63,196,136,0.16); color: var(--color-ok); }
.badge-accessory { background: rgba(224,168,62,0.16); color: var(--color-warn); }
.badge-new { background: rgba(63,196,136,0.16); color: var(--color-ok); }
.badge-used { background: rgba(224,168,62,0.16); color: var(--color-warn); }
/* Zustand-Badge in der Pick-Positionen-Tabelle: an Größe/Optik des
   Bestellungs-Badges derselben Tabelle angeglichen (siehe
   .pick-order-badge.pick-items-order-badge weiter unten) statt der kleineren
   globalen .badge-Größe, die an vielen anderen Stellen (z.B. minifigures.php)
   unverändert bleiben soll. Zwei Klassen aus demselben Grund wie dort:
   unabhängig von der Reihenfolge im Stylesheet zuverlässig vor der globalen
   .badge-Regel. */
.badge.pick-items-condition-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.88rem;
    padding: 3px 10px;
    text-transform: none;
    letter-spacing: normal;
}
/* Status-/Zahlungs-Badge in orders.php/order_detail.php: dieselbe Icon+Text-
   Optik wie das Zustand-Badge oben (.pick-items-condition-badge) - eigene
   Klasse statt Wiederverwendung, da inhaltlich unabhängig (Bestellstatus statt
   Teile-Zustand), aber aus demselben Spezifitätsgrund zwei Klassen kombiniert. */
.badge.order-status-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.88rem;
    padding: 3px 10px;
    text-transform: none;
    letter-spacing: normal;
}
/* Badge ohne Textlabel (renderTaxSchemeBadge($scheme, true), renderStornoBadge()
   in list_helpers.php): schmaleres Padding, und das margin-right des Icons muss
   weg - es steht als inline style in CONDITION_ICON_NEW/-USED, wo es fuer die
   Textvarianten richtig ist, und nur !important kommt dagegen an.
   Die Regel steht bewusst NACH .pick-items-condition-badge und
   .order-status-badge: sie hat dieselbe Spezifitaet (zwei Klassen) und gewinnt
   nur ueber die Reihenfolge. Weiter oben behielten die Badges deren
   padding: 3px 10px und standen dann verschieden hoch nebeneinander. */
.badge.badge-icon-only {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Feste Kantenlaenge statt Padding: nur so wird aus dem Pillen-Radius der
       Basisregel (--radius-pill) ein exakter Kreis. 22px = 13px Icon + 4px Luft
       ringsum; das Ergebnis ist genauso hoch wie die Textbadges daneben. */
    width: 22px;
    height: 22px;
    padding: 0;
    border-radius: 50%;
}
.badge.badge-icon-only svg { margin-right: 0 !important; }
.badge-low { background: rgba(240,98,94,0.16); color: var(--color-danger); }
.badge-ok { background: rgba(63,196,136,0.16); color: var(--color-ok); }

/* --- Statuspunkt neben einer Überschrift (z.B. eBay-Verbindung) ---
   Ersetzt an Stellen mit nur einem Status (verbunden/nicht verbunden) das
   textlastige .badge - die Farbe allein trägt hier schon die Aussage, ein
   Label direkt neben dem Seitentitel wäre doppelt gemoppelt. */
.status-dot {
    display: inline-block;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    flex-shrink: 0;
}
.status-dot-ok { background: var(--color-ok); box-shadow: 0 0 0 3px rgba(63,196,136,0.18); }
.status-dot-low { background: var(--color-danger); box-shadow: 0 0 0 3px rgba(240,98,94,0.18); }
/* Ampel-Icon in der Status-Spalte in orders.php (orderCompletionState()) -
   zeigt allein den Stand des "Bestellung abschließen"-Knopfs. Kreisförmig mit
   Hintergrund wie .badge-circle, damit die Farbe auch als Fläche und nicht
   nur am dünnen Icon-Strich erkennbar ist; vertikal mittig über die
   td-Zeilenhöhe (vertical-align:middle, siehe globale td-Regel oben). */
.order-complete-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    vertical-align: middle;
}
.order-complete-icon svg { width: 18px; height: 18px; }
.order-complete-icon.is-done { background: rgba(63,196,136,0.16); color: var(--color-ok); }
.order-complete-icon.is-ready { background: rgba(224,168,62,0.16); color: var(--color-warn); }
.order-complete-icon.is-error { background: rgba(240,98,94,0.16); color: var(--color-danger); }
.order-complete-icon.is-cancelled { background: rgba(240,98,94,0.16); color: var(--color-danger); }
.order-complete-icon.is-blocked { background: rgba(155,155,160,0.16); color: var(--color-ink-faint); }
/* Für Abgleichs-Gründe, die kein echtes Mengen-/Lagerort-Mismatch sind,
   sondern eine offene To-do-Datenpflege (z.B. fehlender Hinweistext bei
   geteilter BrickOwl-BOID, siehe reconciliationReasonLabel()) - bewusst
   Warn- statt Fehlerfarbe, um sie von echten Abweichungen zu unterscheiden. */
.badge-warn { background: rgba(224,168,62,0.16); color: var(--color-warn); }
/* Nicht zugeordnete Positionen in orders.php: Warn-Icon vor der Zahl. */
.order-unmapped-badge { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; }
.order-unmapped-badge svg { flex: none; }


/* Adresscheck-Status-Icon (renderAddressCheckIcon() in list_helpers.php) -
   reiner Indikator ohne Textlabel/Badge-Pille, damit er sowohl inline in der
   Ort-Spalte von customers.php als auch neben dem "Adresse"-Label in
   customer_detail.php/order_detail.php passt. */
.address-check-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    vertical-align: -5px;
    margin-right: 4px;
}
.address-check-icon-ok { background: rgba(63,196,136,0.16); color: var(--color-ok); }
.address-check-icon-warn { background: rgba(224,168,62,0.16); color: var(--color-warn); }

/* Neu/Gebraucht-Badge in der Artikelübersicht (articles.php, siehe
   renderConditionQtyBadge()): wie .pick-items-condition-badge oben, aber
   zweizeilig (Stückzahl + Lagerort statt eines reinen Zustands-Labels) - das
   Icon dadurch etwas größer und über die Höhe der zwei Textzeilen zentriert
   statt an eine einzelne Textzeile ausgerichtet. */
.qty-location-badge {
    display: inline-flex;
    align-items: center;
    padding: 5px 16px 5px 10px;
    text-transform: none;
    letter-spacing: normal;
}
/* flex: none - als Flex-Element schrumpfte das Icon sonst, sobald der
   Lagerort breiter war als der Rest des Badges (gemessen: 21px, 9px, 0px je
   nach Lagerortlänge - daher "fehlt manchmal, mal kleiner"). Zu knapper Platz
   geht jetzt zulasten des Lagerorts (Ellipse), nie des Icons. */
.qty-location-badge svg {
    width: 21px;
    height: 21px;
    flex: none;
}
.qty-location-badge-text {
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    /* Ohne Lagerort entfällt die zweite Zeile (siehe renderConditionQtyBadge())
       - min-height hält die Badge-Höhe trotzdem gleich zur zweizeiligen
       Variante, die Stückzahl zentriert sich dann allein in diesem Raum. */
    min-height: 34px;
    line-height: 1.25;
}
.qty-location-badge-qty {
    font-size: 0.92rem;
    font-weight: 700;
}
.qty-location-badge-loc {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 0.72rem;
    font-weight: 500;
    opacity: 0.8;
}

/* --- Buttons (M3: volle Pill-Form) ---
   .btn entspricht dem M3 "Outlined Button" (transparent, Rahmen, Label in
   Primärfarbe) - die naheliegende Wahl für sekundäre Aktionen. .btn-primary
   ist der "Filled Button" für die eine hervorgehobene Haupt-Aktion. */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 20px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-line);
    background: transparent;
    color: var(--color-brick);
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    /* Eine Knopfbeschriftung wird nicht umbrochen. Wo der Platz eng wird,
       soll der Knopf schmaler werden oder die Zeile umbrechen - "Pflegelauf
       starten" auf preis_hub.php stand sonst zweizeilig in einem 53px hohen
       Knopf neben lauter einzeiligen. */
    white-space: nowrap;
    transition: background-color 0.15s, border-color 0.15s;
}
.btn:hover { background: var(--state-hover); border-color: var(--color-brick); }
.btn:active { background: var(--state-selected); }
.btn:disabled {
    opacity: 0.38;
    cursor: not-allowed;
    background: transparent;
    border-color: var(--color-line);
    color: var(--color-ink-faint);
}
.btn-primary {
    background: var(--color-brick);
    border-color: var(--color-brick);
    color: #04141f;
    box-shadow: var(--elevation-1);
}
/* color hier explizit wiederholt (nicht nur background/border-color): das
   globale "a:hover { color: #5cb6ff; }" (siehe unten im Stylesheet) hat als
   Element+Pseudoklasse-Selektor eine höhere Spezifität als eine einzelne
   Klasse wie .btn-primary und würde sonst unabhängig von der Reihenfolge den
   dunklen Button-Text auf Hover in genau das Hellblau der Hover-Fläche
   umfärben - Text auf gleichfarbigem Hintergrund, unlesbar. */
.btn-primary:hover { background: #5cb6ff; border-color: #5cb6ff; color: #04141f; }
.btn-primary:active { background: var(--color-brick-dark); border-color: var(--color-brick-dark); }
.btn-primary:disabled {
    opacity: 0.38;
    cursor: not-allowed;
    box-shadow: none;
    background: var(--color-panel-raised);
    border-color: var(--color-panel-raised);
    color: var(--color-ink-faint);
}
.btn-sm { padding: 6px 14px; font-size: 0.78rem; }
.btn-danger-outline { color: var(--color-danger); border-color: #5a2c2e; }
.btn-danger-outline:hover { background: rgba(240,98,94,0.1); border-color: var(--color-danger); }
/* Gefüllter roter Knopf (M3 "error container") für Löschaktionen, die klar
   als solche erkennbar sein sollen - purchases.php benutzte .btn-danger
   bisher, ohne dass die Klasse je definiert war, der Knopf sah aus wie ein
   normaler. */
.btn-danger {
    background: var(--color-danger);
    border-color: var(--color-danger);
    color: #2a0a09;
    box-shadow: var(--elevation-1);
}
.btn-danger:hover { background: #f5827f; border-color: #f5827f; color: #2a0a09; }
.btn-danger:active { background: #d64f4b; border-color: #d64f4b; }
/* Gefüllter dunkelgrauer Knopf für Neben-Aktionen neben einem gefüllten
   Haupt-Knopf (Abbrechen, Hilfsaktionen) - der Outlined-.btn wirkt daneben
   verloren. Genutzt im Dialog (app-dialog.js) und im Storno-Modus. */
.btn-neutral,
.btn-neutral:hover,
.btn-neutral:focus { color: #fff; }
.btn-neutral {
    background: #4a4f57;
    border-color: #4a4f57;
    box-shadow: var(--elevation-1);
}
.btn-neutral:hover { background: #5a606a; border-color: #5a606a; }
.btn-neutral:active { background: #656c77; border-color: #656c77; }
.btn-icon { padding: 5px 8px; min-width: 30px; text-align: center; border-radius: var(--radius-pill); }
/* Icon-Button als echter Kreis (z.B. "Angebot erstellen" in Tabellenzeilen) -
   feste Breite/Höhe statt der inhaltsabhängigen .btn-icon-Pille, die bei
   einem einzelnen Icon oval statt rund wirkt. */
.btn-circle {
    width: 34px;
    height: 34px;
    padding: 0;
    border-radius: 50%;
    justify-content: center;
    flex-shrink: 0;
}
.btn-muted { color: var(--color-ink-soft); }
.btn-muted:hover { background: var(--state-hover); border-color: var(--color-ink-soft); }

/* --- API-Status-Icon (Buchhaltung-Übersicht, oben rechts neben der H1) ---
   M3 "Filled tonal Icon Button": runder, tonal eingefärbter Grund-Kreis mit
   farbcodiertem Cloud-Icon je Verbindungszustand, bei Hover kräftigerer Ton.
   Klick löst eine erneute Prüfung aus (?refresh_status=1) bzw. führt bei
   "nicht eingerichtet" in die Einstellungen. */
.bb-status-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    text-decoration: none;
    flex-shrink: 0;
    transition: background-color 0.15s, color 0.15s, transform 0.1s;
}
.bb-status-btn svg { display: block; overflow: visible; }
.bb-status-btn.is-ok    { color: var(--color-ok);     background: rgba(63,196,136,0.16); }
.bb-status-btn.is-error { color: var(--color-danger); background: rgba(240,98,94,0.16); }
.bb-status-btn.is-off   { color: var(--color-warn);   background: rgba(224,168,62,0.16); }
.bb-status-btn.is-ok:hover    { background: rgba(63,196,136,0.28); }
.bb-status-btn.is-error:hover { background: rgba(240,98,94,0.26); }
.bb-status-btn.is-off:hover   { background: rgba(224,168,62,0.28); }
.bb-status-btn:active { transform: scale(0.94); }

/* --- Bestellung-Detailansicht: Aktionsleiste (M3 Icon-Button-Gruppe) ---
   Tonale Pill-Fläche mit rahmenlosen Icon-Buttons statt einzelner Outlined
   Buttons - kompakter und "übersichtlicher" für 2-4 gleichrangige Aktionen. */
.order-action-bar {
    display: flex;
    align-items: center;
    gap: 2px;
    background: var(--color-panel-raised);
    border-radius: var(--radius-pill);
    padding: 4px;
    flex-shrink: 0;
}
.order-action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-ink-soft);
    cursor: pointer;
    /* Die Leiste trägt inzwischen auch <a>-Elemente (eBay-Übersicht:
       Templates, Import, Verbindung trennen) - ohne das käme der
       Browser-Unterstrich mitten in die Icon-Pille. */
    text-decoration: none;
    transition: background-color 0.15s, color 0.15s;
}
.order-action-btn svg { display: block; }
.order-action-btn:hover { background: var(--state-hover); color: var(--color-brick); }
.order-action-btn:active { background: var(--state-selected); }
.order-action-btn:disabled { opacity: 0.35; cursor: not-allowed; background: transparent; color: var(--color-ink-faint); }
.order-action-btn.is-success:hover { background: rgba(63,196,136,0.14); color: var(--color-ok); }
.order-action-btn.is-success.has-label { background: var(--color-panel); }
.order-action-btn.is-danger:hover { background: rgba(240,98,94,0.12); color: var(--color-danger); }
/* Sobald "Bestellung abschließen" nutzbar ist, bekommt der Button zusätzlich
   ein Textlabel und weicht dafür vom runden Icon-Button zur Pille auf -
   gesperrt (disabled) bleibt er weiterhin ein reiner Icon-Button. */
.order-action-btn.has-label {
    width: auto;
    padding: 0 16px 0 12px;
    gap: 8px;
    font-size: 0.85rem;
    font-weight: 600;
}
/* Einzelversand-Button in der Versandtabelle: gleiche Fläche wie das
   Versandprodukt-Dropdown und das Gewichtsfeld daneben, statt unsichtbar
   transparent in der Zeile zu stehen. */
.order-action-btn.has-bg { background: var(--color-panel-raised); }
.order-action-btn.has-bg:hover { background: var(--state-hover); color: var(--color-brick); }
/* Jeder Button steckt in einem eigenen <form> (eigener POST-Submit) - das
   Formular selbst soll dabei keine eigene Box im Flex-Layout bilden. */
.order-action-bar form { display: contents; }

/* --- Forms --- */
label {
    display: block;
    font-size: 0.82rem;
    font-weight: 600;
    margin-bottom: 6px;
    color: var(--color-ink-soft);
}
input, select, textarea {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    font-family: var(--font-body);
    background: var(--color-panel-raised);
    color: var(--color-ink);
}
input::placeholder, textarea::placeholder { color: var(--color-ink-faint); }
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--color-brick);
    box-shadow: 0 0 0 3px var(--state-focus);
}
/* Klick-Elemente: kein Ring nach Mausklick (blieb stehen, bis woanders
   hingeklickt wurde), nur bei Tastatur-Fokus. */
input[type="checkbox"]:focus, input[type="radio"]:focus, input[type="file"]:focus { box-shadow: none; }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible, input[type="file"]:focus-visible { box-shadow: 0 0 0 3px var(--state-focus); }
.field { margin-bottom: 16px; position: relative; }
.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 16px;
}

/* Klickbarer Kundenname (customer_detail.php): dezenter Hover-State-Layer,
   damit erkennbar ist, dass ein Klick das Inline-Editierfeld öffnet. */
.name-editable {
    display: inline-block;
    padding: 2px 6px;
    margin: -2px -6px;
    border-radius: var(--radius-sm);
    transition: background 0.15s;
}
.name-editable:hover {
    background: var(--state-hover);
}

/* Link, der nicht als Link aussehen soll, sondern als kräftig gesetzter
   Zelleninhalt - die Nummernspalte der Ankaufsliste ist komplett verlinkt,
   eine Unterstreichung in jeder Zeile wäre dort nur Unruhe. */
a.link-plain {
    color: var(--color-ink);
    text-decoration: none;
    font-weight: 600;
}
a.link-plain:hover { color: var(--color-brick); }

/* M3 "filled text field" (https://m3.material.io/components/text-fields) für
   das Adress-Bearbeiten-Formular in customer_detail.php: Eingabefläche auf
   Tonfarbe statt umrandetem Kasten, nur unten eine Indikatorlinie statt
   eines vollen Rahmens, die sich bei Fokus färbt/verdickt. */
.md3-field label {
    font-size: 0.72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.md3-field input {
    background: var(--color-panel-raised);
    border: none;
    border-radius: var(--radius-pill);
    padding: 9px 16px;
    transition: background 0.15s;
}
.md3-field input:hover {
    background: var(--color-surface-container-high);
}
.md3-field input:focus {
    background: var(--color-surface-container-high);
    box-shadow: none;
}
/* Eingabefeld mit Aktion am Ende als ein Bauteil (Beleg-Mail in
   purchases.php): die Pille trägt die Tonfläche, das Feld darin ist
   durchsichtig, der Knopf sitzt rechts innen - statt Feld und Knopf als
   zwei lose Teile mit unterschiedlicher Höhe nebeneinander. */
.md3-input-action {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px;
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    transition: background 0.15s;
}
.md3-input-action:hover,
.md3-input-action:focus-within {
    background: var(--color-surface-container-high);
}
.md3-field .md3-input-action input,
.md3-field .md3-input-action input:hover,
.md3-field .md3-input-action input:focus {
    flex: 1;
    min-width: 0;
    padding: 6px 13px;
    background: transparent;
}
/* Drei Klassen tief, weil ".toolbar .btn" mobil auf flex: 1 1 auto stellt -
   der Knopf fraß sonst das halbe Feld. */
.md3-field .md3-input-action .btn { flex: 0 0 auto; box-shadow: none; }
/* Zahlen-Pfeilchen raus - stören bei Preis-/Prozentfeldern nur (Minifiguren-
   Kandidaten: Preisformel + Preisfilter). */
.md3-field input[type="number"] {
    appearance: textfield;
    -moz-appearance: textfield;
}
.md3-field input[type="number"]::-webkit-outer-spin-button,
.md3-field input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Auswahl- und Mehrzeilenfelder im selben M3-Stil. Das Ankaufsformular
   (purchases.php) mischt Text-, Auswahl- und Textfelder in einer Maske -
   mit nur teilweise gefüllten Feldern sah die Maske uneinheitlich aus.
   Das Textfeld bekommt den Karten- statt des Pillenradius, eine mehrzeilige
   Fläche mit 100px-Ecken sieht sonst wie ein verrutschter Knopf aus. */
.md3-field select,
.md3-field textarea {
    background: var(--color-panel-raised);
    border: none;
    transition: background 0.15s;
}
.md3-field select {
    border-radius: var(--radius-pill);
    padding: 9px 16px;
}
.md3-field textarea {
    border-radius: var(--radius);
    padding: 12px 16px;
}
.md3-field select:hover,
.md3-field textarea:hover {
    background: var(--color-surface-container-high);
}
.md3-field select:focus,
.md3-field textarea:focus {
    background: var(--color-surface-container-high);
    box-shadow: none;
}
/* Auswahlfeld, das per initMd3Dropdown() zum eigenen Pillen-Trigger geworden
   ist (Kategorie der Anlagen, Zahlungsart): der Trigger bringt seine eigene,
   dunklere Grundfarbe mit und sähe neben den Eingabefeldern daneben aus wie
   ein Fremdkörper. Gleiche Füllung, gleiche Höhe wie ein .md3-field input. */
.md3-field .md3-dropdown-trigger {
    background: var(--color-panel-raised);
    font-size: inherit;
}
.md3-field .md3-dropdown-trigger:hover,
.md3-field .md3-dropdown.is-open .md3-dropdown-trigger {
    background: var(--color-surface-container-high);
}
/* --- Filterleiste über einer Liste ---
   Bis hierher gab es zu .filter-bar nur Regeln für die *Kinder* (select, btn,
   md3-dropdown) - die Leiste selbst hatte keine. Ihre Flex-Zeile stand auf
   jeder Seite einzeln als inline-style am Element, achtmal dasselbe
   abgeschrieben. purchases.php hatte sie schlicht vergessen: dort stand jedes
   Feld einzeln untereinander über die volle Panelbreite (1081px für ein
   Betragsfeld). Bewusst ohne margin-bottom - die Seiten setzen den Abstand
   nach unten unterschiedlich, das bleibt bei ihnen. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
}
/* Filterleiste ohne Panel dahinter (articles.php): die Elemente tragen ihre
   eigene Tonflaeche, ein Block darunter waere eine zweite Ebene ohne
   Aussage. Der Abstand nach unten kam bisher vom Panel. */
.filter-bar--bare { margin-bottom: 20px; }

/* Preisfilter (Minifiguren-Kandidaten) auf dieselbe 44px-Zeilenhöhe wie
   Suchfeld/Select/Button daneben (siehe .filter-bar select / .filter-bar .btn
   oben) - .md3-field input hat sonst nur sein eigenes, kleineres Padding. */
.filter-bar .md3-field input {
    height: 44px;
}

/* --- Suchfeld (M3 Search bar - https://m3.material.io/components/search/overview):
   volle Pill-Form, randlos, auf einer eigenen Tonfläche (surface-container-high)
   statt der Umrandung normaler Textfelder, mit führendem Such-Icon. --- */
.search-field {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
}
.search-field .search-icon {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    color: var(--color-ink-soft);
    pointer-events: none;
}
.search-field input {
    width: 100%;
    height: 44px;
    padding: 0 14px 0 40px;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
    color: var(--color-ink);
    font-size: 0.92rem;
}
.search-field input::placeholder { color: var(--color-ink-faint); }
.search-field input:focus {
    outline: none;
    box-shadow: 0 0 0 3px var(--state-focus);
}

/* --- Filterleiste Artikelübersicht (articles.php): Auswahlfelder auf
   dieselbe randlose MD3-Tonfläche wie das Suchfeld daneben (.search-field
   oben) heben, statt der generischen eckigen input/select-Rahmenoptik. */
.filter-bar select {
    appearance: none;
    height: 44px;
    padding: 0 32px 0 14px;
    border: none;
    border-radius: var(--radius-pill);
    background-color: var(--color-surface-container-high);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='%238a8a8e'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    color: var(--color-ink);
    font-size: 0.92rem;
}
/* Bis md3-dropdown.js das Feld ersetzt hat, steht für einen Moment das
   native Feld da. Es bekommt deshalb schon die Maße der fertigen Pille
   (.md3-dropdown-trigger: 190px Mindestbreite, 16px links, Pfeil bei 12px),
   sonst springt beim Umbau die Breite und die Filterzeile bricht neu um.
   width:auto gegen das globale select{width:100%}: direkt in der Leiste
   (ohne .field-Hülle) nahm sonst jedes Feld kurz eine eigene Zeile ein. */
.filter-bar > select:not([multiple]) { width: auto; }
.filter-bar select:not([multiple]) {
    min-width: 190px;
    padding: 0 38px 0 16px;
    font-family: inherit;
}
.notif-filter select { font-size: 0.88rem; font-weight: 500; }
.filter-bar select:focus {
    outline: none;
    box-shadow: 0 0 0 3px var(--state-focus);
}
/* Mehrfachauswahl (Farbe) bleibt eine native Listbox statt einer Pille - nur
   Rahmen und Tonfläche an dieselbe Optik angeglichen, der Pfeil-Hintergrund
   von oben ergibt bei einer mehrzeiligen Liste keinen Sinn. */
.filter-bar select[multiple] {
    appearance: auto;
    padding: 6px 10px;
    border: none;
    border-radius: var(--radius-sm);
    background-color: var(--color-surface-container-high);
    background-image: none;
}
/* Bestätigen-Button hat kein eigenes Label über sich - feste Höhe statt der
   Button-eigenen Padding-Höhe, damit er trotz align-items:flex-end im
   Formular exakt auf der gleichen Grundlinie wie die 44px hohen Auswahl-
   felder sitzt. */
.filter-bar .btn {
    height: 44px;
}
/* MD3-Dropdown-Trigger in einer Filterzeile (Kundenübersicht) auf dieselbe
   44px-Höhe wie Suchfeld/Select/Button daneben bringen - ohne diese Regel
   richtet sich die Höhe nur nach dem eigenen Innenabstand (~35px). */
.filter-bar .md3-dropdown-trigger {
    height: 44px;
}
/* Filterchip (M3 "filter chip") in einer Filterleiste: die Pille trägt sonst
   nur ihren eigenen Innenabstand (~35px) und säße damit tiefer als die 44px
   hohen Felder daneben. Verwendet auf preis_hub_update.php ("nur mit
   Hub-Preis"). */
.filter-bar .pill-label {
    height: 44px;
}

/* Klappknopf der Filterleiste (siehe .filter-collapsible in
   includes/layout_footer.php). Auf dem Desktop passt die Leiste in eine
   Zeile, dort wird der Knopf gar nicht erst gebraucht. */
.filter-toggle { display: none; }

/* --- Tag/Block-Eingabe (mehrere kommagetrennte Werte pro Textfeld) --- */
.tag-input-wrap {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    background: var(--color-panel-raised);
    cursor: text;
}
.tag-input-wrap:focus-within {
    border-color: var(--color-brick);
    box-shadow: 0 0 0 3px var(--state-focus);
}
.tag-input-chips {
    display: contents;
}
.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 6px 3px 10px;
    border-radius: var(--radius-pill);
    background: rgba(57,166,254,0.16);
    color: var(--color-ink);
    font-size: 0.82rem;
    line-height: 1.4;
    white-space: nowrap;
}
.tag-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-soft);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}
.tag-chip-remove:hover { background: rgba(240,98,94,0.2); color: var(--color-danger); }
.tag-input-typer {
    flex: 1 1 80px;
    width: auto;
    min-width: 80px;
    border: none;
    outline: none;
    padding: 3px 2px;
    background: transparent;
    font-size: 0.9rem;
    color: var(--color-ink);
}
.tag-input-typer:focus {
    outline: none;
    box-shadow: none;
    border-color: transparent;
}

/* Kategorie-Filter (Minifiguren-Kandidaten): dieselbe Chip-Mechanik wie das
   Tag-Feld im eBay-Bearbeiten-Formular oben, aber randlos auf MD3-Tonfläche
   wie Suchfeld/Select/Preisfelder daneben statt der dort üblichen Rahmenbox. */
.filter-bar .tag-input-wrap {
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
    min-height: 44px;
    padding: 5px 14px;
}
.filter-bar .tag-input-wrap:focus-within {
    box-shadow: 0 0 0 3px var(--state-focus);
}

/* --- Pill-Auswahl (z.B. Material: Mehrfachauswahl per Klick statt Strg/Cmd+Klick) --- */
.pill-select {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.pill-option {
    display: inline-flex;
    align-items: center;
    margin: 0;
    cursor: pointer;
}
.pill-checkbox {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.pill-label {
    display: inline-flex;
    align-items: center;
    padding: 7px 14px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-line);
    background: var(--color-panel-raised);
    color: var(--color-ink-soft);
    font-size: 0.85rem;
    font-weight: 600;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}
.pill-option:hover .pill-label {
    border-color: var(--color-brick);
}
.pill-checkbox:checked + .pill-label {
    background: var(--color-brick);
    border-color: var(--color-brick);
    color: #04141f;
}
.pill-checkbox:focus-visible + .pill-label {
    box-shadow: 0 0 0 3px var(--state-focus);
}

/* --- Gespeicherte Werte (Preset-Liste je Artikelmerkmal-Feld) --- */
.preset-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 4px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--color-ink-soft);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    vertical-align: middle;
}
.preset-btn:hover { color: var(--color-brick); }
.preset-panel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 20;
    margin-top: 4px;
    width: 100%;
    max-height: 260px;
    overflow-y: auto;
    background: var(--color-surface-container-high);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    padding: 8px;
    box-shadow: var(--elevation-3);
    box-sizing: border-box;
}
.preset-item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 6px 3px 10px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-line);
    background: transparent;
    color: var(--color-ink);
    font-size: 0.82rem;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
}
.preset-item:hover { background: rgba(57,166,254,0.08); border-color: var(--color-brick); }
.preset-item.selected {
    background: rgba(57,166,254,0.16);
    border-color: transparent;
    font-weight: 600;
}
.preset-delete {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-soft);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}
.preset-delete:hover { background: rgba(240,98,94,0.2); color: var(--color-danger); }
.preset-add-row {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 4px 3px 10px;
    border-radius: var(--radius-pill);
    border: 1px dashed var(--color-line);
    background: transparent;
    margin: 0;
}
.preset-add-input {
    width: 90px;
    flex: 0 0 auto;
    border: none;
    outline: none;
    background: transparent;
    font-size: 0.82rem;
    padding: 2px 0;
    color: var(--color-ink);
}
.preset-add-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    margin: 0 4px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(57,166,254,0.16);
    color: var(--color-ink);
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
}
.preset-add-btn:hover { background: var(--color-brick); color: #04141f; }

/* --- Alerts --- */
.alert {
    padding: 12px 16px;
    border-radius: var(--radius);
    margin-bottom: 20px;
    font-size: 0.88rem;
    border: 1px solid transparent;
}
.alert-success { background: rgba(63,196,136,0.12); color: var(--color-ok); border-color: rgba(63,196,136,0.3); }
.alert-error { background: rgba(240,98,94,0.12); color: var(--color-danger); border-color: rgba(240,98,94,0.3); }
.alert-info { background: rgba(57,166,254,0.12); color: var(--color-brick); border-color: rgba(57,166,254,0.3); }

/* ============================================================
   Toasts: Rückmeldungen auf Aktionen, unten rechts gestapelt
   (assets/js/app-toast.js, PHP-Seite: flash() in app_includes/flash.php).
   Farbstrich rechts, abgerundet nur links. Die Restzeit steckt in der
   Animation von .app-toast-progress - :hover/:focus-within hält sie an,
   ihr Ende blendet den Toast aus.
   .alert bleibt für Zustandshinweise im Seiteninhalt.
   ============================================================ */
.app-toast-region {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 9000;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    width: min(400px, calc(100vw - 32px));
    pointer-events: none;
}
.app-toast {
    --toast-accent: var(--color-brick);
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    margin-top: 10px;
    padding: 14px 14px 14px 16px;
    overflow: hidden;
    background: var(--color-panel-raised);
    color: var(--color-ink);
    border: 1px solid var(--color-line);
    border-right: 0;
    border-radius: var(--radius) 0 0 var(--radius);
    box-shadow: inset -4px 0 0 var(--toast-accent), 0 10px 28px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.3);
    pointer-events: auto;
    animation: app-toast-in 260ms cubic-bezier(0.2, 0.9, 0.3, 1.15);
}
/* Schon eingefahren: beim Umhängen in einen Dialog (app-toast.js) nicht noch einmal. */
.app-toast.is-shown { animation: none; }
.app-toast--success { --toast-accent: var(--color-ok); }
.app-toast--error   { --toast-accent: var(--color-danger); }
.app-toast--warn    { --toast-accent: var(--color-warn); }
.app-toast--info    { --toast-accent: var(--color-brick); }
.app-toast-icon { flex-shrink: 0; display: flex; color: var(--toast-accent); }
.app-toast-body { flex: 1; min-width: 0; }
.app-toast-msg {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
    white-space: pre-line;
}
.app-toast-details {
    margin: 6px 0 0;
    padding-left: 18px;
    max-height: 160px;
    overflow-y: auto;
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--color-ink-soft);
    overflow-wrap: anywhere;
}
.app-toast-body form { margin: 0; }
.app-toast-action {
    display: inline-block;
    margin-top: 8px;
    padding: 5px 12px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-stud);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
}
.app-toast-action:hover { background: var(--state-hover); border-color: var(--color-brick); }
.app-toast-close {
    flex-shrink: 0;
    align-self: center;
    display: flex;
    padding: 6px;
    margin-right: 4px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-soft);
    cursor: pointer;
}
.app-toast-close:hover { background: var(--color-surface-container-high); color: var(--color-ink); }
.app-toast-close:focus-visible, .app-toast-action:focus-visible { outline: 2px solid var(--color-brick); outline-offset: 1px; }
.app-toast-progress {
    position: absolute;
    left: 0;
    right: 4px;
    bottom: 0;
    height: 3px;
    background: var(--toast-accent);
    opacity: 0.75;
    transform-origin: left center;
    animation: app-toast-countdown 10s linear forwards;
}
.app-toast:hover .app-toast-progress,
.app-toast:focus-within .app-toast-progress,
.app-toast-region.is-paused .app-toast-progress { animation-play-state: paused; }
.app-toast .visually-hidden {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@keyframes app-toast-in {
    from { opacity: 0; transform: translateX(calc(100% + 24px)); }
    to   { opacity: 1; transform: translateX(0); }
}
@keyframes app-toast-countdown {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
}
@media (max-width: 600px) {
    .app-toast-region { right: 12px; left: 12px; bottom: 12px; width: auto; }
}
@media (prefers-reduced-motion: reduce) {
    .app-toast { animation: none; }
}

/* Käufernachricht als eigenes Panel über "Bestellte Artikel" (order_detail.php) */
.buyer-message-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.buyer-message-icon { color: var(--color-brick); display: inline-flex; }
.buyer-message-reply { margin-left: auto; text-decoration: none; }
.buyer-message-item { margin-top: 14px; padding: 12px 14px; background: rgba(57,166,254,0.07); border-radius: var(--radius-sm); }
.buyer-message-meta { font-size: 0.75rem; color: var(--color-ink-soft); margin-bottom: 4px; }
.buyer-message-body { font-size: 0.88rem; color: var(--color-ink); line-height: 1.5; overflow-wrap: anywhere; }
@media (max-width: 600px) { .buyer-message-reply { margin-left: 0; width: 100%; text-align: center; } }

/* --- Login page --- */
.login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: var(--color-bg);
    background-image: radial-gradient(circle at 50% 0%, rgba(57,166,254,0.1), transparent 60%);
}
.login-box {
    background: var(--color-panel);
    border: 1px solid var(--color-outline-variant);
    padding: 40px;
    border-radius: var(--radius-lg);
    box-shadow: var(--elevation-2);
    width: 360px;
    max-width: calc(100vw - 32px);
}
.login-box .brand {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 28px;
}
.login-box .brand img {
    height: 32px;
    width: auto;
}

/* --- Utility --- */
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.text-soft { color: var(--color-ink-soft); }
/* Trennpunkt zwischen Metainfos: im ganzen Tool ein 4px-Kreis per CSS statt
   eines Schriftzeichens - so hängt seine Größe nicht an Schrift oder
   Schriftgröße. Das "•" im Markup bleibt für Kopieren und Vorlesen, wird aber
   per text-indent aus dem Kreis geschoben und abgeschnitten - nicht per
   font-size: 0, damit "em" hier die Schriftgröße der Zeile meint.
   Höhe: overflow: hidden macht die Unterkante zur Grundlinie des Kreises, er
   wird also um 0.36em (halbe Ziffernhöhe in Roboto) minus Radius angehoben und sitzt so
   mittig zu Ziffern und Großbuchstaben; vertical-align: middle (halbe
   x-Höhe) lag 1-2px zu tief. In Flex-Zeilen greift statt dessen align-self.
   Pixelraster: Der Browser rundet die Grundlinie der Schrift und die Kanten
   des Kreises getrennt auf Gerätepixel. Ist der Abstand dazwischen kein
   ganzes Vielfaches eines Gerätepixels, rundet der Kreis je nach Zeilenlage
   anders als die Schrift und sitzt bis zu einem Gerätepixel zu hoch (bei 150 %
   Windows-Skalierung im Benachrichtigungs-Panel gemessen). Darum wird die
   Anhebung per round() auf ganze Gerätepixel (--dot-step = 1px / Pixeldichte)
   gerundet; die 4px Höhe sind bei den üblichen Dichten schon ganzzahlig.
   Reine Textstellen (Tooltips, Auswahllisten, Meldungen) zeigen das Zeichen
   "•"; die Rechnung behält "·", der Mail-Footer hat einen eigenen 3px-Kreis. */
.dot-sep { --dot-step: 1px; display: inline-block; width: 4px; height: 4px; margin: 0 2px; border-radius: 50%; background: currentColor; overflow: hidden; text-indent: 100px; white-space: nowrap; line-height: 4px; vertical-align: calc(0.36em - 2px); vertical-align: round(calc(0.36em - 2px), var(--dot-step)); align-self: center; flex: none; }
@media (min-resolution: 1.2dppx) and (max-resolution: 1.3dppx) { .dot-sep { --dot-step: 0.8px; } }
@media (min-resolution: 1.45dppx) and (max-resolution: 1.55dppx) { .dot-sep { --dot-step: calc(2px / 3); } }
@media (min-resolution: 1.7dppx) and (max-resolution: 1.8dppx) { .dot-sep { --dot-step: calc(4px / 7); } }
@media (min-resolution: 1.95dppx) and (max-resolution: 2.05dppx) { .dot-sep { --dot-step: 0.5px; } }
@media (min-resolution: 2.95dppx) and (max-resolution: 3.05dppx) { .dot-sep { --dot-step: calc(1px / 3); } }
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.toolbar { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
.empty-state {
    text-align: center;
    padding: 48px 20px;
    color: var(--color-ink-soft);
}

/* --- Sortable column headers --- */
th.sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
th.sortable a {
    color: inherit;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
th.sortable a:hover,
th.sortable:hover {
    color: var(--color-brick);
}
/* Sortier-Pfeile für JS-gesteuerte Tabellen (Klick auf <th>, kein Link) -
   gleiche Zeichen/Optik wie bei serverseitig sortierten Übersichten (Artikel). */
th.sort-asc::after {
    content: ' ▲';
}
th.sort-desc::after {
    content: ' ▼';
}

/* --- Bestellpositionen: Bundle-Gruppierung (Bestellung-Detailansicht) --- */
tr.bundle-group-header td {
    background: var(--color-panel-raised);
    color: var(--color-ink-soft);
    font-size: 0.78rem;
    font-weight: 600;
    padding: 6px 12px;
}
/* Ende eines Bundles: dickere Trennlinie in der Farbe der Kopfzeile - macht
   den Zeilenblock eines Bundles erkennbar. */
tr.bundle-item.bundle-end td {
    border-bottom: 6px solid var(--color-panel-raised);
}

/* --- Pagination --- */
.pagination {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 20px;
    flex-wrap: wrap;
    gap: 12px;
}
.pagination-info {
    font-size: 0.82rem;
    color: var(--color-ink-soft);
}
/* Verbundenes MD3-Pill-Segment (Vorbild: .history-filter/.order-action-bar)
   statt einzelner .btn.btn-sm-Links mit eigenem Rahmen pro Seitenzahl. */
.pagination-links {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    background: var(--color-panel-raised);
    border-radius: var(--radius-pill);
    padding: 4px;
    flex-wrap: wrap;
}
.pagination-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding: 0 12px;
    border-radius: var(--radius-pill);
    color: var(--color-ink-soft);
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
    transition: background-color 0.15s, color 0.15s;
}
.pagination-btn:hover { background: var(--state-hover); color: var(--color-ink); }
/* "Weiter"-Button ist reines Icon (kein Text mehr, siehe renderPagination())
   - schmalere Pillenbreite statt der text-bemessenen 12px-Seiten-Polsterung,
   damit er nicht unnötig breiter als die runden Seitenzahlen-Buttons wirkt. */
.pagination-btn-next { padding: 0 8px; }
.pagination-btn.is-active {
    background: var(--state-selected);
    color: var(--color-brick);
}
.pagination-ellipsis {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    color: var(--color-ink-soft);
    font-size: 0.82rem;
}

/* --- Artikel-Detailansicht (View-Modus) --- */
/* Bildspalte in der Artikelfarbe bis an den Panelrand, daneben zwei
   Info-Spalten (Nummern | Stammdaten) mit Trennstrich. Der Bildkasten
   bleibt immer weiß, weil die Bilder unterschiedliche Formate mit weißem
   Hintergrund haben. */
.panel.article-view-panel {
    padding: 0;
    overflow: hidden;
    background: var(--color-panel);
}
.article-view-layout {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
}
.article-view-media {
    background: var(--article-color, var(--color-panel-raised));
    padding: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* .detail-list.article-view-col statt nur .article-view-col: das spätere
   .detail-list { margin: 0 } würde den Abstand sonst überschreiben */
.detail-list.article-view-col {
    margin: 28px 0 20px;
    padding: 0 24px;
}
.article-view-col + .article-view-col {
    border-left: 1px solid var(--color-line);
}
.article-view-col .detail-row { grid-template-columns: 130px minmax(0, 1fr); }
/* Link-Icon hinter BL-/BO-ID. Abstand > 10px, weil .field-display per
   negativem Rand 10px über seine Box hinaus hovert. */
.article-view-col dd:has(> .detail-ext-link) {
    display: flex;
    align-items: center;
}
.detail-ext-link {
    display: inline-flex;
    margin-left: 14px;
    color: var(--color-ink-faint);
    transition: color 0.15s;
}
.detail-ext-link:hover { color: var(--color-brick); }
/* Elementnummern als Link zur BrickLink-Suche: sehen aus wie Text, damit
   eine Liste aus mehreren Nummern ruhig bleibt; Hover zeigt den Link. */
.element-link { color: inherit; text-decoration: none; }
.element-link:hover { color: var(--color-brick); }
/* Pick-a-Brick-Preis mit Statuspunkt davor (Artikelseite und
   preis_hub_pab.php): grün = Neuzugang, rot = End of Life (letzte Chance). */
.pab-price { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.pab-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.pab-dot.is-available   { background: var(--color-ok);     box-shadow: 0 0 0 3px rgba(63,196,136,0.18); }
.pab-dot.is-unavailable { background: var(--color-danger); box-shadow: 0 0 0 3px rgba(240,98,94,0.18); }
.pab-dot.is-unknown     { background: var(--color-ink-faint); }
.article-view-image {
    position: relative;
    width: 280px;
    height: 280px;
    background: #ffffff;
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.article-view-image img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}
.article-view-media.is-light .article-view-image {
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.14);
}
.article-view-image-placeholder {
    color: #6c6c70;
    font-size: 0.85rem;
}
/* Bild-Upload: statt eines eigenen Buttons unter dem Bild jetzt ein
   MD3-Scrim am unteren Bildrand, über die gesamte Bildbreite, nur beim
   Hover/Fokus sichtbar - die weiße Bildfläche bleibt so für Produktfotos
   frei, der Upload-Einstieg sitzt direkt am Bild statt daneben. */
.article-image-upload-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 12px;
    background: rgba(19,19,19,0.72);
    color: #fff;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    opacity: 0;
    transform: translateY(100%);
    transition: opacity 0.15s, transform 0.15s;
}
.article-view-image:hover .article-image-upload-overlay,
.article-view-image:focus-within .article-image-upload-overlay {
    opacity: 1;
    transform: translateY(0);
}
.article-image-upload-overlay input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.detail-list {
    margin: 0;
}
.detail-row {
    display: grid;
    grid-template-columns: 160px 1fr;
    padding: 10px 0;
    border-bottom: 1px solid var(--color-line-soft);
    gap: 16px;
}
.detail-row:last-child { border-bottom: none; }
/* Der Farb-Chip ist durch sein Polster höher als eine Textzeile - mittig
   ausrichten, sonst sitzt der Farbname tiefer als das Label */
.detail-row:has(.color-chip) { align-items: center; }
.detail-row dt {
    color: var(--color-ink-soft);
    font-size: 0.82rem;
    font-weight: 600;
}
.detail-row dd {
    margin: 0;
    color: var(--color-ink);
    /* Gleiche Schriftgröße wie dt (Label-Spalte) - vormals erbte dd die
       größere body-Schriftgröße (15px) und stach damit gegenüber der
       schmaleren Label-Spalte hervor. */
    font-size: 0.82rem;
}

/* --- Farb-Chip (Stammdaten "Farbe", article_edit.php): kreisförmiger Punkt
   in der tatsächlichen Artikelfarbe (Hex aus color_catalog, siehe
   renderColorChip() in article_field_editor.php) + Farbname, auf einer zur
   Farbe passenden Tonfläche - gleiches rgba(...,0.16)-Muster wie
   .badge-new/.badge-used statt vollflächigem Hintergrund. */
.color-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 3px 10px 3px 6px;
    border-radius: var(--radius-pill);
    /* font-size: inherit statt eines eigenen 0.88rem - alle übrigen Werte im
       Stammdaten-Block (Kategorie, Gewicht, ...) erben schlicht die
       body-Schriftgröße über die .field-display-Zelle, der Farb-Chip stach
       daneben als spürbar kleiner heraus. */
    font-size: inherit;
    /* Für den Hover-Effekt weiter unten (.field-editable[data-field="color"]
       .field-display:hover .color-chip) - eigene Tonfläche wird dort per
       filter aufgehellt statt eines zusätzlichen Hintergrund-Layers. */
    transition: filter 0.15s;
}
.color-chip-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    /* MD3-Optik: flache Fläche mit dezenter Outline statt Skeuomorphismus.
       Der frühere Inset-Schatten sollte den Punkt bei Schwarz vom dunklen
       Chip-Hintergrund abheben - das übernimmt inzwischen renderColorChip()
       selbst (helle neutrale Tonfläche ab Luminanz < 40 statt der
       farbeigenen rgba(...,0.16)-Tönung), der Schatten war dadurch nur noch
       doppelt gemoppelt. */
    border: 1px solid rgba(255,255,255,0.3);
    flex-shrink: 0;
}
/* Der generische Pillen-Hover von .field-display (siehe oben) würde hier als
   zweite, leicht versetzte Pille um die bereits eigene .color-chip-Tonfläche
   erscheinen ("sieht falsch aus"). Für dieses Feld daher deaktiviert und
   stattdessen die vorhandene Chip-Fläche selbst leicht aufgehellt. */
.field-editable[data-field="color"] .field-display {
    padding: 0;
    margin: 0;
    border-radius: var(--radius-pill);
}
.field-editable[data-field="color"] .field-display:hover {
    background: none;
}
.field-editable[data-field="color"] .field-display:hover .color-chip {
    filter: brightness(1.3);
}

/* --- Mengen-Stepper (Bestand-Buchen, article_edit.php): Minus/Eingabe/Plus
   als ein zusammenhängendes MD3-Pill-Element (Vorbild: .order-action-bar)
   statt dreier optisch getrennter Bausteine. */
.qty-stepper {
    display: inline-flex;
    align-items: center;
    background: #18181a;
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.qty-stepper .btn {
    border: none;
    border-radius: 0;
    background: transparent;
    padding: 9px 14px;
    font-size: 1rem;
    line-height: 1;
}
.qty-stepper .btn:hover { background: var(--state-hover); }
.qty-stepper .btn:active { background: var(--state-selected); }
.qty-stepper input {
    width: 56px;
    border: none;
    border-radius: 0;
    background: transparent;
    padding: 9px 4px;
    text-align: center;
    -moz-appearance: textfield;
}
.qty-stepper input:focus { outline: none; box-shadow: none; }
.qty-stepper input::-webkit-outer-spin-button,
.qty-stepper input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* --- Historie-Filter (article_edit.php): Alle/Neu/Gebraucht als
   zusammenhängendes MD3-Pill-Segment statt einzelner .btn.btn-sm-Links
   (Vorbild: .qty-stepper). */
.history-filter {
    display: inline-flex;
    background: var(--color-panel-raised);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.history-filter-btn {
    padding: 7px 16px;
    font-size: 0.82rem;
    color: var(--color-ink-soft);
    text-decoration: none;
    transition: background-color 0.15s, color 0.15s;
}
.history-filter-btn:hover { background: var(--state-hover); color: var(--color-ink); }
.history-filter-btn.is-active {
    background: var(--state-selected);
    color: var(--color-brick);
    font-weight: 600;
}

/* "In der vollständigen Historie ansehen"-Link unter der Historie-Tabelle
   als dezenter MD3-Textbutton statt nacktem <a> (kein Unterstrich, Tonfläche
   beim Hover, Pfeil-Icon signalisiert Sprung auf eine andere Seite). */
.history-view-all-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 14px;
    padding: 6px 12px;
    border-radius: var(--radius-pill);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-ink-soft);
    background: var(--color-panel-raised);
    text-decoration: none;
    transition: background-color 0.15s, color 0.15s;
}
.history-view-all-link:hover { background: var(--state-hover); color: var(--color-brick); }
.history-view-all-link svg { flex-shrink: 0; }

/* Feste Breite für Zeitpunkt/Zustand (siehe colgroup in article_edit.php) -
   Zeitpunkt knapp auf das feste Datumsformat "TT.MM.JJ - HH:MM" bemessen
   (nowrap auf der Zelle), Zustand auf das breitere "Gebraucht"-Badge inkl.
   Icon (siehe .pick-items-condition-badge), jeweils mit etwas Puffer gegen
   Font-/Locale-Ausreißer. Grund/Referenz/Änderung bleiben ohne feste Breite
   und teilen sich den Rest. */
.history-table { table-layout: fixed; }
.history-table td, .history-table th { overflow-wrap: break-word; }
.history-table td:nth-child(2), .history-table th:nth-child(2) { text-align: center; }

/* Mittlere Breite: Bild links, beide Info-Spalten rechts untereinander */
@media (max-width: 1100px) {
    .article-view-layout {
        grid-template-columns: auto minmax(0, 1fr);
    }
    .article-view-media { grid-row: span 2; }
    .article-view-col + .article-view-col {
        border-left: none;
        border-top: 1px solid var(--color-line);
        margin-top: 0;
        padding-top: 16px;
    }
    .article-view-col:first-of-type { margin-bottom: 16px; }
}
@media (max-width: 720px) {
    .article-view-layout {
        grid-template-columns: 1fr;
    }
    .article-view-media { grid-row: auto; padding: 16px; }
    .article-view-image {
        width: 100%;
        height: 220px;
    }
    .article-view-col { padding: 0 16px; }
    .article-view-col .detail-row { grid-template-columns: 1fr; gap: 2px; }
    .article-view-col:first-of-type { margin: 16px 0; }
}

/* --- Klick-zum-Bearbeiten (Stammdaten + Lot-Felder, article_edit.php) ---
   Ersetzt den früheren separaten Bearbeiten-Modus: Klick auf den Anzeigewert
   blendet ein Eingabefeld + Speichern-Icon ein, per AJAX ohne Reload. */
.field-editable {
    display: inline-flex;
    align-items: stretch;
    vertical-align: middle;
    gap: 0;
    flex-wrap: wrap;
}
/* Bewusst neutrales Grau statt var(--state-hover) (Markenblau) - Blau
   signalisiert im übrigen UI primäre Aktionen/Links, ein bearbeitbarer
   Wert ist aber keine solche Aktion. Pillenform (radius-pill) + spürbares
   Padding statt der schmalen radius-sm-Kontur lässt den Hover wie einen
   MD3-Textbutton um den Wert wirken; die gleich große negative margin
   gleicht das Padding aus, damit der Wert nicht aus der Fließtext-Position
   rutscht (Hover-Fläche wächst nur "nach außen" über die Nachbarelemente).
   border: 1px solid transparent ist reine Höhen-Parität zum Eingabemodus
   (.field-input-row hat denselben Borderwert) - ohne das wäre die Anzeige-
   Zeile beim Umschalten in den Bearbeiten-Modus um die Borderbreite
   niedriger und die Zeile "springt" sichtbar nach unten. */
.field-display {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    margin: -3px -10px;
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    transition: background-color 0.15s;
}
.field-display:hover {
    background: rgba(255,255,255,0.08);
}
/* Eingabemodus: Eingabefeld und Bestätigen-Button standen vorher als lose
   Einzelelemente nebeneinander (eckiger Input mit dickem blauen
   Fokusrahmen + separater runder Button daneben). Jetzt eine gemeinsame
   MD3-Kontur: .field-input-row liefert Rahmen/Fläche der Pille, das Input
   selbst ist randlos/transparent und der Bestätigen-Button dockt (bei
   gap:0 auf .field-editable) nahtlos rechts an, statt als eigenständiges
   Element zu schweben. */
.field-input-row {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    transition: border-color 0.15s, box-shadow 0.15s;
}
/* Grauer statt blauer Fokusring - liegt auf dem gemeinsamen Container statt
   auf dem Input allein (siehe .field-input-row .field-input:focus weiter
   unten, das den globalen blauen input:focus-Ring hier deaktiviert), damit
   der Ring die ganze Pille inkl. Button-Segment umschließt. */
.field-input-row:focus-within {
    border-color: rgba(255,255,255,0.4);
    box-shadow: 0 0 0 3px rgba(255,255,255,0.12);
}
/* Unterzustand-Spalte (.lots-table): das <select> ist hier bereits per
   initMd3Dropdown() zu einem eigenen, komplett fertig gestylten
   Pillen-Button aufgewertet (.md3-dropdown-trigger) - ein zusätzlicher
   Rahmen/Hintergrund auf .field-input-row selbst wäre eine zweite,
   überflüssige Pille um die schon vorhandene (gleiches "sieht falsch aus"
   wie beim Farb-Chip weiter oben). */
.field-input-row:has(.md3-dropdown) {
    border: none;
    background: none;
}
/* Nahtloser Übergang zum Bestätigen-Button: nur wenn er unmittelbar auf
   .field-input-row folgt. Beim Hinweistext-Feld (platform_description)
   sitzt dazwischen noch der runde Presets-Button - für diesen Sonderfall
   bleibt bewusst die alte, einzeln stehende Optik erhalten statt einer
   erzwungenen Drei-Segment-Pille. */
.field-input-row:has(+ .field-save-btn) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border-right: none;
}
.field-input-row:has(+ .field-save-btn) .md3-dropdown-trigger {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
.field-input-row + .field-save-btn {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-left: none;
}
/* Artikeltitel (h1) ist selbst editierbar - Eingabefeld an die Titelgröße
   angleichen statt der geerbten Standardgröße aus .field-input-row
   .field-input. Steht bewusst NACH dieser generischen Regel (gleiche
   Spezifität, je zwei Klassen) - vorher gewann durch reine Quellreihenfolge
   die generische 0.88rem-Schriftgröße, die Titel-Anpassung lief dadurch
   faktisch ins Leere. */
/* Kein eigenes min-width/width mehr hier - das Eingabefeld soll exakt so
   groß erscheinen wie die Hover-Pille von .field-display, sonst "springt"
   die Zeile beim Umschalten sichtbar auf. activateFieldEdit() (siehe
   <script>) misst dazu die tatsächliche Breite von .field-display und setzt
   sie per Inline-Style auf .field-input-row - das Input selbst füllt diese
   Breite nur noch per width:100% aus. Padding hier bewusst identisch zu
   .field-display (3px 10px), sonst würde die gemessene Breite nicht zur
   tatsächlichen Eingabefeld-Breite passen. */
.field-input-row .field-input {
    width: 100%;
    padding: 3px 10px;
    font-size: inherit;
    line-height: 1.5;
    border: none;
    background: none;
    box-shadow: none;
}
/* Zahlenfelder (Gewicht, Jahr, Preis) ohne die nativen Auf/Ab-Pfeilchen -
   die stehlen bei den ohnehin schon knapp bemessenen Feldern unnötig Breite
   und wurden nie zum Klicken gedacht (siehe gleiches Muster bei
   .weight-input und .pick-qty-confirm input[type="number"] weiter unten). */
.field-input-row input.field-input[type="number"] {
    appearance: textfield;
    -moz-appearance: textfield;
}
.field-input-row input.field-input[type="number"]::-webkit-outer-spin-button,
.field-input-row input.field-input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
/* Der globale input:focus-Rahmen (blau, siehe input:focus weiter oben im
   Stylesheet) würde hier als dicker blauer Ring um das - jetzt randlose -
   Eingabefeld erscheinen; der Fokus-Zustand übernimmt stattdessen komplett
   .field-input-row:focus-within (grauer Ring um die ganze Pille inkl.
   Button, siehe oben). */
.field-input-row .field-input:focus {
    outline: none;
    box-shadow: none;
    border-color: transparent;
}
.article-title-editable .field-input {
    font-size: 1.6rem;
    font-weight: 700;
    font-family: var(--font-display);
    padding: 3px 10px;
}
/* Natives <select> (z.B. "Typ" oben in den Stammdaten) - anders als die
   Unterzustand-Spalte nicht per initMd3Dropdown() zu einem eigenen Button
   aufgewertet, bekommt aber dieselbe Pillen-Optik direkt auf dem <select>:
   eigener Pfeil per appearance:none + Hintergrund-Chevron statt des nativen,
   je nach Betriebssystem unterschiedlich aussehenden Pfeils. */
.field-input-row select.field-input {
    appearance: none;
    padding-right: 30px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='%238a8a8e'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}
/* Select, das zusätzlich per initMd3Dropdown() zum MD3-Dropdown aufgewertet
   wurde (siehe Unterzustand-Spalte, .lots-table): .field-input-row .field-input
   hat höhere Spezifität als .md3-dropdown-native allein und würde dessen
   Verstecken (width/padding/opacity) sonst wieder überschreiben - die
   Drei-Klassen-Kombination hier gewinnt bewusst dagegen. */
.field-input-row .field-input.md3-dropdown-native {
    width: 1px;
    height: 1px;
    min-width: 0;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    opacity: 0;
    position: absolute;
    pointer-events: none;
}
textarea.field-input {
    min-width: 220px;
}
.field-save-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    padding: 0 12px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: rgba(63,196,136,0.16);
    color: var(--color-ok);
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;
}
.field-save-btn:hover {
    background: var(--color-ok);
    color: #04141f;
    border-color: var(--color-ok);
}

/* --- Bestand-Buchen-Control (article_edit.php) --- */
.lot-adjust-control {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-bottom: 20px;
    padding: 12px 14px;
    background: var(--color-panel-raised);
    border-radius: var(--radius);
}
.lot-adjust-new-fields {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.lot-adjust-new-fields input {
    width: auto;
}
/* Buchen-Button auf dieselbe Höhe wie die Eingabefelder davor (Mengen-Stepper,
   Ziel-Lot-Dropdown) bringen - ohne dies stand der Button dank .btn-sm
   spürbar niedriger da als die restliche Zeile. */
.lot-adjust-control .btn-primary {
    padding: 9px 20px;
    font-size: 0.88rem;
}
/* eBay-Toggle innerhalb der Buchen-Zeile: per margin-left:auto ans Zeilenende
   gedrückt, per Trennlinie optisch von der Buchen-Bedienung abgegrenzt, da
   inhaltlich unabhängig (Artikel-weite Einstellung statt Bestandsbuchung). */
.lot-adjust-ebay {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    padding-left: 10px;
    border-left: 2px solid var(--color-line);
}
/* Auf dem Handy bricht die Zeile um: die Trennlinie links stand dann vor
   einer leeren Fläche. Dort wird sie zur Linie über einer eigenen Zeile. */
@media (max-width: 600px) {
    .lot-adjust-control #lotAdjustTarget { flex: 1 1 140px; width: auto; min-width: 0; }
    .lot-adjust-ebay {
        flex: 1 0 100%;
        flex-wrap: wrap;
        margin-left: 0;
        padding: 10px 0 0;
        border-left: 0;
        border-top: 1px solid var(--color-line);
    }
}
/* MD3-Toggle-Button fürs eBay-Flag: Icon + Label + Schalter in einem
   gemeinsamen, klickbaren Element (das <label> deckt den ganzen Bereich ab,
   ein Klick irgendwo darin schaltet die dahinterliegende Checkbox). */
.ebay-toggle-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 12px 7px 14px;
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    margin: 0;
    cursor: pointer;
    font-size: 0.88rem;
    font-weight: 600;
    user-select: none;
    transition: background-color 0.15s;
}
.ebay-toggle-btn:hover { background: var(--state-hover); }
.ebay-toggle-icon { flex-shrink: 0; color: var(--color-ink-soft); }
.ebay-toggle-text { white-space: nowrap; color: #fff; }
.ebay-toggle-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.ebay-toggle-switch {
    position: relative;
    width: 34px;
    height: 20px;
    flex-shrink: 0;
    border-radius: var(--radius-pill);
    background: var(--color-line);
    transition: background-color 0.15s;
}
.ebay-toggle-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--color-ink-soft);
    transition: transform 0.15s, background-color 0.15s;
}
.ebay-toggle-input:checked ~ .ebay-toggle-switch {
    background: var(--color-brick);
}
.ebay-toggle-input:checked ~ .ebay-toggle-switch .ebay-toggle-switch-thumb {
    transform: translateX(14px);
    background: #04141f;
}
.ebay-toggle-input:focus-visible ~ .ebay-toggle-switch {
    box-shadow: 0 0 0 3px var(--state-focus);
}
/* Hinweis "BrickOwl: ..." im Bestand-Block (article_edit.php), wenn BrickOwl
   mehrere BrickLink-getrennte Artikel unter derselben Katalog-Nummer (BOID)
   führt. Per border-left/padding-left vom eBay-Toggle abgegrenzt - dieselbe
   Trennlinien-Optik wie zwischen Buchen-Bedienung und eBay-Toggle
   (.lot-adjust-ebay), da auch hier inhaltlich unabhängige Bereiche
   aneinanderstoßen. */
.brickowl-shared {
    display: inline-flex;
    align-items: center;
    align-self: stretch;
    gap: 6px;
    padding-left: 14px;
    border-left: 2px solid var(--color-line);
    font-size: 0.88rem;
}
.brickowl-shared-icon { flex-shrink: 0; color: var(--color-ink-soft); }
.brickowl-shared-label { font-weight: 600; }
.brickowl-shared-link { color: var(--color-brick); text-decoration: none; }
.brickowl-shared-link:hover { text-decoration: none; }

/* MD3-Dropdown - ersetzt fürs Bestand-Buchen-Ziel-Lot-Select und das
   zugehörige Zustand(Set)-Mini-Select im "Neuer Lot"-Zweig den nativen
   <select>-Popup komplett (siehe initMd3Dropdown() in article_edit.php):
   das <select> bleibt nur unsichtbar als Werte-Quelle bestehen, Klick-Feld
   und Menü werden eigenständig gerendert - so bleibt die Optik unabhängig
   von Browser/OS identisch statt teils weiß/unlesbar. */
/* --- Portokasse aufladen (settings.php, Reiter Versand) --- */
/* Betragsfeld, Zahlweg und Knopf stehen in einer Zeile; ausgerichtet wird an
   der Unterkante, weil nur das Betragsfeld eine Beschriftung darüber trägt. */
.portokasse-topup-row {
    display: flex;
    gap: 10px;
    align-items: flex-end;
    flex-wrap: wrap;
}
/* Der Dropdown-Trigger bringt einen eigenen, dunkleren Grundton mit. Direkt
   neben dem Betragsfeld (M3 "filled text field", siehe .md3-field) sähe das
   nach zwei verschiedenen Bauteilen aus - hier deshalb dieselbe Tonfläche. */
.portokasse-topup-row .md3-dropdown-trigger {
    background: var(--color-panel-raised);
}
.portokasse-topup-row .md3-dropdown-trigger:hover,
.portokasse-topup-row .md3-dropdown.is-open .md3-dropdown-trigger {
    background: var(--color-surface-container-high);
}

.md3-dropdown {
    position: relative;
    display: inline-flex;
}
/* Dropdown innerhalb eines .field-Containers (z.B. eine Filterzeile mit
   Label) - füllt die vom Feld vorgegebene Breite statt der pauschalen
   190px-Mindestbreite des Standard-Triggers, die schmale Spalten sprengen
   würde. */
.field .md3-dropdown { width: 100%; }
.field .md3-dropdown-trigger { width: 100%; min-width: 0; }
.md3-dropdown-native {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}
.md3-dropdown-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-width: 190px;
    padding: 9px 12px 9px 16px;
    border: none;
    border-radius: var(--radius-pill);
    /* Dieselbe Tonflaeche wie Suchfeld und Farbfilter daneben - vorher lag
       der Ausloeser auf dem dunklen Tabellenton und stach aus jeder
       Filterleiste heraus. */
    background: var(--color-surface-container-high);
    color: var(--color-ink);
    font-size: 0.92rem;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.15s;
}
.md3-dropdown-trigger:hover { background: var(--color-surface-container-high); filter: brightness(1.12); }
.md3-dropdown-trigger:focus-visible,
.md3-dropdown.is-open .md3-dropdown-trigger {
    outline: none;
    box-shadow: 0 0 0 3px var(--state-focus);
}
.md3-dropdown-value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.md3-dropdown-chevron {
    flex-shrink: 0;
    color: var(--color-ink-soft);
    transition: transform 0.15s;
}
.md3-dropdown.is-open .md3-dropdown-chevron { transform: rotate(180deg); }
/* position:fixed statt absolute + Koordinaten aus getBoundingClientRect()
   (siehe positionMd3DropdownMenu() in article_edit.php): .panel hat
   overflow-x:auto, wodurch der Browser overflow-y ebenfalls implizit auf
   auto setzt (CSS-Spec: eine visible-Achse neben einer nicht-visible-Achse
   wird zu auto) - ein absolut positioniertes Menü würde dadurch vom Panel
   abgeschnitten/eingescrollt statt frei über dem Inhalt zu schweben. Fixed
   positioniert relativ zum Viewport und ignoriert das Overflow der Vorfahren. */
.md3-dropdown-menu {
    position: fixed;
    min-width: 160px;
    max-height: 280px;
    overflow-y: auto;
    background: var(--color-surface-container-high);
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    padding: 6px;
    box-shadow: var(--elevation-3);
    box-sizing: border-box;
    z-index: 200;
}
.md3-dropdown-group-label {
    padding: 8px 10px 4px;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-ink-faint);
    white-space: nowrap;
}
.md3-dropdown-option {
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: 0.86rem;
    color: var(--color-ink);
    white-space: nowrap;
    cursor: pointer;
}
.md3-dropdown-option:hover { background: var(--state-hover); }
.md3-dropdown-option.is-selected { background: var(--state-selected); font-weight: 600; }
/* Tastatur-Markierung (Pfeiltasten im Such-Modus) - optisch wie :hover, damit
   Maus- und Tastaturbedienung dasselbe "hier steht der Cursor" zeigen. */
.md3-dropdown-option.is-active { background: var(--state-hover); }
.md3-dropdown-empty {
    padding: 9px 10px;
    font-size: 0.85rem;
    color: var(--color-ink-faint);
    white-space: nowrap;
}

/* Such-Modus (data-md3-search am <select>, siehe assets/js/md3-dropdown.js):
   der Trigger ist ein Textfeld statt einer Beschriftung. Das <input> erbt die
   Pillen-Optik vom Trigger drumherum und ist selbst randlos/transparent. */
.md3-dropdown-trigger-search { cursor: text; }
.md3-dropdown-search {
    flex: 1;
    min-width: 0;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--color-ink);
    font-family: inherit;
    font-size: 0.88rem;
    outline: none;
}
.md3-dropdown-search::placeholder { color: var(--color-ink-faint); }
.md3-dropdown-trigger-search:focus-within {
    background: var(--state-hover);
    box-shadow: 0 0 0 3px rgba(255,255,255,0.12);
}

/* --- Versandübersicht (shipping.php) --- */

/* Gewicht in kg, schmal und ohne Zahlen-Pfeilchen. Das Feld ist ein
   type="text" (das Komma wegen), die appearance-Regeln fangen nur den Fall ab,
   dass hier jemand später wieder ein type="number" einsetzt.
   Optik wie der geschlossene .md3-dropdown-trigger daneben (randlos, voll
   gerundet, gleiche angehobene Fläche) - beide Felder einer Zeile sollen als
   zusammengehöriges Paar wirken. margin-right schafft den Abstand zur
   "kg"-Einheit dahinter, die sonst direkt am Feld kleben würde. */
.weight-input {
    width: 41px;
    padding: 9px 6px;
    margin-right: 6px;
    text-align: center;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    appearance: textfield;
    -moz-appearance: textfield;
}
.weight-input::-webkit-outer-spin-button,
.weight-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Produkt- UND Zusatzleistungs-Dropdown (siehe initMd3Dropdown()-Aufruf für
   beide Selects unten) heben sich von der Tabellenzeile ab: der Standard-
   Trigger (#18181a) liegt so dicht am Panel-Ton, dass er in der Zeile
   untergeht. Gleiche Fläche wie jedes andere Eingabefeld (input/select oben),
   damit es auch als eines gelesen wird. Bewusst nur hier, der Trigger tritt
   anderswo (Filterleiste, Lot-Tabelle) auf dunklerem Grund auf. Keine eigene
   min-width mehr (der Standardwert aus .md3-dropdown-trigger reicht) -
   schmaler als vorher, damit das Zusatzleistungs-Dropdown daneben in der
   Zeile Platz hat. */
.shipping-product-cell .md3-dropdown-trigger {
    background: var(--color-panel-raised);
}
.shipping-product-cell .md3-dropdown-trigger:hover,
.shipping-product-cell .md3-dropdown.is-open .md3-dropdown-trigger {
    background: var(--color-surface-container-high);
}
/* Einzelversand-Button (Papierflieger) hängt direkt am Dropdown statt in einer
   eigenen Spalte am Zeilenende - beide gehören inhaltlich zusammen (Produkt
   wählen -> sofort für diese Zeile kaufen). Die Spalte ist nur so breit wie
   ihr breitester Zeileninhalt (width:1% am th); in schmaleren Zeilen füllt
   das Produkt-Dropdown den Rest, damit jede Zeile bündig unter der
   Überschrift beginnt und die Knöpfe untereinander am rechten Rand stehen. */
.shipping-product-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.shipping-product-row > .md3-dropdown:first-child { flex: 1 1 auto; }
.shipping-product-row > .md3-dropdown:first-child .md3-dropdown-trigger { width: 100%; }
.shipping-product-row .order-action-btn {
    flex-shrink: 0;
}

/* Empfänger-Spalte: Adresscheck-Icon (.address-check-icon, siehe list_helpers.php)
   links neben Name+Adresse statt inline im Text. Normale Icon-Größe wie überall
   sonst im Tool (customers.php, customer_detail.php, order_detail.php) - war
   testweise per JS auf die Höhe von Name- plus Adresszeilen daneben gestreckt,
   wirkte damit aber neben der jetzt zweizeiligen Adresse zu groß. */
.recipient-cell {
    display: flex;
    align-items: center;
    gap: 10px;
}
.recipient-cell .address-check-icon {
    flex-shrink: 0;
    margin-right: 0;
}

/* --- Lot-Tabelle (article_edit.php): Zustand-Badge steht jetzt pro Zeile in
   einer eigenen ersten Spalte statt als eigene Zwischenüberschrift-Zeile pro
   Gruppe - die beiden <tbody data-condition="NEW|USED"> bleiben aber in fester
   Reihenfolge (Neu vor Gebraucht) im DOM, das genügt für die Sortierung.
   Die Unterzustand-Spalte wird nur für Typ=SET überhaupt ins DOM gerendert
   (siehe $COL_COUNT-Kommentar in article_edit.php), verschiebt also je nach
   Artikeltyp die Position der nachfolgenden Spalten - deshalb .lot-stat/
   .lot-platform-col als explizite Klassen statt positions-abhängiger
   nth-child-Selektoren. */
/* Menge/Reserviert/Verfügbar farblich als zusammengehöriger Block lesbar und
   zentriert statt rechtsbündig (überschreibt .num) darstellen, damit die drei
   Spalten wie eine zusammengehörige Kennzahlengruppe wirken. Grauton statt
   Markenblau, damit die Fläche als neutrale Gruppierung liest statt wie ein
   aktiver/interaktiver Zustand (Blau ist im übrigen UI für Primäraktionen/
   Fokus reserviert). */
.lots-table th.lot-stat,
.lots-table td.lot-stat {
    background: rgba(255,255,255,0.02);
    text-align: center;
}
.lots-table td.lot-available {
    font-weight: 600;
}
.lots-table td.lot-available.is-positive { color: var(--color-ok); }
.lots-table td.lot-available.is-zero { color: var(--color-ink-soft); }
/* Reserviert-Badge kreisförmig statt als Pille - eigene Klasse zusätzlich zu
   .badge-low, damit Form und Farbe unabhängig bleiben. */
.badge-circle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border-radius: 50%;
    font-size: 0.72rem;
    text-transform: none;
    letter-spacing: normal;
}
/* Plattform-Spalten (BrickLink/BrickOwl/eBay): Text linksbündig innerhalb der
   Spalte, weiterhin am rechten Tabellenrand positioniert. white-space:nowrap
   verhindert, dass lange Lot-IDs (z.B. "237724749") in der knappen
   Spaltenbreite umbrechen. */
.lots-table th.lot-platform-col,
.lots-table td.lot-platform-col {
    text-align: left;
    white-space: nowrap;
}
/* Lot-ID + ↻-Reset-Button (article_edit.php, BrickLink/BrickOwl-Spalte) -
   Reset-Button bleibt dezent (erst bei Hover der Zelle sichtbar), damit die
   ohnehin knappe Spalte nicht optisch überladen wirkt. */
.lot-listing-cell {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.lot-listing-reset {
    opacity: 0;
    transition: opacity 0.12s ease;
}
.lot-platform-col:hover .lot-listing-reset,
.lot-listing-reset:focus-visible {
    opacity: 1;
}
/* Feste Spaltenbreiten - sonst verschiebt sich beim Umschalten einer Zelle
   zwischen Anzeige und Eingabefeld die gesamte Tabelle spürbar (vormals ein
   Inline-<style>-Block direkt in article_edit.php). */
.lots-table { table-layout: fixed; }
.lots-table td { overflow-wrap: break-word; }
/* Unterzustand-Spalte: schmalere Variante des MD3-Dropdowns (siehe
   .md3-dropdown-trigger oben) - die Spalte muss innerhalb der 170px-<col>-
   Breite (siehe colgroup in article_edit.php) bleiben, ohne beim Wechsel
   zwischen Anzeige- und Bearbeiten-Zustand zu wachsen. Kurze Optionswerte
   ohne "(New/Used ...)"-Zusatz ($setConditionOptionsTable in
   article_edit.php) plus knappere Paddings/Chevron halten die Breite auch
   für "Unvollständig" (längster Wert) spaltentauglich; max-width auf dem
   Wertetext dient nur als Sicherheitsnetz gegen Font-/Locale-Ausreißer
   (fällt sonst nie ein). */
.lots-table .md3-dropdown-trigger {
    min-width: 0;
    padding: 4px 8px;
    gap: 5px;
    font-size: 0.82rem;
    line-height: 1.5;
}
.lots-table .md3-dropdown-value {
    max-width: 96px;
}
.lots-table .md3-dropdown-chevron {
    width: 13px;
    height: 13px;
}
/* Lager/Preis/Hinweis-Spalten: dasselbe Grundproblem wie bei Unterzustand vor dem
   MD3-Dropdown-Umbau oben - das Eingabefeld hatte über .field-input-row
   .field-input eine feste min-width (140px), die vor allem die schmalen
   Lager-/Preis-Spalten überragen und in die Nachbarspalte laufen konnte.
   .field-editable wird hier statt des normalen shrink-to-fit inline-flex
   auf volle Zellbreite gestellt, das Eingabefeld füllt darin die tatsächlich
   verfügbare Breite - dadurch bleibt die Spalte beim Wechsel Anzeige-/
   Bearbeiten-Zustand stabil, unabhängig von der jeweiligen <col>-Breite.
   Die Lager-/Preis-<col> (#col-storage-location/#col-price-eur, siehe
   colgroup in article_edit.php) selbst ist knapp auf den jeweiligen
   Anzeigewert bemessen ("XXX-XXX" bzw. "XXX,XXX €") und wird von
   activateFieldEdit()/deactivateFieldEdit() (siehe <script>-Block) beim
   Wechsel in den Bearbeiten-Modus auf eine breitere Spalte umgeschaltet,
   die zusätzlich Platz für den Bestätigen-Button lässt, statt dauerhaft
   breiter als nötig zu sein. */
.lots-table .field-editable[data-field="storage_location"],
.lots-table .field-editable[data-field="price_eur"],
.lots-table .field-editable[data-field="platform_description"] {
    display: flex;
    width: 100%;
    flex-wrap: nowrap;
}
.lots-table .field-editable[data-field="storage_location"] .field-input-row,
.lots-table .field-editable[data-field="price_eur"] .field-input-row,
.lots-table .field-editable[data-field="platform_description"] .field-input-row {
    flex: 1 1 auto;
    min-width: 0;
    /* Eigene Pille sitzt hier bereits direkt auf dem Input (siehe unten) -
       der generische Pillen-Rahmen/-Hintergrund von .field-input-row (siehe
       oben) würde sonst eine zweite, versetzte Pille drumherum zeichnen. */
    border: none;
    background: none;
}
/* Pillenoptik passend zum MD3-Dropdown-Trigger der Unterzustand-Spalte statt
   des eckigen Standard-Inputs (Rahmen + radius-sm, siehe globale
   input,select,textarea-Regel) - visuell dasselbe "Design von oben". */
.lots-table .field-editable[data-field="storage_location"] input.field-input,
.lots-table .field-editable[data-field="price_eur"] input.field-input,
.lots-table .field-editable[data-field="platform_description"] input.field-input {
    width: 100%;
    min-width: 0;
    border: none;
    border-radius: var(--radius-pill);
    background: #18181a;
    padding: 4px 12px;
    font-size: 0.82rem;
}
/* Lager/Preis: enger als der Hinweistext-Standard (4px 12px) - Lagercode
   und Betrag sind kurze, feste Formate ("XXX-XXX" / "XXX,XXX €"), das
   generische Padding ließ hier unnötig viel Luft und zwang die Spalte
   breiter als nötig. */
.lots-table .field-editable[data-field="storage_location"] input.field-input,
.lots-table .field-editable[data-field="price_eur"] input.field-input {
    padding: 4px 8px;
}
/* Dieselbe Verschlankung auch für die Anzeige-Pille (.field-display), sonst
   bliebe die Hover-Fläche breiter als das enger gefasste Eingabefeld und die
   knapp bemessene <col> würde den Anzeigewert clippen. margin gleicht das
   Padding wie beim generischen .field-display oben aus. */
.lots-table .field-editable[data-field="storage_location"] .field-display,
.lots-table .field-editable[data-field="price_eur"] .field-display {
    padding: 3px 6px;
    margin: -3px -6px;
}
/* storage_location/price_eur haben keinen Presets-Button dazwischen - der
   Bestätigen-Button dockt hier also direkt an (siehe .field-input-row:has(+
   .field-save-btn) weiter oben) und die eigene Input-Pille braucht rechts
   dieselbe abgeflachte Ecke, sonst träfe eine runde auf eine flache Kante. */
.lots-table .field-editable[data-field="storage_location"] .field-input-row:has(+ .field-save-btn) input.field-input,
.lots-table .field-editable[data-field="price_eur"] .field-input-row:has(+ .field-save-btn) input.field-input {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
/* Preis-Spalte: linksbündig statt der generischen rechtsbündigen num-Optik
   (Beträge stehen hier direkt neben Lager/Hinweis, rechtsbündig hätte die
   Ziffern optisch von den Nachbarspalten losgelöst wirken lassen) - die
   Monospace-Schrift von td.num/th.num (Ziffernbreiten gleichmäßig) bleibt
   trotzdem erwünscht, deshalb eigene Klasse statt nur text-align auf .num
   zu überschreiben. */
.lots-table th.price-col,
.lots-table td.price-col {
    text-align: left;
    font-family: var(--font-mono);
}
/* Kartenoptik, Kopfzeilen-Ton, Zellabstände und Zeilen-Hover aller
   Datentabellen kommen aus der globalen Tabellen-Designsprache weiter oben
   (Abschnitt "Tabellen: eine Designsprache für das ganze Tool"). Hier stehen
   nur noch die tabellenspezifischen Abweichungen. */
/* Erste Spalte ist reine Checkbox-Klickfläche ohne Header-Text. Die zweite
   Spalte verzichtet auf ihr linkes Padding, damit zwischen Checkbox und Datum
   nicht doppelter Abstand steht - den Abstand trägt allein das rechte Padding
   der Checkbox-Zelle, gleich breit wie links (12px). Nur für Tabellen mit
   Checkbox-Spalte (erkennbar am th.card-media vorn: Bestellungen, offener
   Versand) - Kunden, Versendet und Kundendetail haben keine und behalten die
   normalen Zellabstände. :where() hält die Spezifität bei der alten Regel,
   sonst überstimmte sie mobil das padding der Kartenansicht. */
.orders-table:where(:has(th.card-media:first-child)) th:first-child,
.orders-table:where(:has(th.card-media:first-child)) td:first-child { padding-left: 12px; padding-right: 12px; }
/* Als Inline-Element sitzt die Checkbox auf der Grundlinie und trägt den
   Browser-Standardrand - als Block ohne Rand zentriert sie das
   vertical-align:middle der Zelle sauber; margin-inline:auto stellt sie
   zusätzlich waagerecht in die Spaltenmitte. */
.orders-table th:first-child input[type="checkbox"],
.orders-table td:first-child input[type="checkbox"] { display: block; margin: 0 auto; }
.orders-table:where(:has(th.card-media:first-child)) th:nth-child(2),
.orders-table:where(:has(th.card-media:first-child)) td:nth-child(2) { padding-left: 0; }
/* .lot-stat bleibt vom globalen Zeilen-Hover ausgenommen, damit dessen
   permanente graue Gruppierungs-Tönung beim Hover nicht kurz von der
   (gleichfarbigen, aber zusätzlichen) Hover-Fläche überdeckt wird. Alle
   anderen Tabellen (inkl. .orders-table) nutzen den globalen tr:hover td
   -Standard oben unverändert. */
.lots-table tbody tr:hover td:not(.lot-stat) { background: rgba(255,255,255,0.05); }
/* Der borderlose Preset-Input hat selbst keinen sichtbaren Rahmen - der
   generische input:focus-Ring würde hier als rechteckiger Glow ohne passende
   Kontur erscheinen. Fokus-Optik daher an die abgerundete Pille
   (.preset-add-row) verlegen (vormals ebenfalls im Inline-<style>-Block). */
.preset-add-input:focus { outline: none; border-color: transparent; box-shadow: none; }
.preset-add-row:focus-within { border-color: var(--color-brick); border-style: solid; box-shadow: 0 0 0 3px rgba(57,166,254,0.18); }

/* --- Pickprozess: fokussierter Pickmodus (minifig_pick.php?view=walk) --- */
.pick-walk-card {
    max-width: 480px;
    margin: 0 auto;
    text-align: center;
}
/* Positionsanzeige mit Blätter-Pfeilen als ein zusammenhängendes Element:
   Pfeil links | "Position x von y" + Status | Pfeil rechts. Die Pfeile
   blättern nur (buchen nichts), siehe goTo() im Walk-Modus-Script. */
.pick-walk-nav {
    display: flex;
    align-items: stretch;
    margin: 0 auto 16px;
    max-width: 340px;
    background: var(--color-panel-raised);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    overflow: hidden;
}
.pick-walk-nav-btn {
    flex: none;
    width: 52px;
    min-height: 48px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--color-ink);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    /* Schnelles Antippen soll blättern, nicht per Doppeltipp zoomen (iOS). */
    touch-action: manipulation;
}
.pick-walk-nav-btn:hover:not(:disabled) { background: var(--color-surface-container-high); }
.pick-walk-nav-btn:active:not(:disabled) { background: var(--color-line); }
.pick-walk-nav-btn:disabled { color: var(--color-ink-faint); opacity: 0.4; cursor: default; }
.pick-walk-nav-pos {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 4px 0;
    border-left: 1px solid var(--color-line);
    border-right: 1px solid var(--color-line);
    line-height: 1.25;
}
.pick-walk-nav-count { font-size: 0.9rem; font-weight: 600; color: var(--color-ink); }
.pick-walk-nav-state { font-size: 0.75rem; color: var(--color-ink-soft); }
.pick-walk-nav-state.is-picked { color: var(--color-ok); }
/* Beim Zurückblättern auf eine bereits gebuchte Position: Artikelinfos
   gedimmt, damit sie nicht mit einer offenen verwechselt wird. */
.pick-walk-card.is-picked .pick-walk-image-area,
.pick-walk-card.is-picked .pick-walk-facts { opacity: 0.45; }
.pick-walk-image-wrap {
    width: 340px;
    height: 340px;
    margin: 0 auto 20px;
    background: #ffffff;
    border: 1px solid var(--color-line);
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
/* Bild öffnet in einem neuen Tab (siehe pw-image-link in pick.php) - Link
   füllt den Bild-Wrap komplett aus, damit sich am Layout nichts ändert. */
.pick-walk-image-wrap a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    cursor: pointer;
}
/* width/height (statt max-width/max-height) füllen die Box immer komplett
   aus - object-fit:contain hält dabei das Seitenverhältnis. Bei Artikelbildern
   mit geringerer nativer Auflösung als die Box wird das Bild dadurch bewusst
   hochskaliert statt klein und von Weißraum umgeben zu bleiben. */
.pick-walk-image { width: 100%; height: 100%; object-fit: contain; }
.pick-walk-name {
    font-family: var(--font-display);
    font-size: 1.3rem;
    font-weight: 700;
    color: #ffffff;
    margin-bottom: 4px;
}
/* BrickLink-Nr., Zustand und Farbe in einer (umbrechenden) Zeile statt drei
   übereinander - spart mobil die Höhe, die sonst das Bild verliert. */
.pick-walk-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 8px 10px;
}
.pick-walk-blid {
    font-family: var(--font-mono);
    font-size: 0.85rem;
}
.pick-walk-color { font-size: 0.9rem; }
/* Neu/Gebraucht-Badge im fokussierten Pickmodus etwas größer als die globale
   .badge-Größe (dort besser lesbar aus Entfernung/im Gehen als am Bildschirm
   in der Tabelle) - Icon-SVG-Attribute (width/height) lassen sich per CSS
   überschreiben, das inline vertical-align/margin-right auf dem SVG selbst
   bleibt dabei unangetastet. */
.pick-walk-meta .badge {
    font-size: 1rem;
    padding: 4px 14px;
}
.pick-walk-meta .badge svg {
    width: 16px;
    height: 16px;
}
/* Farbfeld statt reinem Text: Hintergrund = tatsächliche Artikelfarbe (Hex
   aus color_catalog), Textfarbe wird per JS kontrastabhängig (schwarz/weiß)
   gesetzt (siehe contrastTextColor() im Walk-Modus-Script) - bei
   Minifig-Artikeln komplett ausgeblendet (keine echte Farbe, siehe
   pickItemToWalkPayload() in pick.php). */
.pick-walk-color-field {
    display: inline-block;
    min-width: 220px;
    padding: 8px 32px;
    border-radius: var(--radius);
    border: 1px solid rgba(255,255,255,0.15);
    font-weight: 700;
    font-size: 1rem;
    text-align: center;
}
.pick-walk-location-label {
    margin-top: 20px;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-ink-soft);
}
.pick-walk-location, .pick-walk-qty-value {
    font-family: var(--font-display);
    font-size: 3.5rem;
    font-weight: 800;
    color: var(--color-brick);
    line-height: 1.2;
    margin-bottom: 20px;
    word-break: break-word;
}
/* Nächste offene Position liegt am selben Lagerort: grün getönte Fläche (wie
   die .pick-order-c*-Pills) statt nur Farbwechsel - Blau und Grün sind in
   dieser Größe im Gehen schwer zu unterscheiden. Padding/Radius stehen auch
   ohne Markierung, damit beim Blättern nichts springt (siehe render()). */
.pick-walk-location { padding: 0 12px; border-radius: var(--radius); }
.pick-walk-location.is-same-next { background: rgba(63,196,136,0.16); color: var(--color-ok); }
.pick-walk-containers {
    margin-bottom: 24px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 16px;
}
.pick-walk-containers .badge { font-size: 1rem; padding: 4px 12px; }
/* Bestellungs-Badge im Walk-Modus bekommt dieselbe Schriftgröße wie
   Lagerort/Menge (statt der kleinen Pill aus der Tabellenansicht) - eigene,
   größere Icon-Variante dafür in pick.php (PICK_ORDER_BADGE_ICON_LARGE).
   Hintergrund kommt (wie beim Tabellen-Pendant .pick-items-order-badge)
   bewusst aus .pick-order-c0..c5 statt hier gesetzt zu werden - Schriftgröße
   bleibt dabei unverändert, nur Pill-Hintergrund + Innenabstand kommen dazu. */
.pick-walk-containers .pick-order-badge {
    font-family: var(--font-display);
    font-size: 3.5rem;
    font-weight: 800;
    line-height: 1.2;
    padding: 6px 30px;
    border-radius: var(--radius-pill);
    text-transform: none;
    letter-spacing: normal;
}
/* Badge + Zusatzzeilen darunter (z.B. "Bundle: ..." bei Bestellungen mit
   mehreren Bundles, siehe describeItemOrigins()) als eine Spalte je Container. */
.pick-walk-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    min-width: 0;
}
.pick-walk-origin {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--color-ink);
    text-align: center;
    word-break: break-word;
}
/* Dezente Zusatzinfos oberhalb des Bestätigen-Buttons (aktuell: erwarteter
   Bestand nach der Entnahme, fürs direkte Abgleichen mit dem physischen
   Lagerort ohne Zusatzklick - siehe render() im Walk-Modus-Script). */
.pick-walk-info-row {
    font-size: 0.8rem;
    color: var(--color-ink-soft);
    margin-bottom: 12px;
}
/* MD3-Divider (etwas kräftiger als der übliche 1dp-Strich), lockert das
   sonst durchgängige Pickmodus-Layout grob in Abschnitte auf - zwischen
   Artikel-Infos/Lagerort und zwischen Bestellungs-Badges/Zusatzinfo-Zeile. */
.pick-walk-divider {
    border: none;
    height: 2px;
    background: var(--color-line);
    border-radius: 1px;
    margin: 18px 0;
}
.pick-walk-actions .btn { width: 100%; padding: 16px; font-size: 1.05rem; justify-content: center; touch-action: manipulation; }

/* X zum Verlassen neben der Positions-Pille gibt es nur mobil (siehe unten) -
   am Desktop bleibt der Zurück-Link über der Karte. */
.pick-walk-exit { display: none; }

/* Mobil: alles ohne Scrollen auf einen Bildschirm. App-Leiste, Hinweis-
   streifen und Zurück-Link entfallen im Pickmodus (das X links neben der
   Positions-Pille führt zurück) - jeder Pixel darüber fehlte sonst unten.
   Die Karte ist mindestens so hoch wie der sichtbare Rest (--pw-vh/--pw-top
   misst measureTop() im Walk-Modus-Script, dvh ist nur der Startwert davor)
   und verteilt ihn als Spalte: alles hat seine natürliche Höhe, nur das
   Bild (.pick-walk-image-area) nimmt den Rest und schrumpft dafür. Bewusst
   min-height statt height: reicht der Platz selbst für das kleinste Bild
   nicht (sehr kleines Display, große Systemschrift), scrollt die Seite
   lieber ein Stück, als dass der Gepickt-Knopf abgeschnitten wird.
   Lager steht über die volle Breite, Menge und Bestellung teilen sich
   darunter eine Zeile - beide Werte sind kurz. */
@media (max-width: 880px) {
    body:has(.pick-walk-card) .topbar { display: none; }
    /* .app-shell hat global min-height:100vh - in Chrome/Android ist 100vh
       die Höhe OHNE Adressleiste. Bei sichtbarer Leiste war die Seite damit
       genau um deren Höhe zu lang, ließ sich scrollen und die Leiste fuhr
       weg. Die Karte misst die sichtbare Höhe selbst (--pw-vh), die Hülle
       braucht hier also keine eigene Mindesthöhe. In der Browser-Vorschau
       nicht nachstellbar (dort gibt es keine einfahrende Adressleiste). */
    body:has(.pick-walk-card) .app-shell { min-height: 0; }
    /* main-Padding hier fest auf die Werte, die in der Kartenhöhe abgezogen
       werden - sonst bleibt ein Scrollrest. */
    main:has(> .pick-walk-card) {
        padding-top: calc(20px + env(safe-area-inset-top));
        padding-bottom: calc(8px + env(safe-area-inset-bottom));
    }
    .panel.pick-walk-card {
        display: flex;
        flex-direction: column;
        min-height: calc(var(--pw-vh, 100dvh) - var(--pw-top, 8px) - 8px - env(safe-area-inset-bottom));
        margin-bottom: 0;
        /* Mobil ohne Kartenfläche: Inhalt liegt direkt auf dem Seiten-
           hintergrund (Rahmen/Rundung wirkten auf voller Breite fremd),
           seitlicher Abstand kommt allein vom main-Padding. */
        padding: 0;
        background: transparent;
        border: none;
        border-radius: 0;
        box-shadow: none;
    }
    .pick-walk-card > * { flex: none; }
    /* Drei Spalten: X | Pille | gleich breiter Leerraum - so steht die
       Positions-Pille exakt mittig, das X sitzt links daneben. */
    .pick-walk-top {
        display: grid;
        grid-template-columns: 44px minmax(0, 1fr) 44px;
        align-items: center;
        gap: 6px;
        margin-bottom: 12px;
    }
    .pick-walk-exit {
        flex: none;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        border-radius: 50%;
        color: var(--color-ink-soft);
        -webkit-tap-highlight-color: transparent;
    }
    .pick-walk-exit:active { background: var(--color-surface-container-high); }
    .pick-walk-nav { width: 100%; min-width: 0; max-width: none; margin: 0; }
    .pick-walk-image-area {
        flex: 1 1 0;
        min-height: 80px;
        position: relative;
        margin-bottom: 10px;
    }
    /* Quadratisch, so groß wie der Platz hergibt: absolut in der Restfläche,
       damit height:100% eine feste Bezugshöhe hat (im Flex-Fluss würde das
       Bild die Fläche sonst selbst aufblähen), Breite folgt über
       aspect-ratio, gedeckelt auf die Kartenbreite. Oben angesetzt statt
       vertikal zentriert: sonst wächst auf hohen Displays die Lücke unter
       der Positions-Pille mit, der Abstand soll dort fest bleiben. */
    .pick-walk-image-wrap {
        position: absolute;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        width: auto;
        height: 100%;
        max-width: 100%;
        aspect-ratio: 1 / 1;
        margin: 0;
    }
    .pick-walk-name {
        font-size: 1.1rem;
        line-height: 1.25;
        margin-bottom: 6px;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    .pick-walk-meta .badge { font-size: 0.85rem; padding: 3px 10px; }
    .pick-walk-color-field { min-width: 0; padding: 3px 16px; font-size: 0.9rem; }
    .pick-walk-divider { margin: 10px 0; }
    .pick-walk-facts {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 6px 12px;
        align-items: start;
    }
    .pick-walk-fact { min-width: 0; }
    .pick-walk-fact-location { grid-column: 1 / -1; }
    .pick-walk-location-label { margin-top: 0; font-size: 0.72rem; }
    .pick-walk-location, .pick-walk-qty-value {
        font-size: 2.4rem;
        line-height: 1.1;
        margin-bottom: 0;
    }
    .pick-walk-containers { margin-bottom: 0; gap: 8px; }
    .pick-walk-containers .pick-order-badge {
        font-size: 2.4rem;
        line-height: 1.1;
        padding: 2px 18px;
    }
    .pick-walk-containers .pick-order-badge svg { width: 28px; height: 28px; }
    .pick-walk-container { gap: 4px; }
    .pick-walk-origin { font-size: 0.85rem; }
    .pick-walk-info-row { margin-bottom: 8px; }
    .pick-walk-actions .btn { padding: 14px; }
}

/* --- Pickprozess: farbige Container-Badges (aktuell nur Bestellungen) -
   je Container-Nummer eine feste Farbe aus einer 6er-Palette (zyklisch),
   bewusst ohne Blau/Rot/Grün/Gelb, da diese Farben im übrigen UI schon für
   Primärakzent/Fehler/OK/Warnung stehen. Gleiche Farbe für dieselbe
   Container-Nummer in Container-Übersicht, Pick-Positionen-Tabelle und
   fokussiertem Pickmodus (siehe pick.php renderContainerNumberBadge()). --- */
.pick-order-badge { display: inline-flex; align-items: center; font-family: var(--font-mono); }
/* Bestellungs-Nummer in der Pick-Positionen-Tabelle: normale Tabellen-
   Schriftgröße statt der kleinen Pill aus der Container-Übersicht (dafür
   ohne .badge-Klasse eingebunden, siehe renderContainerNumberBadgeTable() in
   pick.php) - Icon dafür eigens etwas größer (PICK_ORDER_BADGE_ICON_MEDIUM).
   Bewusst kein eigenes background/border-radius hier: die dezente, runde
   Pill-Farbfläche kommt aus .pick-order-c0..c5 (gleiches rgba(...,0.16)-Muster
   wie .badge-new/.badge-used), damit der Bestellungs-Badge optisch zu den
   anderen Badges in der Zeile passt. Selektor trotzdem bewusst als
   .pick-order-badge.pick-items-order-badge (zwei Klassen) statt nur einer:
   gleiche Spezifität wie .pick-order-c0..c5 würde sonst rein über die
   Reihenfolge im Stylesheet entscheiden, welche Regel z.B. font-size/padding
   gewinnt - mit der zweiten Klasse ist das unabhängig von der Reihenfolge
   immer diese Regel. */
.pick-order-badge.pick-items-order-badge {
    font-size: 0.88rem;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: var(--radius-pill);
    text-transform: none;
    letter-spacing: normal;
    margin-bottom: 3px;
}
.pick-item-origin { font-size: 0.8rem; }
.pick-order-c0 { background: rgba(167,139,250,0.16); color: #a78bfa; }
.pick-order-c1 { background: rgba(244,114,182,0.16); color: #f472b6; }
.pick-order-c2 { background: rgba(251,146,60,0.16);  color: #fb923c; }
.pick-order-c3 { background: rgba(45,212,191,0.16);  color: #2dd4bf; }
.pick-order-c4 { background: rgba(192,133,82,0.16);  color: #c08552; }
.pick-order-c5 { background: rgba(168,162,158,0.16); color: #a8a29e; }

/* Mengen-Eingabe + Bestätigen-Button am Zeilenende der Pick-Positionen-
   Tabelle als ein gemeinsames MD3-Element (Tonfläche/Pill mit randlosem
   Zahlenfeld links, rundem Icon-Button rechts) statt zweier getrennter
   Controls - siehe pick.php. */
.pick-qty-confirm {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    background: var(--color-panel-raised);
    border-radius: var(--radius-pill);
    padding: 3px 3px 3px 10px;
}
.pick-qty-confirm input[type="number"] {
    width: 30px;
    padding: 0;
    border: none;
    background: transparent;
    text-align: center;
    font-size: 0.82rem;
    -moz-appearance: textfield;
}
.pick-qty-confirm input[type="number"]:focus {
    box-shadow: none;
}
/* Native Auf/Ab-Pfeile ausblenden - ohne sie sitzt die Zahl (text-align:
   center oben) tatsächlich mittig im Feld statt vom Spinner nach links
   verdrängt zu werden. */
.pick-qty-confirm input[type="number"]::-webkit-outer-spin-button,
.pick-qty-confirm input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
/* Runder Icon-Button (Breite = Höhe + Pill-Radius) statt der gedrückten
   Pillenform eines Textbuttons - Farbgebung wie .order-action-btn (dezentes
   Grau in Ruhe, Tonfläche in Primärfarbe on hover). */
.pick-qty-confirm-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-ink-soft);
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color 0.15s, color 0.15s;
}
.pick-qty-confirm-btn:hover { background: var(--state-hover); color: var(--color-brick); }
.pick-qty-confirm-btn:active { background: var(--state-selected); }

/* --- Scrollbar (Webkit) ---
   Schwebend: keine Spur, runder heller Daumen. Der transparente Rand rückt ihn
   von der Kante ab (background-clip), beim Überfahren wird er etwas dicker.
   Kein scrollbar-color/-width global setzen - damit ignoriert Chrome die
   ::-webkit-scrollbar-Regeln. */
::-webkit-scrollbar { width: 14px; height: 14px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background: #5a5a5f; border-radius: 999px; border: 4px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: #7a7a80; border-width: 3px; background-clip: padding-box; }

/* --- Links innerhalb von Fließtext (z.B. Panel-Beschreibungen) --- */
a { color: var(--color-brick); }
a:hover { color: #5cb6ff; }

/* ============================================================
   Farbtabelle (colors.php)
   ============================================================ */
.page-subtitle {
    color: var(--color-ink-soft);
    margin: 4px 0 20px;
    font-size: 0.9rem;
}

/* Alle Bausteine dieser Seite werden per hidden ein- und ausgeblendet. Ein
   eigenes display (flex/grid) schlägt das display:none des Browsers für
   [hidden] - ohne diese Regel bleiben ausgefilterte Kacheln stehen. */
.pcard[hidden],
.palette-grid[hidden],
.palette-table-wrap[hidden],
.palette-empty[hidden],
.color-sheet[hidden],
.color-sheet-scrim[hidden],
.colorfilter-pop[hidden],
.colorfilter-opt[hidden],
.colorfilter-empty[hidden] { display: none; }

/* --- Werkzeugleiste: Suche links, Ansichtsumschalter rechts --- */
.palette-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.palette-search {
    flex: 1 1 260px;
    max-width: 420px;
}

/* M3 "segmented button": zwei Segmente in einer gemeinsamen Umrandung,
   das aktive trägt die Tonfläche des Primärcontainers. */
.palette-view-switch {
    display: inline-flex;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    overflow: hidden;
    flex: none;
}
.pv-btn {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 40px;
    padding: 0 16px;
    border: none;
    background: transparent;
    color: var(--color-ink-soft);
    font: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
}
.pv-btn + .pv-btn { border-left: 1px solid var(--color-line); }
.pv-btn:hover { background: var(--state-hover); color: var(--color-ink); }
.pv-btn.is-active {
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}

/* --- Familien-Filterchips (M3 filter chips) --- */
.palette-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 18px;
}
.palette-chip {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 14px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-ink-soft);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}
.palette-chip:hover { background: var(--state-hover); color: var(--color-ink); }
.palette-chip.is-active {
    background: var(--color-primary-container);
    border-color: transparent;
    color: var(--color-on-primary-container);
}
.palette-chip-n { opacity: 0.6; font-variant-numeric: tabular-nums; }
.palette-filters-sep {
    width: 1px;
    height: 20px;
    background: var(--color-line);
    margin: 0 2px;
}

/* --- Palettenraster: die Farbfläche ist die Hauptsache, der
   Beschriftungsstreifen darunter so schmal wie möglich. --- */
.palette-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(164px, 1fr));
    gap: 14px;
}
.pcard {
    appearance: none;
    display: flex;
    flex-direction: column;
    padding: 0;
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    background: var(--color-panel-raised);
    color: inherit;
    font: inherit;
    text-align: left;
    overflow: hidden;
    cursor: pointer;
    transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.pcard:hover {
    transform: translateY(-2px);
    border-color: var(--color-brick);
    box-shadow: var(--elevation-2);
}
.pcard:focus-visible {
    outline: none;
    border-color: var(--color-brick);
    box-shadow: 0 0 0 3px var(--state-focus);
}
.pcard-swatch {
    position: relative;
    display: block;
    height: 96px;
    /* Innenschatten statt Rahmen: er trennt helle Farben vom Panel, ohne
       bei dunklen Farben als zweite Kante aufzufallen. */
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
}
.pcard-id {
    position: absolute;
    top: 8px;
    right: 8px;
    padding: 1px 7px;
    border-radius: var(--radius-pill);
    background: rgba(0,0,0,0.42);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    backdrop-filter: blur(2px);
}
.pcard.is-light .pcard-id { background: rgba(255,255,255,0.55); color: #17171a; }
.pcard-stock {
    position: absolute;
    left: 8px;
    bottom: 8px;
    padding: 1px 8px;
    border-radius: var(--radius-pill);
    background: rgba(0,0,0,0.42);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 600;
    backdrop-filter: blur(2px);
}
.pcard.is-light .pcard-stock { background: rgba(255,255,255,0.55); color: #17171a; }
.pcard-foot {
    display: block;
    padding: 9px 11px 11px;
}
.pcard-name {
    display: block;
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--color-ink);
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pcard-sub {
    display: block;
    margin-top: 2px;
    font-size: 0.74rem;
    color: var(--color-ink-soft);
    font-variant-numeric: tabular-nums;
}

.palette-empty {
    padding: 32px 0;
    text-align: center;
    color: var(--color-ink-soft);
}
.palette-count {
    margin: 18px 0 0;
    font-size: 0.82rem;
    color: var(--color-ink-faint);
}

/* --- Tabellenansicht: dieselbe Farbfläche, nur klein --- */
.color-swatch {
    display: inline-block;
    width: 26px;
    height: 26px;
    border-radius: 6px;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.14);
    vertical-align: middle;
    flex-shrink: 0;
}
.color-swatch--btn {
    appearance: none;
    padding: 0;
    border: none;
    cursor: pointer;
}
.color-swatch--btn:hover { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.3), 0 0 0 2px var(--color-brick); }

.col-swatch {
    width: 52px;
    text-align: center;
}

.col-id {
    text-align: center;
    white-space: nowrap;
}

/* Textknopf, der sich wie ein Link verhält (Farbname in der Tabelle) */
.linklike {
    appearance: none;
    border: none;
    background: none;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: var(--color-ink);
    cursor: pointer;
    text-align: left;
}
.linklike:hover { color: var(--color-brick); }

.inline-edit-input {
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    padding: 2px 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-ink);
}

/* ============================================================
   Farbdetail als Seitenblatt (M3 "side sheet", modal)
   Inhalt kommt per AJAX aus colors.php?action=detail.
   ============================================================ */
.color-sheet-scrim {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.55);
    opacity: 0;
    transition: opacity 200ms ease;
    z-index: 70;
}
.color-sheet-scrim.is-open { opacity: 1; }

.color-sheet {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(460px, 100%);
    display: flex;
    flex-direction: column;
    background: var(--color-panel);
    border-left: 1px solid var(--color-outline-variant);
    box-shadow: var(--elevation-3);
    transform: translateX(24px);
    opacity: 0;
    transition: transform 220ms cubic-bezier(0.2, 0, 0, 1), opacity 220ms ease;
    z-index: 71;
}
.color-sheet.is-open { transform: none; opacity: 1; }

.color-sheet-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 10px 12px 20px;
    border-bottom: 1px solid var(--color-line-soft);
    flex: none;
}
.color-sheet-title {
    flex: 1;
    min-width: 0;
    font-weight: 700;
    font-size: 0.98rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.color-sheet-close {
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--color-ink-soft);
    cursor: pointer;
    flex: none;
}
.color-sheet-close:hover { background: var(--state-hover); color: var(--color-ink); }
.color-sheet-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.cd-loading { padding: 40px 20px; text-align: center; color: var(--color-ink-soft); }

.cd-hero {
    position: relative;
    padding: 26px 20px 18px;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
}
.cd-hero-inner { display: flex; flex-direction: column; gap: 2px; }
.cd-hero-id {
    align-self: flex-start;
    padding: 1px 9px;
    border-radius: var(--radius-pill);
    background: rgba(0,0,0,0.42);
    color: #fff;
    font-size: 0.74rem;
    font-weight: 700;
}
.cd-hero-name {
    margin: 6px 0 0;
    font-size: 1.4rem;
    font-weight: 700;
    color: #fff;
    text-shadow: 0 1px 6px rgba(0,0,0,0.45);
}
.cd-hero-hex {
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: rgba(255,255,255,0.82);
    text-shadow: 0 1px 4px rgba(0,0,0,0.4);
}
.cd-hero.is-light .cd-hero-id { background: rgba(255,255,255,0.6); color: #17171a; }
.cd-hero.is-light .cd-hero-name { color: #111113; text-shadow: none; }
.cd-hero.is-light .cd-hero-hex { color: rgba(0,0,0,0.6); text-shadow: none; }

.cd-meta {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px 16px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-line-soft);
}
.cd-meta-label {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-ink-faint);
}
.cd-meta-value { display: block; font-size: 0.88rem; margin-top: 2px; }
.cd-stock-hint { color: var(--color-ok); font-weight: 600; }

.cd-section { padding: 18px 20px; border-bottom: 1px solid var(--color-line-soft); }
.cd-section:last-child { border-bottom: none; }
.cd-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
}
.cd-section-head h3 { margin: 0; font-size: 0.95rem; font-weight: 700; }
.cd-section-note { font-size: 0.76rem; color: var(--color-ink-faint); }
.cd-section-link { font-size: 0.8rem; color: var(--color-brick); text-decoration: none; white-space: nowrap; }
.cd-section-link:hover { color: #5cb6ff; }

/* Verwechslungskandidaten: waagerechte Reihe, damit die Töne unmittelbar
   nebeneinander liegen - das ist der eigentliche Vergleich. */
.cd-near {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 104px;
    gap: 10px;
    overflow-x: auto;
    /* Innenabstand rundherum, weil der Hover-Ring der Kacheln sonst am Rand
       dieses Scroll-Containers abgeschnitten wird; der negative Außenabstand
       links hält die erste Kachel trotzdem auf der Fluchtlinie der
       Überschrift darüber. */
    padding: 3px 3px 8px;
    margin-left: -3px;
    scrollbar-width: thin;
}
.cd-near-item {
    appearance: none;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.cd-near-swatch {
    display: block;
    height: 56px;
    border-radius: var(--radius-sm);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.1);
}
.cd-near-item:hover .cd-near-swatch { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.25), 0 0 0 2px var(--color-brick); }
.cd-near-name {
    font-size: 0.76rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--color-ink);
}
.cd-near-meta { font-size: 0.7rem; color: var(--color-ink-faint); }
.cd-near-item.has-stock .cd-near-meta { color: var(--color-ok); }

.cd-articles { list-style: none; margin: 0; padding: 0; }
.cd-article {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--color-line-soft);
}
.cd-article:last-child { border-bottom: none; }
.cd-article.is-empty { opacity: 0.55; }
.cd-article-link {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    text-decoration: none;
    color: inherit;
}
.cd-article-thumb {
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: var(--radius-sm);
    background: var(--color-panel-raised);
    object-fit: contain;
}
.cd-article-text { min-width: 0; }
.cd-article-name {
    display: block;
    font-size: 0.84rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cd-article-link:hover .cd-article-name { color: var(--color-brick); }
.cd-article-sku { display: block; font-size: 0.74rem; color: var(--color-ink-faint); }
.cd-article-qty {
    display: flex;
    align-items: center;
    gap: 5px;
    flex: none;
    font-size: 0.78rem;
}
.cd-empty, .cd-more { font-size: 0.83rem; color: var(--color-ink-soft); margin: 0; }
.cd-more { margin-top: 10px; }

/* ============================================================
   Farbfilter der Artikelübersicht (articles.php)
   ============================================================ */
/* .panel trägt overflow-x:auto (für breite Tabellen) und schneidet damit
   auch nach unten ab - das Überblendfenster wäre sonst nach zwei Zeilen zu
   Ende. Nur solange es offen ist, sonst verlöre das Panel sein Scrollen. */
.panel:has(.colorfilter.is-open) { overflow: visible; }

.colorfilter-field { flex: 0 0 auto; position: relative; }
.colorfilter { position: relative; }
.colorfilter-trigger {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    min-width: 210px;
    padding: 0 10px 0 14px;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-surface-container-high);
    color: var(--color-ink);
    font: inherit;
    font-size: 0.92rem;
    cursor: pointer;
}
.colorfilter.is-open .colorfilter-trigger,
.colorfilter-trigger:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--state-focus); }
.colorfilter.has-selection .colorfilter-trigger {
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}
.colorfilter-dots { display: inline-flex; }
.colorfilter-dots:empty { display: none; }
.colorfilter-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.2), 0 0 0 2px var(--color-primary-container);
}
.colorfilter-dot + .colorfilter-dot { margin-left: -5px; }
.colorfilter-label { flex: 1; text-align: left; white-space: nowrap; }
.colorfilter-chevron { flex: none; opacity: 0.7; }
.colorfilter.is-open .colorfilter-chevron { transform: rotate(180deg); }

.colorfilter-pop {
    position: absolute;
    top: calc(100% + 6px);
    /* rechtsbündig zum Auslöser: der Farbfilter steht am rechten Ende der
       Filterleiste, linksbündig ragte das Fenster über den Bildschirmrand. */
    right: 0;
    width: 320px;
    max-width: calc(100vw - 32px);
    display: flex;
    flex-direction: column;
    max-height: 60vh;
    background: var(--color-surface-container-high);
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    box-shadow: var(--elevation-3);
    z-index: 40;
    overflow: hidden;
}
.colorfilter-pop-head {
    padding: 12px 12px 10px;
    border-bottom: 1px solid var(--color-line-soft);
    flex: none;
}
.colorfilter-pop-head .search-field input {
    height: 38px;
    background: var(--color-panel);
    font-size: 0.86rem;
    padding-left: 36px;
}
.colorfilter-pop-head .search-field .search-icon { left: 12px; }
.colorfilter-list {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 6px;
}
.colorfilter-opt {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 0.86rem;
}
.colorfilter-opt:hover { background: var(--state-hover); }
/* Feste Maße: .field input setzt Textfeldern width:100%, ein Kästchen
   würde damit die ganze Zeile einnehmen und Farbfläche samt Namen
   hinausschieben. */
.colorfilter-opt input[type="checkbox"] {
    flex: none;
    width: 17px;
    height: 17px;
    min-width: 0;
    margin: 0;
    accent-color: var(--color-brick);
}
.colorfilter-opt-swatch {
    width: 22px;
    height: 22px;
    flex: none;
    border-radius: 5px;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.14);
}
.colorfilter-opt-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.colorfilter-opt-n { flex: none; font-size: 0.76rem; color: var(--color-ink-faint); font-variant-numeric: tabular-nums; }
.colorfilter-empty { padding: 18px 8px; text-align: center; color: var(--color-ink-soft); font-size: 0.85rem; margin: 0; }

.colorfilter-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 12px;
    border-top: 1px solid var(--color-line-soft);
    flex: none;
}
/* Farbe in der Artikeltabelle: der Chip ist zugleich der Filter-Link */
/* color: der Chip bleibt weiss wie der uebrige Tabellentext - als <a>
   erbte er sonst die blaue Linkfarbe. */
.color-chip-link { text-decoration: none; color: var(--color-ink); }
.color-chip-link:hover .color-chip { box-shadow: 0 0 0 2px var(--color-brick); }

@media (max-width: 760px) {
    .palette-grid { grid-template-columns: repeat(auto-fill, minmax(134px, 1fr)); gap: 10px; }
    .pcard-swatch { height: 78px; }
    /* Beide Leistenteile je eine eigene Zeile: mit flex-basis 0 schrumpfte
       der Umschalter auf Nullbreite, statt umzubrechen. */
    .palette-search { flex: 1 1 100%; max-width: none; }
    .palette-view-switch { flex: 1 1 100%; }
    .pv-btn { flex: 1; justify-content: center; }
    /* Auf schmalen Geräten kommt das Farbblatt als M3-Bottom-Sheet von
       unten - von rechts hätte es ohnehin die volle Breite. */
    .color-sheet {
        top: auto;
        left: 0;
        width: 100%;
        max-height: 88vh;
        border-left: none;
        border-top: 1px solid var(--color-outline-variant);
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        transform: translateY(24px);
    }
    .colorfilter-field { flex: 1 1 100%; }
    .colorfilter-trigger { width: 100%; }
    .colorfilter-pop { width: 100%; max-height: 70vh; }
}


.id-badge {
    display: inline-block;
    background: var(--color-panel-raised);
    border: 1px solid var(--color-line);
    border-radius: 4px;
    padding: 1px 7px;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-brick);
}

.id-badge--lego {
    color: var(--color-warn);
    border-color: rgba(224,168,62,0.25);
}

.id-badge--bo {
    color: var(--color-ok);
    border-color: rgba(63,196,136,0.25);
}

.text-faint {
    color: var(--color-ink-faint);
}

.sortable-table th.sortable:hover {
    color: var(--color-brick);
}

.sortable-table th .sort-icon {
    font-size: 0.75rem;
    opacity: 0.5;
    margin-left: 4px;
}

/* ============================================================
   BrickLink-Preise (Artikeldetail): zwei Zustandskarten (Neu/Gebraucht)
   statt zweier dichter 7-Spalten-Tabellen. Der Kartenkopf trägt das
   Zustands-Badge und den runden Reload-Button und bleibt fest; der Rumpf
   (.price-guide-content) wird beim AJAX-"neu laden" ersetzt und enthält
   deshalb auch Kennzahl, Spannen-Balken und Zeitstempel. Zwillings-
   Renderer: renderPriceGuideCardBody() (PHP) und renderPriceGuideRows()
   (JS) - beide in article_edit.php.
   ============================================================ */
.pg-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
}
.pg-card {
    background: var(--color-panel-raised);
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    padding: 18px 20px;
}
.pg-card-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}
.pg-reload { width: 32px; height: 32px; }
.pg-reload svg { width: 17px; height: 17px; }

.pg-empty { font-size: 0.85rem; color: var(--color-ink-soft); margin: 4px 0 0; }

.pg-hero { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.pg-hero-value {
    font-family: var(--font-display);
    font-size: 1.7rem;
    font-weight: 700;
    color: #ffffff;
    line-height: 1;
}
.pg-hero-label {
    font-size: 0.72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-ink-soft);
}
.pg-hero-sub { font-size: 0.8rem; color: var(--color-ink-soft); margin-top: 6px; }
.pg-range { margin-top: 10px; font-size: 0.85rem; }
.pg-range-label { color: var(--color-ink-soft); }
.pg-range-sub { margin-top: 2px; font-size: 0.78rem; color: var(--color-ink-soft); }
.pg-range-badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 0.74rem; font-weight: 700; }
.pg-range-badge.is-fast { background: rgba(63, 196, 136, 0.16); color: var(--color-ok); }
.pg-range-badge.is-normal { background: rgba(57, 166, 254, 0.16); color: #7fc4ff; }
.pg-range-badge.is-slow { background: rgba(224, 168, 62, 0.16); color: var(--color-warn); }
.pg-range-badge.is-stale, .pg-range-badge.is-none { background: rgba(240, 98, 94, 0.16); color: var(--color-danger); }

.pg-bar { margin: 18px 0 2px; }
.pg-bar-title {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-ink-faint);
    margin-bottom: 9px;
}
.pg-bar-track {
    position: relative;
    height: 3px;
    border-radius: var(--radius-pill);
    background: var(--color-line);
    margin: 0 2px;
}
.pg-bar-marker { position: absolute; top: 50%; transform: translate(-50%, -50%); }
.pg-bar-marker.is-sold {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--color-brick);
}
.pg-bar-marker.is-stock {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--color-panel-raised);
    border: 2px solid var(--color-stud);
}
.pg-bar-ends {
    display: flex;
    justify-content: space-between;
    margin-top: 7px;
    font-size: 0.7rem;
    color: var(--color-ink-faint);
    font-variant-numeric: tabular-nums;
}
.pg-bar-cap {
    display: flex;
    flex-wrap: wrap;
    gap: 3px 14px;
    margin-top: 10px;
    font-size: 0.74rem;
    color: var(--color-ink-soft);
}
.pg-bar-cap .d {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin-right: 5px;
}
.pg-bar-cap .d.sold { background: var(--color-brick); }
.pg-bar-cap .d.stock { background: var(--color-panel-raised); border: 2px solid var(--color-stud); }

/* Zu wenige Datenpunkte für eine echte Spanne: der Block bleibt stehen
   (Titel + inaktive Linie + Platzhaltertext), damit Neu-/Gebraucht-Karte
   gleich hoch sind und die Lücke nicht wie ein Renderfehler aussieht. */
.pg-bar-track.is-empty { opacity: 0.4; }
.pg-bar-empty {
    margin-top: 8px;
    font-size: 0.72rem;
    font-style: italic;
    color: var(--color-ink-faint);
}

.pg-mini {
    width: 100%;
    border-collapse: collapse;
    margin-top: 15px;
    font-size: 0.82rem;
}
.pg-mini th {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--color-ink-faint);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    text-align: right;
    padding: 0 0 6px;
    border: 0;
}
.pg-mini th:first-child { text-align: left; }
.pg-mini th.is-key { color: var(--color-brick); }
.pg-mini td {
    text-align: right;
    padding: 5px 0;
    border-bottom: 1px solid var(--color-line-soft);
    font-variant-numeric: tabular-nums;
}
.pg-mini td:first-child { text-align: left; color: var(--color-ink-soft); }
.pg-mini tr:last-child td { border-bottom: 0; }
.pg-mini .is-key { color: var(--color-stud); font-weight: 700; }

.pg-meta { margin-top: 9px; font-size: 0.74rem; color: var(--color-ink-faint); line-height: 1.5; }
.pg-stamp { margin-top: 10px; font-size: 0.72rem; color: var(--color-ink-faint); }

.pg-legend {
    display: flex;
    gap: 7px;
    align-items: flex-start;
    margin: 16px 2px 0;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--color-ink-soft);
}
.pg-legend svg { flex-shrink: 0; margin-top: 2px; opacity: 0.65; }

.pg-history {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--color-line-soft);
}

/* ============================================================
   Mobile: Top-App-Bar + Off-Canvas-Navigation (M3 Navigation Drawer)
   ============================================================ */
@media (max-width: 880px) {
    /* Zwei Zeilen: App-Bar und <main> (die Schublade liegt fixed daneben).
       Ohne feste Zeilenaufteilung verteilte das Raster die Resthöhe aus
       min-height:100vh auf beide Zeilen - auf kurzen Seiten (Einstellungen,
       leere Listen) wurde die App-Bar dadurch mehrere hundert Pixel hoch. */
    .app-shell {
        grid-template-columns: 1fr;
        grid-template-rows: auto 1fr;
    }
    /* <main> ist Grid-Item von .app-shell. Ohne min-width:0 wächst die
       1fr-Spalte auf die *Mindestbreite ihres Inhalts* - eine breite
       Datentabelle dehnt damit die komplette Seite inklusive App-Bar über den
       Viewport hinaus, und das Handy scrollt horizontal. Gemessen vor diesem
       Fix: 1009px Dokumentbreite bei 390px Viewport (shipping.php), 15 von 19
       Seiten betroffen. Mit min-width:0 darf die Spalte schrumpfen, und der
       Überlauf landet dort, wo er hingehört: im scrollbaren .panel um die
       Tabelle. Bewusst nur mobil - auf dem Desktop bleibt alles unverändert.

       Gilt für alle Rasterkinder, nicht nur <main>: die App-Bar ist ebenfalls
       eines, und ihr Inhalt (Menüknopf, Marke, Seitentitel, zwei Aktionen)
       hat bei langen Titeln eine Mindestbreite über dem Viewport - sie zieht
       die gemeinsame Spalte sonst allein auf (order_detail.php: 436px). */
    .app-shell > * {
        min-width: 0;
    }
    .topbar {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 10px 12px;
        /* env(safe-area-inset-*) hält die Leiste auf Geräten mit Notch bzw.
           abgerundeten Ecken aus dem Sperrbereich; ohne Notch ist der Wert 0. */
        padding-top: calc(10px + env(safe-area-inset-top));
        padding-left: calc(12px + env(safe-area-inset-left));
        padding-right: calc(12px + env(safe-area-inset-right));
        background: var(--color-panel);
        border-bottom: 1px solid var(--color-line);
        position: sticky;
        top: 0;
        z-index: 90;
    }
    .topbar img {
        height: 26px;
    }
    .nav-toggle {
        display: inline-flex;
    }
    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        height: 100dvh;   /* die ein-/ausfahrende Adressleiste mit einrechnen */
        width: 272px;
        max-width: 84vw;
        padding-top: calc(24px + env(safe-area-inset-top));
        padding-bottom: calc(24px + env(safe-area-inset-bottom));
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        z-index: 100;
        box-shadow: var(--elevation-2);
        overscroll-behavior: contain;   /* kein Weiterscrollen der Seite dahinter */
    }
    .sidebar.open {
        transform: translateX(0);
    }
    .sidebar .brand {
        justify-content: space-between;
        gap: 12px;
    }
    .sidebar-close {
        display: inline-flex;
    }
    /* Fingerfreundliche Zeilenhöhe in der Schublade (M3: mindestens 48px). */
    .sidebar nav a {
        padding: 13px 16px;
        font-size: 0.95rem;
    }
    .sidebar-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,0.55);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease;
        z-index: 95;
    }
    .sidebar-backdrop.visible {
        opacity: 1;
        pointer-events: auto;
    }
    /* Seite hinter dem offenen Menü festhalten (gesetzt in layout_footer.php),
       sonst scrollt die Liste im Hintergrund mit. */
    body.nav-open {
        overflow: hidden;
    }
    main {
        padding: 20px 16px;
        padding-bottom: calc(28px + env(safe-area-inset-bottom));
        max-width: 100%;
    }
    .kpi-row {
        grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    }
    /* Raster mit fester Mindestspaltenbreite: die Spalte passt zwar noch in
       den Viewport, ihr Inhalt aber nicht - ohne min-width:0 wächst das
       Raster-Kind auf seine Mindestinhaltsbreite und schiebt die Seite
       seitlich hinaus (order_detail.php: 436px bei 390px Viewport). */
    .order-overview-row {
        grid-template-columns: minmax(0, 1fr);
    }
    .order-overview-row > *,
    .kpi-row > * {
        min-width: 0;
    }
}

/* Artikeltabelle (articles.php) mit festen Spaltenbreiten: Bei automatischem
   Tabellenlayout verteilte der Browser die Spalten mit jeder eintreffenden
   Zeile neu (gemessen: nach 5 Zeilen Name 239px, nach 50 Zeilen 221px) -
   kam die Seite stückweise an, zuckte die Tabelle mehrmals. Nur am Desktop,
   darunter wird sie ohnehin zur Karte.
   Eigene Klasse statt .articles-table: die teilen sich auch ebay_overview,
   ebay_articles_all, ebay_minifig_candidates und preis_hub_update mit ganz
   anderen Spalten - dort quetschten die Breiten z.B. den Angebotstitel
   auf 90px. */
@media (min-width: 761px) {
    /* min-width: die festen Spalten belegen ~770px, der Name bekommt nur den
       Rest - bei 1024px Fensterbreite waren das 0px. Darunter scrollt die
       Tabelle im .panel waagerecht, der Name behält mindestens ~240px. */
    .articles-table-fixed { table-layout: fixed; width: 100%; min-width: 1010px; }
    .articles-table-fixed th:nth-child(1) { width: 90px; }
    .articles-table-fixed th:nth-child(3) { width: 100px; }
    .articles-table-fixed th:nth-child(4) { width: 80px; }
    .articles-table-fixed th:nth-child(5) { width: 184px; }
    .articles-table-fixed th:nth-child(6) { width: 84px; }
    .articles-table-fixed th:nth-child(7) { width: 120px; }
    .articles-table-fixed th:nth-child(8) { width: 114px; }
    .articles-table-fixed td { overflow: hidden; text-overflow: ellipsis; }
    /* Neu/Gebraucht: beide Spalten 102px Inhalt - so breit wird das Badge
       mit Icon und dem breitesten ungeteilten Lagerort im Bestand
       ("CMFSHR-2"). Bei weniger Platz blieben dem Lagerort nur ein paar
       Pixel - schon "14-106" drückte früher das Icon zusammen. Mehrere
       Lagerorte brechen am "/" um.
       An der Naht zwischen den Spalten und rechts außen nur 6px statt 12px
       Innenabstand: die Badges stehen zentriert, der Leerraum daneben kam
       sonst doppelt dazu (gemessen 60px zwischen den Badges, jetzt ~32px).
       Dazu die Mindestbreite am Badge unten: ohne sie stand ein 53px-Badge
       ohne Lagerort ("0") mit fast 25px Leerraum je Seite in der Spalte.
       th bekommt dieselben Abstände, damit die Überschrift mittig über dem
       Badge bleibt. */
    .articles-table-fixed th:nth-child(7),
    .articles-table-fixed td:nth-child(7) { padding-right: 6px; }
    .articles-table-fixed th:nth-child(8),
    .articles-table-fixed td:nth-child(8) { padding-left: 6px; padding-right: 6px; }
    .articles-table-fixed .qty-location-badge { min-width: 82px; max-width: 100%; padding: 5px 12px 5px 8px; }
    /* Füllt den Platz neben dem Icon, damit die Zahl im verbreiterten Badge
       mittig steht statt links am Icon zu kleben. */
    .articles-table-fixed .qty-location-badge-text { flex: 1; }
    .articles-table-fixed .qty-location-badge-loc { white-space: normal; }
    .articles-table-fixed .qty-location-badge-loc > span { white-space: nowrap; }
    /* Sehr lange Farbnamen enden mit "…", der Tooltip am Link nennt sie ganz. */
    .articles-table-fixed .color-chip-link { display: inline-flex; max-width: 100%; }
    .articles-table-fixed .color-chip { max-width: 100%; min-width: 0; }
    .articles-table-fixed .color-chip-dot { flex: none; }
    .articles-table-fixed .color-chip-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
}

/* ============================================================
   Karten-Tabellen: eine Datenzeile wird auf schmalen Viewports zur
   gestapelten Karte statt zur seitwärts scrollenden Tabellenzeile.

   Angeschaltet wird das über die Klasse .table-cards am <table>. Die zweite
   Klasse .cards-ready setzt erst das Skript in includes/layout_footer.php,
   nachdem es die Spaltennamen als data-label an die Zellen gehängt und den
   Zellinhalt in .card-val verpackt hat. Ohne aktives JavaScript bleibt es
   damit bei der gewohnten (scrollbaren) Tabelle statt bei einer Karte aus
   unbeschrifteten Werten.

   Im <thead> steuern drei Klassen den Aufbau der Karte:
     th.card-media    - Bild-/Auswahlspalte, steht links oben in der Karte
     th.card-title    - Titelspalte, steht groß daneben, ohne Beschriftung
     th.card-nolabel  - Kopftext taugt nicht als Feldbeschriftung
     th.card-block    - Fließtext, Beschriftung darüber statt daneben
   ============================================================ */
@media (max-width: 760px) {
    table.table-cards.cards-ready,
    table.table-cards.cards-ready tbody {
        display: block;
        background: transparent;
        border-radius: 0;
        overflow: visible;
    }
    table.table-cards.cards-ready thead {
        display: none;
    }
    table.table-cards.cards-ready tbody tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        background: var(--color-table);
        border: 1px solid var(--color-outline-variant);
        border-radius: var(--radius);
        padding: 12px 14px;
        margin-bottom: 10px;
    }
    table.table-cards.cards-ready tbody tr:last-child {
        margin-bottom: 0;
    }
    /* Der Zeilen-Hover des Desktops färbte hier nur einzelne Felder der
       Karte ein statt der Zeile - in der Karte ergibt er keinen Sinn. */
    table.table-cards.cards-ready tr:hover td {
        background: transparent;
    }

    table.table-cards.cards-ready td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 6px 16px;
        grid-column: 1 / -1;
        /* Bild und Titel gehören an den Kartenkopf, unabhängig davon, an
           welcher Stelle ihre Spalte im Quelltext steht - bei Bestellungen
           ist die Bestell-Nr. z.B. erst die vierte. Die Rasterplatzierung
           folgt der von "order" geänderten Reihenfolge. */
        order: 2;
        min-width: 0;
        padding: 5px 0;
        border: none;
    }
    table.table-cards.cards-ready td.card-cell-media { order: 0; }
    table.table-cards.cards-ready td.card-cell-title { order: 1; }
    table.table-cards.cards-ready td::before {
        content: attr(data-label);
        flex: 0 1 auto;
        font-size: 0.72rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        line-height: 1.5;
        color: var(--color-ink-soft);
    }
    /* Spalten ohne Kopftext (Auswahlkästchen, Aktionsknöpfe) brauchen keine
       leere Beschriftungsspalte davor. */
    table.table-cards.cards-ready td[data-label=""]::before {
        display: none;
    }
    table.table-cards.cards-ready td[data-label=""] {
        justify-content: flex-start;
    }
    table.table-cards.cards-ready .card-val {
        display: block;
        /* Wächst über den Restplatz der Zeile, nicht nur über den eigenen
           Inhalt: sonst schrumpfen Eingabefelder mit width:100% (Gewicht auf
           shipping.php) auf ein paar Pixel zusammen. Kurze Textwerte bleiben
           trotzdem rechtsbündig am Zeilenende. */
        flex: 1 1 auto;
        min-width: 0;
        text-align: right;
        overflow-wrap: anywhere;
    }

    /* Versandprodukt-Zelle (shipping.php): zwei Auswahlmenüs mit je 190px
       Mindestbreite und der Absende-Knopf stehen in der Tabelle in einer
       Zeile ohne Umbruch. In der Karte sind dafür nur 300px da, und weil
       die Zeile rechtsbündig ausrichtet, schob sich das erste Menü nach
       links aus der Karte hinaus - unsichtbar, nicht scrollbar. */
    table.table-cards.cards-ready .shipping-product-row {
        flex-wrap: wrap;
    }
    table.table-cards.cards-ready .shipping-product-row .md3-dropdown,
    table.table-cards.cards-ready .shipping-product-row .md3-dropdown-trigger {
        width: 100%;
        min-width: 0;
    }

    /* Inline bearbeitbare Werte (article_edit.php) stehen in der Tabelle auf
       voller Spaltenbreite, damit das Eingabefeld beim Umschalten in den
       Bearbeiten-Modus die Spalte nicht sprengt. In der Karte trägt die
       Zeile die Beschriftung links, der Wert gehört ans rechte Ende. */
    table.table-cards.cards-ready td .field-editable {
        justify-content: flex-end;
    }

    /* Zellen ohne jeden Inhalt fallen ganz weg statt als leere Zeile mit
       Beschriftung stehen zu bleiben (Markierung vom Skript im Footer). */
    table.table-cards.cards-ready td.card-cell-empty {
        display: none;
    }

    /* Zellen mit Eingabefeld oder Auswahlmenü: Beschriftung darüber statt
       daneben, damit das Bedienelement die ganze Zeilenbreite bekommt
       (Versandprodukt-Dropdown auf shipping.php passte sonst nicht neben
       seine eigene Beschriftung). */
    table.table-cards.cards-ready td.card-cell-wide {
        display: block;
    }
    table.table-cards.cards-ready td.card-cell-wide::before {
        display: block;
        margin-bottom: 5px;
    }
    table.table-cards.cards-ready td.card-cell-wide .card-val {
        text-align: left;
    }
    /* Schmale Spezialfelder (z.B. das Gewichtsfeld, das in der Tabelle nur
       41px breit ist) sind als alleinstehende Zeile weder zu treffen noch zu
       lesen - hier bekommen sie eine fingergerechte Mindestgröße. */
    /* Nachträglich per JavaScript in eine Zelle gesetzte Bedienelemente
       (Inline-Bearbeitung auf colors.php) liegen neben .card-val statt darin
       und würden als Flex-Element mit width:100% auf wenige Pixel
       zusammenfallen. */
    table.table-cards.cards-ready td > input,
    table.table-cards.cards-ready td > select,
    table.table-cards.cards-ready td > textarea {
        flex: 1 1 auto;
        min-width: 110px;
        min-height: 40px;
    }
    table.table-cards.cards-ready td.card-cell-wide input[type="text"],
    table.table-cards.cards-ready td.card-cell-wide input[type="number"],
    table.table-cards.cards-ready td.card-cell-wide input[type="search"],
    table.table-cards.cards-ready td.card-cell-wide select,
    table.table-cards.cards-ready td.card-cell-wide textarea {
        min-width: 110px;
        min-height: 44px;
    }

    /* --- Kartenkopf: Bild links, Titel groß daneben ---
       column-gap bleibt 0, den Abstand trägt das Bild als padding-right: nur
       so läuft die Trennlinie unter dem Kartenkopf ohne Lücke durch. */
    table.table-cards.cards-ready tbody tr.has-card-media {
        grid-template-columns: auto minmax(0, 1fr);
        column-gap: 0;
    }
    /* !important: manche Bildspalten tragen für die Tabelle ein inline
       padding-right:0 (bundle_edit.php), in der Karte klebte der Titel
       dann direkt am Bild. */
    table.table-cards.cards-ready td.card-cell-media {
        padding-right: 14px !important;
    }
    table.table-cards.cards-ready td.card-cell-media {
        grid-column: 1;
        display: block;
        padding-top: 0;
    }
    table.table-cards.cards-ready tr.has-card-media td.card-cell-title {
        grid-column: 2;
    }
    table.table-cards.cards-ready td.card-cell-title {
        grid-column: 1 / -1;
        display: block;
        padding-top: 0;
    }
    table.table-cards.cards-ready td.card-cell-title .card-val {
        text-align: left;
        font-size: 1rem;
        font-weight: 700;
        line-height: 1.3;
        color: #ffffff;
    }
    /* Der Titel ist in manchen Listen ein .sku-Link (Bestell-Nr., Ankaufs-
       nummer) und brächte damit seine eigene, kleinere Schriftgröße mit -
       als Kartenüberschrift soll er die Größe der Karte tragen. Die Farbe
       bleibt dem Element überlassen, ein blauer Link darf blau bleiben. */
    table.table-cards.cards-ready td.card-cell-title .card-val > a,
    table.table-cards.cards-ready td.card-cell-title .card-val > span {
        font-size: inherit;
        font-weight: inherit;
    }
    table.table-cards.cards-ready td.card-cell-title .card-val > .sku {
        color: #ffffff;
    }
    /* Trennlinie unter dem Kartenkopf. Sie sitzt an Bild- und Titelzelle
       selbst - die im Quelltext folgende Zelle kann durch die
       Rasterplatzierung in einer ganz anderen Zeile landen. */
    table.table-cards.cards-ready td.card-cell-title,
    table.table-cards.cards-ready tr.has-card-media td.card-cell-media {
        padding-bottom: 10px;
        margin-bottom: 8px;
        border-bottom: 1px solid var(--color-line-soft);
    }

    /* Zeilen, die sich über mehrere Spalten ziehen (Gruppenköpfe, Summen-
       oder Hinweiszeilen), passen nicht ins Kartenraster und bleiben
       schlichte Blöcke ohne Rahmen. Markiert vom Skript im Footer. */
    table.table-cards.cards-ready tbody tr.card-plain {
        display: block;
        background: transparent;
        border: none;
        padding: 6px 2px;
        margin-bottom: 0;
    }
    table.table-cards.cards-ready tbody tr.card-plain td {
        display: block;
        padding: 4px 0;
    }
    table.table-cards.cards-ready tbody tr.card-plain td::before {
        display: none;
    }

    /* Jede Karte bringt ihren eigenen Rahmen mit - das Panel darum darf
       schmaler polstern, sonst liegen zwei Rahmen dicht ineinander. */
    .panel:has(> table.table-cards.cards-ready),
    .panel:has(> form > table.table-cards.cards-ready) {
        padding: 12px;
    }
}

/* ============================================================
   Schmale Viewports: Touch-Flächen, umbrechende Leisten, Schriftgrößen
   ============================================================ */
@media (max-width: 600px) {
    main { padding: 16px 12px; }
    h1 { font-size: 1.35rem; }
    .panel { padding: 16px; }
    /* Kennzahlen stehen zu zweit nebeneinander. Mit 1.7rem und 20px
       Polster rutschte bei Beträgen das Euro-Zeichen allein in die nächste
       Zeile (Lagerwert "29.295,81 €" auf statistik.php). */
    .kpi-row { gap: 12px; margin-bottom: 24px; }
    .kpi-row .kpi-card { padding: 14px 16px; }
    .kpi-row .kpi-card .value { font-size: 1.3rem; }
    table { font-size: 0.82rem; }
    th, td { padding: 8px; }
    .detail-row { grid-template-columns: 1fr; gap: 2px; }
    /* Pickmodus: eigener Mobil-Block bei .pick-walk-card (max-width: 880px). */

    /* Überschrift und die Aktion daneben ("+ Neuer Artikel") stehen sonst
       zwangsweise in einer Zeile und quetschen sich gegenseitig. */
    .flex-between {
        flex-wrap: wrap;
        gap: 10px 12px;
    }

    /* Tabellen, die keine Karten sind, scrollen innerhalb ihres Panels. Dass
       dort etwas zu holen ist, verrät der Rand: die beiden äußeren
       Deckflächen scrollen mit dem Inhalt weg (background-attachment: local)
       und geben den darunterliegenden Schatten frei, sobald links oder
       rechts noch etwas kommt. */
    .panel {
        background-image:
            linear-gradient(to right, var(--color-panel) 40%, rgba(30,30,32,0)),
            linear-gradient(to left,  var(--color-panel) 40%, rgba(30,30,32,0)),
            linear-gradient(to right, rgba(0,0,0,0.45), rgba(0,0,0,0)),
            linear-gradient(to left,  rgba(0,0,0,0.45), rgba(0,0,0,0));
        background-position: 0 0, 100% 0, 0 0, 100% 0;
        background-repeat: no-repeat;
        background-size: 36px 100%, 36px 100%, 14px 100%, 14px 100%;
        background-attachment: local, local, scroll, scroll;
    }

    /* Die Reiterleiste der Einstellungen ist hier breiter als der Bildschirm
       und scrollt seitwärts. Denselben Rand wie am Panel oben: die weiche
       Kante verrät, dass links oder rechts noch Reiter stehen. */
    .settings-tabs {
        background-image:
            linear-gradient(to right, var(--color-bg) 30%, rgba(19,19,19,0)),
            linear-gradient(to left,  var(--color-bg) 30%, rgba(19,19,19,0)),
            linear-gradient(to right, rgba(0,0,0,0.5), rgba(0,0,0,0)),
            linear-gradient(to left,  rgba(0,0,0,0.5), rgba(0,0,0,0));
        background-position: 0 0, 100% 0, 0 0, 100% 0;
        background-repeat: no-repeat;
        background-size: 28px 100%, 28px 100%, 12px 100%, 12px 100%;
        background-attachment: local, local, scroll, scroll;
    }

    /* --- Eingaben --- iOS zoomt beim Antippen in jedes Feld unter 16px
       hinein und findet danach nicht von selbst zurück. 16px ist die
       Schwelle, ab der Safari das lässt. */
    input, select, textarea,
    .search-field input,
    .filter-bar select {
        font-size: 16px;
    }

    /* --- Filterleisten --- Die Felder tragen ihre Desktop-Breiten als
       inline-style (flex: 0 0 130px o. ä.) direkt am Element. Deshalb hier
       ausnahmsweise !important - anders lässt sich die einzeilige
       Desktop-Filterleiste auf dem Handy nicht umbrechen. Zwei Felder je
       Zeile, Suchfeld und Absende-Knopf über die volle Breite. */
    .filter-bar > * {
        flex: 1 1 calc(50% - 5px) !important;
        min-width: 0 !important;
    }
    .filter-bar > *:has(.search-field),
    .filter-bar > *:has(.tag-input-wrap),
    .filter-bar > *:last-child {
        flex-basis: 100% !important;
    }
    .filter-bar .btn {
        width: 100%;
        justify-content: center;
    }
    /* Knopfgruppen innerhalb der Leiste (Offen/Versendet auf shipping.php)
       teilen sich die Zeile, statt als volle Balken untereinander zu stehen. */
    .filter-bar > div > .btn {
        width: auto;
        flex: 1 1 auto;
    }
    /* Die Mehrfachauswahl (Farbe auf articles.php) trägt ihre Höhe als
       inline-style (height:42px) und zeigt damit nicht einmal zwei Einträge
       ganz - auf dem Handy ist das weder les- noch treffbar. */
    .filter-bar select[multiple] {
        height: 108px !important;
    }

    /* --- Knöpfe --- 44px ist die kleinste Fläche, die sich mit dem Daumen
       zuverlässig treffen lässt (Apple HIG / Material). */
    .btn {
        min-height: 44px;
        padding: 10px 18px;
    }
    .btn-sm {
        min-height: 38px;
        padding: 8px 14px;
    }
    .btn-icon, .btn-circle {
        min-height: 0;
    }
    /* Das Polster von .btn oben gilt auch für runde Symbolknöpfe - bei 34px
       Breite blieben für das Icon 0px, übrig war ein leerer Kreis
       (buchhaltung_uebersicht.php, Erneut prüfen). */
    .btn-circle {
        width: 40px;
        height: 40px;
        padding: 0;
    }
    .toolbar .btn {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* --- Blätterleiste --- mittig statt auseinandergezogen, größere Ziele. */
    .pagination {
        justify-content: center;
        gap: 10px;
    }
    .pagination-info {
        flex: 1 1 100%;
        text-align: center;
    }
    .pagination-btn,
    .pagination-ellipsis {
        min-width: 40px;
        height: 40px;
    }

    /* --- Auswahlmenü in der Filterleiste --- Der MD3-Trigger bringt eine
       Mindestbreite von 190px mit. In einer halbbreiten Filterspalte (156px)
       tritt er damit seitlich aus der Leiste heraus, und die Leiste selbst
       wird scrollbar (gemessen auf orders.php: 323px sichtbar, 356px breit). */
    .filter-bar .md3-dropdown,
    .filter-bar .md3-dropdown-trigger {
        width: 100%;
        min-width: 0;
    }

    /* --- Feldreihen --- Mehrere Formularseiten schreiben ihre Spaltenzahl
       als inline-style ans Element (grid-template-columns: 1fr 1fr 1fr).
       Bei 323px Inhaltsbreite blieben davon 97px je Feld, und Felder mit
       eigener Mindestbreite schoben die Reihe seitlich hinaus
       (ebay_listing_edit.php: 596px in einer 323px breiten Spalte).
       Auf dem Handy steht jedes Feld für sich - deshalb !important, gegen
       den inline-style kommt man sonst nicht an. */
    .field-row {
        grid-template-columns: minmax(0, 1fr) !important;
    }
    .field-row > * {
        min-width: 0;
    }

    /* --- Mehrspaltige Inhaltsraster --- Gleiches Muster wie oben: Die
       Spaltenzahl steht als inline-style am Element (statistik.php,
       ebay_overview.php, bricklink_bulk_update.php). Zwei bis drei Spalten
       auf 323px hießen 150px bzw. 97px je Spalte - untereinander ist das
       lesbar, nebeneinander nicht. */
    .split-cols {
        grid-template-columns: minmax(0, 1fr) !important;
        gap: 20px !important;
    }
    .split-cols > * {
        min-width: 0;
    }

    /* Gruppen innerhalb einer Filterleiste (Knopfpaare, Trefferzahl neben
       Aktionen) sind selbst Flex-Zeilen ohne Umbruch und traten dadurch
       seitlich aus der Leiste heraus (ebay_articles_all.php: 420px in einer
       331px breiten Leiste). */
    .filter-bar > * {
        flex-wrap: wrap;
    }
    /* Die Felder einer umgebrochenen Zeile richten sich oben aus. Die
       Mehrfachauswahl (Farbe auf articles.php) ist dreimal so hoch wie ein
       Auswahlmenü und zog das Feld neben sich sonst an ihren unteren Rand -
       zwischen Beschriftung und Feld klaffte eine Lücke. Die Leisten tragen
       ihr align-items als inline-style, daher !important. */
    .filter-bar {
        align-items: flex-start !important;
    }

    /* --- Eingeklappte Filterleiste --- Sichtbar bleiben nur die Elemente
       mit .filter-keep: das Suchfeld und der Klappknopf selbst. Beide
       vergibt das Skript in includes/layout_footer.php. */
    .filter-collapsible.filters-collapsed > *:not(.filter-keep) {
        display: none;
    }
    .filter-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        /* eigene Zeile: die halbbreiten Filterspalten daneben würden den
           Knopf sonst als "auch nur ein Feld" erscheinen lassen. */
        flex: 1 1 100% !important;
        width: 100%;
        min-height: 44px;
        padding: 10px 18px;
        border: 1px solid var(--color-line);
        border-radius: var(--radius-pill);
        background: none;
        color: var(--color-ink);
        font-family: inherit;
        font-size: 0.9rem;
        font-weight: 600;
        cursor: pointer;
    }
    .filter-count {
        min-width: 22px;
        padding: 0 7px;
        border-radius: var(--radius-pill);
        background: var(--color-primary-container);
        color: var(--color-on-primary-container);
        font-size: 0.75rem;
        line-height: 22px;
    }
    .filter-chevron {
        color: var(--color-ink-soft);
        transition: transform 0.2s;
    }
    .filters-collapsed .filter-chevron {
        transform: rotate(-90deg);
    }
}

/* ============================================================
   Sync-Dashboard (sync_dashboard.php) – eigenständiges Redesign.
   Alles unter .sync2 gekapselt, damit die generischen Namen
   (.card, .stat, .grid, .tab, .dot, .err, .muted …) nicht mit dem
   globalen Stylesheet kollidieren. Farben/Radien kommen aus :root,
   Buttons aus der globalen .btn-Familie (+ .btn-warn hier ergänzt).
   ============================================================ */
/* <main> ist ein Grid-Item in .app-shell; ohne min-width:0 wächst die
   1fr-Spalte auf die Mindest-Inhaltsbreite und die Seite scrollt auf
   schmalen Viewports horizontal. Nur auf dieser Seite entschärfen. */
main:has(> .sync2) { min-width: 0; }

/* --- Unternavigation Bereich Synchronisation (includes/sync_subnav.php) ---
   Bewusst als Unterstrich-Leiste statt Pill-Tabs, damit sie sich auf dem
   Sync-Dashboard klar von den Tabs Übersicht/Warteschlange/... darunter
   abhebt. Scrollt auf schmalen Viewports in sich selbst. Steht auf allen
   vier Seiten innerhalb von .sync2 - das min-width:0 oben reicht also. */
.subnav { display: flex; gap: 4px; margin: 0 0 22px; border-bottom: 1px solid var(--color-line-soft); overflow-x: auto; scrollbar-width: none; }
.subnav::-webkit-scrollbar { display: none; }
.subnav__link { display: inline-flex; align-items: center; gap: 8px; padding: 10px 14px 11px; margin-bottom: -1px; border-bottom: 2px solid transparent; color: var(--color-ink-soft); font-size: 0.88rem; font-weight: 600; text-decoration: none; white-space: nowrap; transition: color 0.15s, border-color 0.15s; }
.subnav__link svg { width: 16px; height: 16px; flex: 0 0 auto; opacity: 0.8; }
.subnav__link:hover { color: var(--color-ink); }
.subnav__link.is-active { color: #fff; border-bottom-color: var(--color-brick); }
.subnav__link.is-active svg { opacity: 1; color: var(--color-brick); }
.subnav__link:focus-visible { outline: 2px solid var(--color-brick); outline-offset: -2px; border-radius: 4px; }

.sync2 { --ctl-h: 48px; min-width: 0; }
.sync2 :focus-visible { outline: 2px solid var(--color-brick); outline-offset: 2px; }

/* --- Seitenkopf mit Aktionsleiste --- */
.sync2 .pagehead { display: flex; align-items: center; justify-content: space-between; gap: 18px 24px; flex-wrap: wrap; margin-bottom: 20px; }
.sync2 .page-h1 { font-size: 1.55rem; font-weight: 700; color: #fff; margin: 0; text-wrap: balance; }
.sync2 .pagehead__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.sync2 .mode-switch { display: inline-flex; align-items: center; gap: 11px; height: var(--ctl-h); padding: 0 8px 0 16px; margin: 0; border-radius: var(--radius-pill); background: var(--color-panel-raised); border: 1px solid var(--color-outline-variant); user-select: none; }
.sync2 .mode-switch__state { font-size: 0.8rem; font-weight: 700; color: var(--color-danger); min-width: 72px; text-align: right; }
.sync2 .mode-switch.is-test .mode-switch__state { color: var(--color-warn); }
.sync2 .mode-switch__btn { appearance: none; border: none; background: transparent; padding: 6px; margin: 0; cursor: pointer; display: inline-flex; }
.sync2 .mode-switch__btn:focus-visible { outline: none; }
.sync2 .mode-switch__track { position: relative; display: block; width: 42px; height: 22px; flex: 0 0 auto; border-radius: var(--radius-pill); background: rgba(240, 98, 94, 0.35); transition: background 0.15s; }
.sync2 .mode-switch.is-test .mode-switch__track { background: rgba(224, 168, 62, 0.32); }
.sync2 .mode-switch__btn:focus-visible .mode-switch__track { outline: 2px solid var(--color-brick); outline-offset: 3px; }
.sync2 .mode-switch__thumb { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--color-danger); transform: translateX(20px); transition: transform 0.15s, background 0.15s; }
.sync2 .mode-switch.is-test .mode-switch__thumb { background: var(--color-warn); transform: translateX(0); }

.sync2 .actiongroup { display: flex; align-items: center; gap: 4px; height: var(--ctl-h); padding: 4px; border-radius: var(--radius-pill); background: var(--color-panel-raised); border: 1px solid var(--color-outline-variant); }
.sync2 .actiongroup form { display: contents; }
.sync2 .actiongroup .btn-primary { height: 40px; padding: 0 18px; box-shadow: none; }
.sync2 .icon-btn { width: 40px; height: 40px; border: none; border-radius: 50%; background: transparent; color: var(--color-ink-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.sync2 .icon-btn:hover { background: var(--state-hover); color: var(--color-brick); }
.sync2 .icon-btn:disabled { opacity: 0.38; cursor: default; background: transparent; color: var(--color-ink-soft); }
/* Symbolleiste rechts im Status-Hinweis eines Reiters (Stammdaten) */
.sync2 .sync-callout > .actiongroup { flex: 0 0 auto; background: var(--color-panel); border-color: var(--color-line); box-shadow: var(--elevation-1); }
.sync2 .sync-callout > .actiongroup .icon-btn { color: var(--color-ink); }
.sync2 .sync-callout > .actiongroup .icon-btn:hover { color: var(--color-brick); }
.sync2 .sync-callout > .actiongroup .icon-btn:disabled { color: var(--color-ink-soft); }
.sync2 .enrichment-more { margin: 12px 0 0; }
.sync2 .enrichment-status .badge { white-space: nowrap; }

/* --- Karten --- */
.sync2 .card { background: var(--color-panel); border: 1px solid var(--color-outline-variant); border-radius: var(--radius); padding: 22px; box-shadow: var(--elevation-1); }

/* --- Sync-Status-Block --- */
.sync2 .health { padding: 22px 24px; display: flex; flex-direction: column; gap: 18px; }
.sync2 .eyebrow { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-ink-soft); font-weight: 700; }
/* Gleicher Puls wie der Sync-Punkt oben in der Leiste (.tb-sync-dot,
   Keyframes tb-sync-pulse): Ring als ::after, wächst und blendet aus. */
.sync2 .pulse-dot { position: relative; width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto; color: var(--color-warn); background: currentColor; }
.sync2 .pulse-dot::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: currentColor; animation: tb-sync-pulse 2.4s ease-out infinite; }
.sync2 .sync-callout.is-danger .pulse-dot { color: var(--color-danger); }
.sync2 .sync-callout.is-danger .pulse-dot::after { animation-duration: 1.4s; }
.sync2 .sync-callout.is-ok .pulse-dot { color: var(--color-ok); }

.sync2 .sync-callout { display: flex; align-items: center; gap: 12px 14px; flex-wrap: wrap; padding: 12px 16px; border-radius: var(--radius); background: rgba(224, 168, 62, 0.10); border: 1px solid rgba(224, 168, 62, 0.30); }
.sync2 .sync-callout.is-danger { background: rgba(240, 98, 94, 0.10); border-color: rgba(240, 98, 94, 0.30); }
.sync2 .sync-callout.is-ok { background: rgba(63, 196, 136, 0.10); border-color: rgba(63, 196, 136, 0.30); }
.sync2 .sync-callout__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.sync2 .sync-callout__text strong { font-size: 1.05rem; font-weight: 700; color: #fff; }
.sync2 .sync-callout .btn { flex: 0 0 auto; }

.sync2 .health__stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; }
.sync2 .stat { background: var(--color-panel-raised); border-radius: var(--radius); padding: 12px 16px; display: flex; flex-direction: column; gap: 3px; }
.sync2 .stat__label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-ink-soft); font-weight: 600; }
.sync2 .stat__value { font-size: 1.2rem; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.sync2 .stat__value--count { letter-spacing: 0.01em; }
.sync2 .stat__sub { font-size: 0.74rem; color: var(--color-ink-soft); }
.sync2 .stat__sub.is-warn { color: var(--color-warn); }
.sync2 .stat__sub.is-danger { color: var(--color-danger); }
.sync2 .stat__sub.is-ok { color: var(--color-ok); }

/* 24-Stunden-Leiste: 96 Balken à 15 Min. Farbe = schlechtester Zustand im Slot.
   OK bleibt bewusst gedämpft, damit Warnung/Fehler aus der grünen Fläche springen. */
.sync2 .runstrip { --rs-skip: #5b7fa6; display: flex; flex-direction: column; align-items: stretch; gap: 10px; padding-top: 16px; border-top: 1px solid var(--color-line-soft); }
.sync2 .runstrip__head { display: flex; align-items: baseline; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap; }
.sync2 .runstrip__label { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-ink-soft); font-weight: 600; }
.sync2 .runstrip__summary { font-size: 0.78rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
.sync2 .runstrip__summary b { font-weight: 600; }
.sync2 .runstrip__summary .is-ok { color: var(--color-ok); }
.sync2 .runstrip__summary .is-warn { color: var(--color-warn); }
.sync2 .runstrip__summary .is-err { color: var(--color-danger); }
.sync2 .runstrip__plot { position: relative; }
.sync2 .runstrip__bars { display: flex; align-items: flex-end; gap: 2px; height: 44px; width: 100%; cursor: default; }
.sync2 .runstrip__bars i { flex: 1 1 0; min-width: 0; height: 100%; border-radius: 2px; background: var(--color-line); transition: opacity 0.12s, transform 0.12s; transform-origin: bottom; }
.sync2 .runstrip__bars i.ok   { background: var(--color-ok); opacity: 0.55; }
.sync2 .runstrip__bars i.warn { background: var(--color-warn); }
.sync2 .runstrip__bars i.err  { background: var(--color-danger); }
.sync2 .runstrip__bars i.skip { background: var(--rs-skip); height: 60%; }
.sync2 .runstrip__bars i.gap  { height: 30%; background: repeating-linear-gradient(135deg, var(--color-ink-faint) 0 2px, transparent 2px 4px); opacity: 0.8; }
.sync2 .runstrip__bars i.none { height: 12%; opacity: 0.6; }
.sync2 .runstrip__bars i.is-now { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35); }
.sync2 .runstrip__bars:hover i:not(.is-hover) { opacity: 0.4; }
.sync2 .runstrip__bars:hover i.ok:not(.is-hover) { opacity: 0.3; }
.sync2 .runstrip__bars i.is-hover { opacity: 1; transform: scaleY(1.08); }
/* API-Ausfälle: eigenes Band unter den Balken, gleiche Spalten */
.sync2 .runstrip__api { display: flex; gap: 2px; height: 6px; margin-top: 4px; }
.sync2 .runstrip__api i { flex: 1 1 0; min-width: 0; border-radius: 1px; background: var(--color-line-soft); }
.sync2 .runstrip__api i.down { background: var(--color-danger); }
.sync2 .runstrip__axis { position: relative; height: 16px; margin-top: 6px; font-size: 0.66rem; color: var(--color-ink-faint); font-variant-numeric: tabular-nums; }
.sync2 .runstrip__axis span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.sync2 .runstrip__axis span:first-child { transform: none; }
.sync2 .runstrip__axis span.is-end { left: auto; right: 0; transform: none; color: var(--color-ink-soft); }
.sync2 .runstrip__axis span::before { content: ""; position: absolute; left: 50%; top: -5px; width: 1px; height: 3px; background: var(--color-line); }
.sync2 .runstrip__axis span:first-child::before, .sync2 .runstrip__axis span.is-end::before { display: none; }
.sync2 .runstrip__tip { position: absolute; bottom: calc(100% + 8px); z-index: 20; width: max-content; max-width: min(340px, 100%); padding: 10px 12px; border-radius: var(--radius); background: var(--color-surface-container-high); border: 1px solid var(--color-line); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45); font-size: 0.76rem; color: var(--color-ink-soft); pointer-events: none; }
.sync2 .runstrip__tip-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.sync2 .runstrip__tip-head strong { color: var(--color-ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.sync2 .runstrip__tip-head span:last-child { margin-left: auto; padding-left: 12px; }
.sync2 .runstrip__tip .dot { width: 8px; height: 8px; border-radius: 2px; background: var(--color-line); }
.sync2 .runstrip__tip .dot.ok { background: var(--color-ok); }
.sync2 .runstrip__tip .dot.warn { background: var(--color-warn); }
.sync2 .runstrip__tip .dot.err { background: var(--color-danger); }
.sync2 .runstrip__tip .dot.skip { background: var(--rs-skip); }
.sync2 .runstrip__tip .dot.gap { background: var(--color-ink-faint); }
.sync2 .runstrip__tip-row { line-height: 1.5; }
.sync2 .runstrip__tip .is-warn { color: var(--color-warn); font-weight: 600; }
.sync2 .runstrip__tip ul { list-style: none; margin: 6px 0 0; padding: 6px 0 0; border-top: 1px solid var(--color-line); display: grid; gap: 3px; }
.sync2 .runstrip__tip li { padding-left: 10px; border-left: 2px solid var(--color-warn); line-height: 1.4; }
.sync2 .runstrip__tip li.warn { color: var(--color-warn); }
.sync2 .runstrip__tip li.err { border-left-color: var(--color-danger); color: var(--color-danger); }
.sync2 .runstrip__tip li.more { border-left-color: transparent; color: var(--color-ink-faint); }
.sync2 .runstrip__tip li b { color: var(--color-ink); font-variant-numeric: tabular-nums; }
.sync2 .runstrip__legend { display: flex; gap: 6px 16px; flex-wrap: wrap; font-size: 0.72rem; color: var(--color-ink-soft); }
.sync2 .runstrip__legend span { display: inline-flex; align-items: center; gap: 6px; }
.sync2 .runstrip__legend span::before { content: ""; width: 9px; height: 9px; border-radius: 2px; background: var(--color-ok); flex: 0 0 auto; }
.sync2 .runstrip__legend span.ok::before { opacity: 0.55; }
.sync2 .runstrip__legend span.warn::before { background: var(--color-warn); }
.sync2 .runstrip__legend span.err::before { background: var(--color-danger); }
.sync2 .runstrip__legend span.skip::before { background: var(--rs-skip); }
.sync2 .runstrip__legend span.gap::before { background: repeating-linear-gradient(135deg, var(--color-ink-faint) 0 2px, transparent 2px 4px); }
.sync2 .runstrip__legend span.api::before { height: 4px; border-radius: 1px; background: var(--color-danger); }
.sync2 .runstrip__tip-row.is-err { color: var(--color-danger); font-weight: 600; }
.sync2 .runstrip__legend b { font-weight: 700; color: var(--color-ink); font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
    .sync2 .runstrip__bars { gap: 1px; height: 36px; }
    .sync2 .runstrip__axis span:first-child { display: none; }
}

/* --- Segmentierte Tabs --- */
.sync2 .tabs { display: inline-flex; gap: 4px; padding: 5px; margin: 24px 0 22px; max-width: 100%; border-radius: var(--radius-pill); background: var(--color-panel-raised); border: 1px solid var(--color-outline-variant); overflow-x: auto; scrollbar-width: none; }
.sync2 .tabs::-webkit-scrollbar { display: none; }
.sync2 .tab { appearance: none; background: transparent; border: none; color: var(--color-ink-soft); font: inherit; font-size: 0.85rem; font-weight: 600; height: 38px; padding: 0 15px; border-radius: var(--radius-pill); white-space: nowrap; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; transition: background 0.15s, color 0.15s; }
.sync2 .tab svg { width: 15px; height: 15px; flex: 0 0 auto; opacity: 0.85; }
.sync2 .tab:hover { color: var(--color-ink); background: var(--state-hover); }
.sync2 .tab.is-active { background: var(--color-panel); color: #fff; box-shadow: var(--elevation-1); }
.sync2 .tab.is-active svg { opacity: 1; color: var(--color-brick); }
.sync2 .tab__count { display: inline-flex; align-items: center; justify-content: center; min-width: 19px; height: 19px; padding: 0 6px; border-radius: var(--radius-pill); background: var(--color-panel); color: var(--color-ink-soft); font-size: 0.7rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.sync2 .tab.is-active .tab__count { background: var(--color-panel-raised); color: var(--color-ink); }
.sync2 .tab__count--alert { background: rgba(224, 168, 62, 0.18); color: var(--color-warn); }

.sync2 .tabpanel { display: none; }
.sync2 .tabpanel.is-active { display: block; animation: sync2-fade 0.2s ease; }
.sync2 .section-label { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-ink-soft); font-weight: 700; margin: 0 0 12px; }
.sync2 .card h3 { font-size: 1.05rem; color: #fff; margin: 0 0 6px; }

/* --- Ergänzungen für die Unterseiten des Bereichs (BrickLink, BrickOwl,
   Bestandsabgleich) - dort stehen Karten untereinander statt in Tabs --- */
.sync2 .card + .card { margin-top: 16px; }
.sync2 .sync-callout form { margin: 0; }
.sync2 .chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px 24px; }
.sync2 .chart-box { position: relative; height: 220px; }
.sync2 .inline-form { display: flex; align-items: center; gap: 6px; margin: 0; }
.sync2 .mini-input { width: 120px; height: 34px; padding: 0 12px; border: 1px solid var(--color-line); border-radius: var(--radius-pill); background: var(--color-panel-raised); color: var(--color-ink); font: inherit; font-size: 0.8rem; }
.sync2 .link-list { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 0.82rem; }
.sync2 .cell-sub { display: block; font-size: 0.76rem; color: var(--color-ink-soft); }
.sync2 .lot-lines { font-size: 0.82rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sync2 .lot-lines div + div { margin-top: 3px; }
.sync2 .badge-stack { display: flex; flex-wrap: wrap; gap: 4px; }
/* Begründungen sind ganze Sätze - in Versalien liefen sie über drei Zeilen */
.sync2 .badge-stack .badge { text-transform: none; letter-spacing: normal; font-size: 0.74rem; font-weight: 600; line-height: 1.35; padding: 3px 9px; }
.sync2 .hint { color: var(--color-ink-soft); font-size: 0.8rem; margin: 0 0 14px; }
.sync2 .subsection + .subsection { margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--color-line-soft); }
.sync2 .row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }

/* --- Panel-Kopf mit Zähler + Filter-Chips --- */
.sync2 .panelhead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; margin-bottom: 12px; }
.sync2 .panelhead__title { display: flex; align-items: center; gap: 10px; }
.sync2 .panelhead__title h3 { margin: 0; }
.sync2 .panelhead__controls { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0; }
.sync2 .count-pill { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 8px; border-radius: var(--radius-pill); background: var(--color-panel-raised); color: var(--color-ink-soft); font-size: 0.74rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.sync2 .count-pill--alert { background: rgba(224, 168, 62, 0.16); color: var(--color-warn); }
.sync2 .filter-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.sync2 .chip-btn { appearance: none; border: 1px solid var(--color-line); background: var(--color-panel-raised); color: var(--color-ink-soft); font: inherit; font-size: 0.78rem; font-weight: 600; padding: 5px 12px; border-radius: var(--radius-pill); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.sync2 .chip-btn:hover { border-color: var(--color-brick); color: var(--color-ink); }
.sync2 .chip-btn.is-active { background: var(--color-brick); border-color: var(--color-brick); color: #04141f; }
.sync2 .chip-btn__n { opacity: 0.7; font-variant-numeric: tabular-nums; }

.sync2 .pchip { display: inline-flex; align-items: center; gap: 6px; font-size: 0.82rem; font-weight: 600; color: var(--color-ink); white-space: nowrap; }
.sync2 .pchip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--color-ink-faint); flex: 0 0 auto; }
.sync2 .pchip-dot.bl { background: #39a6fe; }
.sync2 .pchip-dot.bo { background: #3fc488; }
.sync2 .pchip-dot.eb { background: #e0a83e; }
.sync2 .pchip-dot.bb { background: #8b7ee8; }

.sync2 .prio { display: inline-flex; align-items: center; font-size: 0.72rem; font-weight: 700; padding: 2px 9px; border-radius: var(--radius-pill); text-transform: uppercase; letter-spacing: 0.02em; }
.sync2 .prio--order { background: rgba(240, 98, 94, 0.16); color: var(--color-danger); }
.sync2 .prio--normal { color: var(--color-ink-faint); font-weight: 600; }

/* --- Problem-Karten --- */
.sync2 .issue-list { display: flex; flex-direction: column; gap: 10px; }
.sync2 .issue-card { display: flex; gap: 14px; align-items: flex-start; background: var(--color-panel-raised); border: 1px solid var(--color-outline-variant); border-radius: var(--radius-sm); padding: 13px 16px; }
.sync2 .issue-card--danger { background: rgba(240, 98, 94, 0.08); border-color: rgba(240, 98, 94, 0.28); }
.sync2 .issue-card--warn { background: rgba(224, 168, 62, 0.08); border-color: rgba(224, 168, 62, 0.28); }
.sync2 .issue-card__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.sync2 .issue-card__top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sync2 .issue-card__name { font-weight: 700; color: #fff; text-decoration: none; }
.sync2 .issue-card__name:hover { color: var(--color-brick); }
.sync2 .issue-card__tag { font-size: 0.71rem; color: var(--color-ink-soft); background: var(--color-panel); padding: 2px 8px; border-radius: var(--radius-pill); }
.sync2 .issue-card__err { font-size: 0.82rem; color: var(--color-danger); background: rgba(240, 98, 94, 0.16); border-radius: var(--radius-sm); padding: 7px 11px; word-break: break-word; }
.sync2 .issue-card__desc { font-size: 0.85rem; color: var(--color-ink-soft); }
.sync2 .issue-card__actions { display: flex; gap: 6px; flex: 0 0 auto; align-items: center; flex-wrap: wrap; justify-content: flex-end; }

/* --- Badges (Doppelstrich-Variante, lässt die globale .badge-Familie unberührt) --- */
.sync2 .badge { display: inline-block; padding: 2px 9px; border-radius: var(--radius-pill); font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; }
.sync2 .badge--ok { background: rgba(63, 196, 136, 0.16); color: var(--color-ok); }
.sync2 .badge--warn { background: rgba(224, 168, 62, 0.16); color: var(--color-warn); }
.sync2 .badge--crit { background: rgba(240, 98, 94, 0.16); color: var(--color-danger); }
.sync2 .badge--info { background: rgba(57, 166, 254, 0.16); color: #7fc4ff; }
.sync2 .badge--new { background: rgba(63, 196, 136, 0.16); color: var(--color-ok); }
.sync2 .badge--used { background: rgba(224, 168, 62, 0.16); color: var(--color-warn); }

/* --- .btn-warn ergänzt die globale Button-Familie --- */
.sync2 .btn-warn { color: var(--color-warn); border-color: rgba(224, 168, 62, 0.45); background: rgba(224, 168, 62, 0.06); }
.sync2 .btn-warn:hover { background: rgba(224, 168, 62, 0.16); border-color: var(--color-warn); }

/* --- Plattform-Board --- */
.sync2 .platform-board { display: grid; grid-template-columns: repeat(auto-fit, minmax(244px, 1fr)); gap: 16px; }

.sync2 .pcard { background: var(--color-panel); border: 1px solid var(--color-outline-variant); border-radius: var(--radius); padding: 16px 18px; display: flex; flex-direction: column; gap: 14px; box-shadow: var(--elevation-1); }
.sync2 .pcard--attn { background: rgba(240, 98, 94, 0.07); border-color: rgba(240, 98, 94, 0.28); }
/* .pcard heißt auch die Farbkachel auf colors.php (anklickbar, hebt sich beim
   Hover an, overflow:hidden). Das hier ist nur eine Anzeige: nichts davon
   übernehmen - overflow muss sichtbar sein, sonst schneidet die Karte den
   Tooltip am Status-Punkt ab. */
.sync2 .pcard { overflow: visible; cursor: default; transition: none; }
.sync2 .pcard:hover { transform: none; border-color: var(--color-outline-variant); box-shadow: var(--elevation-1); }
.sync2 .pcard--attn:hover { border-color: rgba(240, 98, 94, 0.28); }
.sync2 .pcard__head { display: flex; align-items: center; gap: 12px; }
/* Status-Punkt mit Tooltip (Verbunden / Nicht konfiguriert). Eigener Träger,
   weil ::after des Punkts schon der Puls-Ring ist. */
.sync2 .pcard__status { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; flex: 0 0 auto; outline: none; }
.sync2 .pcard__name { font-weight: 700; color: #fff; }
.sync2 .pcard__stats { display: flex; gap: 8px; }
.sync2 .pcard__stats > div { flex: 1; background: var(--color-panel-raised); border-radius: var(--radius-sm); padding: 9px 6px; text-align: center; display: flex; flex-direction: column; gap: 3px; }
.sync2 .pcard__stats b { font-size: 1.15rem; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.sync2 .pcard__stats span { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-ink-soft); }
.sync2 .pcard__stats b.is-ok { color: var(--color-ok); }
.sync2 .pcard__stats b.is-warn { color: var(--color-warn); }
.sync2 .pcard__stats b.is-danger { color: var(--color-danger); }
.sync2 .backlog { display: flex; height: 6px; border-radius: var(--radius-pill); background: var(--color-line-soft); overflow: hidden; }
.sync2 .backlog > span { display: block; height: 100%; }
.sync2 .backlog .seg-wait { background: var(--color-brick); }
.sync2 .backlog .seg-retry { background: var(--color-warn); }
.sync2 .pcard__foot { margin-top: auto; }
.sync2 .dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
/* Plattform-Punkte pulsieren wie der Sync-Punkt oben (tb-sync-pulse). */
.sync2 .dot--ok, .sync2 .dot--warn, .sync2 .dot--err { position: relative; background: currentColor; }
.sync2 .dot--ok { color: var(--color-ok); }
.sync2 .dot--warn { color: var(--color-warn); }
.sync2 .dot--err { color: var(--color-danger); }
.sync2 .dot--ok::after, .sync2 .dot--warn::after, .sync2 .dot--err::after { content: ''; position: absolute; inset: 0; border-radius: 50%; background: currentColor; animation: tb-sync-pulse 2.4s ease-out infinite; }

/* --- Tabellen --- */
.sync2 .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Kartenoptik, Kopfzeile, Zellabstände und Zeilen-Hover kommen aus der
   globalen Tabellen-Designsprache (Abschnitt "Tabellen: eine Designsprache
   für das ganze Tool") - das Sync-Dashboard hatte hier vorher eine eigene,
   kleinere Kopfzeile in Versalien. Übrig bleibt, was hier tatsächlich eigen
   ist: Kopfzeilen brechen nicht um, Zahlenspalten laufen mit Tabellenziffern. */
.sync2 table.grid th { white-space: nowrap; }
.sync2 table.grid .num { text-align: right; font-variant-numeric: tabular-nums; }
.sync2 .rowlink { color: var(--color-ink); font-weight: 600; text-decoration: none; }
.sync2 .rowlink:hover { color: var(--color-brick); }
.sync2 .muted { color: var(--color-ink-soft); }
.sync2 .err { color: var(--color-danger); }
.sync2 .mini-select { height: 34px; padding: 0 12px; border: 1px solid var(--color-line); border-radius: var(--radius-pill); background: var(--color-panel-raised); color: var(--color-ink); font: inherit; font-size: 0.8rem; }

/* --- Ereignis-Log --- */
.sync2 details.run { border-bottom: 1px solid var(--color-line-soft); }
.sync2 details.run > summary { cursor: pointer; display: flex; align-items: center; gap: 12px; padding: 10px 12px; list-style: none; font-size: 0.86rem; }
.sync2 details.run > summary::-webkit-details-marker { display: none; }
.sync2 details.run > summary::before { content: "\25B8"; color: var(--color-ink-faint); transition: transform 0.15s; }
.sync2 details.run[open] > summary::before { transform: rotate(90deg); }
.sync2 .run__time { width: 96px; flex: 0 0 auto; color: var(--color-ink-soft); font-size: 0.8rem; }
.sync2 .run__label { width: 82px; flex: 0 0 auto; color: var(--color-ink-soft); }
.sync2 .run__summary { flex: 1; min-width: 0; }
.sync2 .run__steps { flex: 0 0 auto; font-size: 0.74rem; color: var(--color-ink-soft); }
.sync2 .run__detail { margin: 0; background: var(--color-panel-raised); }
.sync2 .run__detail table { width: 100%; border-collapse: collapse; }
.sync2 .run__detail td { border-bottom: 1px solid var(--color-line-soft); font-size: 0.8rem; padding: 7px 12px; color: var(--color-ink-soft); vertical-align: top; }
.sync2 .run__detail tr:last-child td { border-bottom: none; }
.sync2 .logrow { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--color-line-soft); font-size: 0.86rem; }

@keyframes sync2-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes sync2-pulse-warn { 0% { box-shadow: 0 0 0 0 rgba(224, 168, 62, 0.4); } 70% { box-shadow: 0 0 0 12px rgba(224, 168, 62, 0); } 100% { box-shadow: 0 0 0 0 rgba(224, 168, 62, 0); } }
@keyframes sync2-pulse-danger { 0% { box-shadow: 0 0 0 0 rgba(240, 98, 94, 0.4); } 70% { box-shadow: 0 0 0 12px rgba(240, 98, 94, 0); } 100% { box-shadow: 0 0 0 0 rgba(240, 98, 94, 0); } }
@media (prefers-reduced-motion: reduce) {
    .sync2 .pulse-dot::after,
    .sync2 .dot--ok::after,
    .sync2 .dot--warn::after,
    .sync2 .dot--err::after { animation: none; opacity: 0.25; transform: scale(1.8); }
    .sync2 .tabpanel.is-active { animation: none; }
}

@media (max-width: 720px) {
    .sync2 .pagehead__actions { width: 100%; }
    .sync2 .health { padding: 18px; }
    .sync2 .issue-card { flex-direction: column; }
    .sync2 .issue-card__actions { width: 100%; justify-content: flex-start; }
}
@media (max-width: 520px) {
    .sync2 .pagehead__actions { flex-direction: column; align-items: stretch; }
    .sync2 .mode-switch { justify-content: space-between; }
    /* Knopf und Symbolknöpfe bleiben in einer Pille - umgebrochen standen
       die zwei Symbole verloren unter dem Knopf in einer zweizeiligen Blase. */
    .sync2 .actiongroup .btn-primary { flex: 1 1 auto; min-width: 0; justify-content: center; }
    .sync2 .actiongroup .icon-btn { flex: none; }
    /* Hinweiskasten mit Knopf (Stammdaten nachladen, Pausieren): der Text
       bekommt eine Mindestbreite, sonst stand er in einer 150px-Spalte
       neben dem Knopf. Passt beides nicht, rückt der Knopf rechtsbündig
       in eine eigene Zeile darunter. */
    .sync2 .sync-callout__text { flex: 1 1 200px; }
    .sync2 .sync-callout > form,
    .sync2 .sync-callout > .btn,
    .sync2 .sync-callout > .actiongroup { margin-left: auto; }
}

/* ============================================================
   Ankäufe: Stammdatenliste, Ablagefläche, Anlagen-Kacheln
   (purchases.php, app_includes/purchase_engine.php)
   ============================================================ */

/* --- Definitionsliste für die Kopfdaten eines Ankaufs ---
   .detail-list darüber setzt eine eigene .detail-row je Zeile voraus; hier
   reichen dt/dd, weil die Zeilen kurz sind und paarweise gelesen werden.
   Alles in dd trägt dieselbe Größe, damit ein Badge nicht als Fremdkörper
   zwischen zwei Textzeilen sitzt. */
.data-list { display: grid; grid-template-columns: max-content 1fr; gap: 8px 20px; margin: 0; }
.data-list dt { color: var(--color-ink-soft); font-size: 0.85rem; }
/* 0.88rem ist die Tabellenschrift der Übersichten - sonst weichen die Badges
   hier und dort um Bruchteile eines Pixels voneinander ab. */
.data-list dd { margin: 0; font-size: 0.88rem; }
.data-list dd .badge,
.data-list dd .sku,
.data-list dd .text-soft { font-size: inherit; }
.data-list dd .badge { padding: 2px 8px; }
/* In der Status-Zeile sitzt ein Badge mit Icon, das ein paar Pixel höher baut
   als eine reine Textzeile. Damit die Liste nicht ungleichmäßig wirkt, tragen
   bei .data-list-rows alle Zeilen dieselbe Mindesthöhe. */
.data-list.data-list-rows { align-items: center; }
.data-list.data-list-rows dt,
.data-list.data-list-rows dd { min-height: 26px; }

/* --- Rücksprung aus einer Detailansicht --- */
.page-back { margin: 0 0 10px; font-size: 0.88rem; }

/* --- Ablagefläche für Anlagen ---
   Auch ohne JavaScript benutzbar: dann ist sie schlicht ein Rahmen um ein
   gewöhnliches Dateifeld. assets/js/upload-dropzone.js ergänzt das Ziehen,
   die Rückmeldung und die Dateiliste. */
.dropzone {
    position: relative;
    border: 2px dashed var(--color-line);
    border-radius: var(--radius);
    background: var(--color-panel-raised);
    padding: 24px 16px;
    text-align: center;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone:hover { border-color: var(--color-stud); }
.dropzone.is-over {
    border-color: var(--color-primary);
    background: var(--color-primary-container);
}
.dropzone.has-files {
    border-style: solid;
    border-color: var(--color-stud);
}
.dropzone input[type="file"] {
    /* Sichtbar bleiben, damit es ohne JavaScript bedienbar ist - nur
       unauffällig genug, dass der Hinweistext die Fläche trägt. */
    display: block;
    margin: 0 auto 10px auto;
    max-width: 100%;
    font-size: 0.82rem;
    color: var(--color-ink-soft);
}
.dropzone-hint {
    font-size: 0.88rem;
    color: var(--color-ink-soft);
    line-height: 1.6;
    pointer-events: none;
}
.dropzone-hint strong { color: var(--color-ink); }
.dropzone-files {
    list-style: none;
    margin: 12px 0 0 0;
    padding: 0;
    font-size: 0.8rem;
    color: var(--color-ink-soft);
    text-align: left;
}
.dropzone-files li {
    padding: 3px 0;
    border-top: 1px solid var(--color-line-soft);
}
.upload-form { margin-bottom: 18px; }
/* Die Knopfleiste unter der Ablagefläche hatte keinen oberen Abstand - der
   "Hochladen"-Knopf klebte auf Pixel genau am unteren Rand der gestrichelten
   Fläche. Unten braucht sie keinen, das Formular bringt seinen eigenen mit. */
.upload-form-actions { margin-top: 16px; margin-bottom: 0; }

/* --- Unterschrift des Verkäufers (Ankauf vor Ort) --- */
.field-hint-block { font-size: 0.85rem; margin: 0 0 10px; }
/* Unterschrift immer auf Weiß, auch im Dunkelmodus: sie ist mit dunkler Tinte
   gezeichnet und landet so auch auf dem Beleg. */
.signature-preview img {
    display: block;
    max-width: 320px;
    width: 100%;
    max-height: 120px;
    object-fit: contain;
    object-position: left center;
    background: #fff;
    border-radius: 8px;
    padding: 8px;
    box-sizing: border-box;
    margin-bottom: 6px;
}
.sign-view { max-width: 760px; }
.sign-description { white-space: pre-wrap; margin: 0 0 14px; }
.sign-amount {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 12px 16px;
    border-radius: 12px;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    margin-bottom: 14px;
}
.sign-amount strong { font-size: 1.35rem; }
.sign-declaration { line-height: 1.55; margin: 0 0 16px; }
.sign-pad {
    position: relative;
    height: 220px;
    background: #fff;
    border: 1px dashed var(--color-line);
    border-radius: 12px;
    overflow: hidden;
    /* Kein Scrollen und kein Zoom, während der Finger unterschreibt. */
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}
.sign-pad canvas {
    display: block;
    width: 100%;
    height: 100%;
    touch-action: none;
    cursor: crosshair;
}
.sign-pad-line {
    position: absolute;
    left: 20px;
    right: 20px;
    bottom: 48px;
    border-top: 1px solid #c4cad0;
    pointer-events: none;
}
.sign-pad-line span {
    display: block;
    padding-top: 4px;
    font-size: 0.8rem;
    color: #8a9097;
}
.sign-pad.has-ink .sign-pad-line span { visibility: hidden; }
.sign-actions { margin-top: 14px; margin-bottom: 0; }
.sign-actions [data-sign-submit] { margin-left: auto; }

/* --- Anlagen als Kachelraster --- */
/* Breite Kacheln, damit der längste erzeugte Name
   ("WB-AK001-Versandnachweis.jpg") in eine Zeile passt. Die Vorschauen sind
   alle gleich groß (--doc-ratio unten); die Kacheln einer Reihe werden auf
   gleiche Höhe gestreckt, damit keine aus der Reihe fällt, falls der Text
   darunter einmal unterschiedlich hoch ist. min(), damit auf schmalen
   Telefonen nichts über den Rand ragt. */
.doc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr));
    gap: 14px;
    margin-top: 6px;
}
.doc-tile {
    border: 1px solid var(--color-outline-variant);
    border-radius: 8px;
    background: var(--color-panel-raised);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-width: 0;
}
/* Alle Vorschauen stehen quer und sind gleich groß. Das Seitenverhältnis
   (--doc-ratio) setzt das Skript in purchases.php auf das häufigste Format
   der Fotos dieses Ankaufs (lange Kante zu kurzer); es gilt für jede Kachel,
   auch die PDF-Kachel. Bis dahin gilt 4:3 - das Format eines Handyfotos.

   Ein Hochformatfoto wird für die Vorschau um 90° gedreht (.is-rotated),
   damit es sich in die Reihe der Querformate einfügt. Die Datei selbst bleibt
   unverändert. Gedreht wird ein Bild mit vertauschten Maßen: breit wie die
   Fläche hoch ist (100cqh) und umgekehrt - dafür ist die Fläche ein
   Größen-Container. */
.doc-preview {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: var(--doc-ratio, 1.333);
    container-type: size;
    background: var(--color-bg);
    overflow: hidden;
}
.doc-preview img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.doc-preview img.is-rotated {
    inset: auto;
    left: 50%;
    top: 50%;
    width: 100cqh;
    height: 100cqw;
    transform: translate(-50%, -50%) rotate(-90deg);
}
.doc-icon {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 1px;
    color: var(--color-ink-faint);
    border: 2px solid var(--color-line);
    border-radius: 4px;
    padding: 10px 14px;
}
.doc-meta {
    padding: 9px 10px 10px 10px;
    font-size: 0.78rem;
    line-height: 1.5;
}
.doc-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 2px;
}
.doc-meta form { margin-top: 8px; }

/* Zwei Badge-Varianten, die es bisher nicht gab.
   .badge-neutral für einen Zustand, an dem nichts falsch ist und nichts zu tun -
   "Nicht übertragen" bei ausgeschalteter Buchhaltungsanbindung wäre in Rot ein
   Fehlalarm. .badge-info für einen Zwischenstand, der weder Warnung noch
   Abschluss ist ("Beleg übertragen"): blau, damit es sich vom grünen
   .badge-ok unterscheidet. */
.badge-neutral { background: rgba(155,155,160,0.16); color: var(--color-ink-faint); }
.badge-info    { background: rgba(57,166,254,0.16);  color: #7fc4ff; }

/* Übertragungs-Badge in Ankaufsansicht und -liste (renderPurchaseSyncBadge):
   gleiche Größe und Schreibweise wie .order-status-badge daneben, nur ohne
   Icon - der Übertragungsstand ist die nachgeordnete Angabe. */
.badge.badge-sync {
    font-size: 0.88rem;
    padding: 3px 10px;
    text-transform: none;
    letter-spacing: normal;
}
/* PDF-Knopf der Ankaufsliste: schmale letzte Spalte, Icon rechtsbündig -
   in der Kartenansicht (Mobil) ebenso am rechten Rand. */
.data-table .purchase-pdf-cell { width: 1%; text-align: right; white-space: nowrap; }
table.table-cards.cards-ready td.purchase-pdf-cell { width: auto; justify-content: flex-end; }

/* .alert-warn fehlte bisher: bis zu den Ankäufen hat keine Seite den Typ
   "warn" gesetzt. Ohne diese Regel erschiene die Meldung ohne Farbe und ohne
   Rahmen. Farbwerte wie die übrigen alert-Varianten, abgeleitet von
   --color-warn. */
.alert-warn { background: rgba(224,168,62,0.12); color: var(--color-warn); border-color: rgba(224,168,62,0.3); }

/* ============================================================
   Preis-Hub: Statuskarte "Letzter Bridge-Lauf" (preis_hub.php).
   Bewusst dieselbe Bildsprache wie der Sync-Status auf
   sync_dashboard.php - Ampelpunkt mit Klartext-Urteil, darunter das
   Kennzahlenraster, die Aktionen als eine Pille daneben. Eigene
   Klassennamen, weil die dortigen Regeln allesamt an .sync2 hängen
   und auf dessen Markup zugeschnitten sind. Die Puls-Keyframes
   (sync2-pulse-*) sind global und werden hier mitbenutzt.
   ============================================================ */
.phub-run { display: flex; flex-direction: column; gap: 16px; }

.phub-callout {
    display: flex;
    align-items: center;
    gap: 12px 14px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border-radius: var(--radius);
    background: rgba(224, 168, 62, 0.10);
    border: 1px solid rgba(224, 168, 62, 0.30);
}
.phub-callout.is-ok     { background: rgba(63, 196, 136, 0.10); border-color: rgba(63, 196, 136, 0.30); }
.phub-callout.is-danger { background: rgba(240, 98, 94, 0.10);  border-color: rgba(240, 98, 94, 0.30); }

.phub-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--color-warn);
    animation: sync2-pulse-warn 2.4s ease-out infinite;
}
.phub-callout.is-ok     .phub-dot { background: var(--color-ok); animation: none; }
.phub-callout.is-danger .phub-dot { background: var(--color-danger); animation-name: sync2-pulse-danger; }

.phub-callout__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.phub-callout__text strong { font-size: 1.05rem; font-weight: 700; color: #fff; }
.phub-eyebrow {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-ink-soft);
    font-weight: 700;
}

/* Aktionen als eine zusammenhängende Pille: Hauptknopf, Nebenknopf und das
   Kopier-Symbol gehören zum selben Wochenlauf und sollen nicht als drei
   lose Bedienelemente nebeneinander stehen. */
.phub-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    padding: 4px;
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    border: 1px solid var(--color-outline-variant);
}
.phub-actions form { display: contents; }
.phub-actions .btn { height: 40px; padding: 0 18px; box-shadow: none; }
.phub-actions .btn:not(.btn-primary) { border-color: transparent; }
.phub-actions .btn:not(.btn-primary):hover { background: var(--state-hover); }
/* Das Kopier-Symbol ist sonst ein 22px-Knopf für den Fließtext - in dieser
   Leiste bekommt es dieselbe runde 40px-Fläche wie die Icon-Knöpfe des
   Sync-Dashboards. */
.phub-actions .copy-icon-btn {
    width: 40px;
    height: 40px;
    margin: 0;
    border-radius: 50%;
    color: var(--color-ink-soft);
}
.phub-actions .copy-icon-btn svg { width: 18px; height: 18px; }

.phub-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; }
.phub-stat {
    background: var(--color-panel-raised);
    border-radius: var(--radius);
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.phub-stat__label {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-ink-soft);
    font-weight: 600;
}
.phub-stat__value { font-size: 1.2rem; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.phub-stat__sub { font-size: 0.74rem; color: var(--color-ink-soft); }
.phub-stat__sub.is-warn { color: var(--color-warn); }
.phub-stat__sub.is-ok   { color: var(--color-ok); }

.phub-run__error { margin: 0; font-size: 0.85rem; color: var(--color-danger); }

/* Auf dem Handy passen Haupt-, Nebenknopf und Kopier-Symbol nicht mehr
   nebeneinander in eine Pille - die schob sich sonst über den Rand der
   Karte hinaus. Dort fällt die Pillenfläche weg und die Knöpfe verteilen
   sich über die volle Breite. */
@media (max-width: 760px) {
    .phub-actions {
        width: 100%;
        flex-wrap: wrap;
        padding: 0;
        background: transparent;
        border: none;
    }
    .phub-actions .btn { flex: 1 1 150px; justify-content: center; }
    .phub-actions .btn:not(.btn-primary) { border-color: var(--color-line); }
}

/* --- BrickLink-Seite (bricklink_bulk_update.php) ---
   Kontingent-Leiste im Kopf: Verbrauch je Funktionsgruppe in Steinblau-
   Abstufungen, Sync-Reserve und Bestellpuffer als dezente Schraffur am
   rechten Ende (zwei Lagen übereinander, der Bestellpuffer wirkt dichter). */
.sync2, .ui-tip { --quota-core: var(--color-brick); --quota-background: #1d6cb5; --quota-manual: var(--color-stud); --quota-other: #55555a;
         --quota-hatch: repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.07) 0 3px, transparent 3px 7px); }
.sync2 .quota { display: flex; flex-direction: column; gap: 8px; }
.sync2 .quota__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.sync2 .quota__total { font-size: 0.85rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
.sync2 .quota__total strong { font-size: 1.2rem; color: #fff; }
.sync2 .quota__track { position: relative; display: flex; height: 10px; border-radius: var(--radius-pill); background: var(--color-panel-raised); overflow: hidden; }
.sync2 .quota__seg { display: block; height: 100%; }
.sync2 .quota__seg--core { background: var(--quota-core); }
.sync2 .quota__seg--background { background: var(--quota-background); }
.sync2 .quota__seg--manual { background: var(--quota-manual); }
.sync2 .quota__seg--other { background: var(--quota-other); }
.sync2 .quota__zone { position: absolute; top: 0; bottom: 0; right: 0; background: var(--quota-hatch); pointer-events: none; }
.sync2 .quota__zones { display: flex; font-size: 0.72rem; color: var(--color-ink-faint); }
.sync2 .quota__zones span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sync2 .quota__zones span + span { border-left: 1px solid var(--color-line); padding-left: 5px; }
.sync2 .quota__legend { display: flex; gap: 6px 18px; flex-wrap: wrap; font-size: 0.76rem; color: var(--color-ink-soft); }
.sync2 .quota__legend span { display: inline-flex; align-items: center; gap: 6px; }
.sync2 .quota__legend span::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--quota-other); }
.sync2 .quota__legend span.is-core::before { background: var(--quota-core); }
.sync2 .quota__legend span.is-background::before { background: var(--quota-background); }
.sync2 .quota__legend span.is-manual::before { background: var(--quota-manual); }
.sync2 .quota__legend span.is-zone { color: var(--color-ink-faint); }
.sync2 .quota__legend span.is-zone::before { background: var(--color-panel-raised) repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.18) 0 2px, transparent 2px 4px); }
.sync2 .quota__legend b { color: var(--color-ink); font-variant-numeric: tabular-nums; }

/* Heutiger Verbrauch je Funktion: Gruppenzeile in der Gruppenfarbe, Anteil
   an der Tagessumme rechts */
.sync2 .quota-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 0.86rem; }
.sync2 .quota-table th { text-align: left; font-size: 0.74rem; font-weight: 600; color: var(--color-ink-soft); padding: 0 8px 6px; border-bottom: 1px solid var(--color-line-soft); }
.sync2 .quota-table td { padding: 6px 8px; border-bottom: 1px solid var(--color-line-soft); }
.sync2 .quota-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; width: 1%; }
.sync2 .quota-table tbody { --quota-color: var(--quota-other); }
.sync2 .quota-table tbody.is-core { --quota-color: var(--quota-core); }
.sync2 .quota-table tbody.is-background { --quota-color: var(--quota-background); }
.sync2 .quota-table tbody.is-manual { --quota-color: var(--quota-manual); }
.sync2 .quota-table__group td { padding-top: 7px; padding-bottom: 7px; border-bottom: 0; background: var(--color-panel-raised); font-size: 0.74rem; font-weight: 600; color: var(--quota-color); }
.sync2 .quota-table tbody + tbody .quota-table__group td { border-top: 8px solid transparent; background-clip: padding-box; }
.sync2 .quota-table tbody.is-background .quota-table__group td { color: #5b9fe0; }
.sync2 .quota-table tbody.is-other .quota-table__group td { color: var(--color-ink-soft); }
.sync2 .quota-table__dot { width: 10px; padding-right: 0 !important; }
.sync2 .quota-table__dot i { display: block; width: 10px; height: 10px; border-radius: 3px; background: var(--quota-color); }
.sync2 .quota-table__bar { width: 30%; }
.sync2 .quota-table__bar span { display: block; height: 6px; min-width: 2px; border-radius: var(--radius-pill); background: var(--quota-color); }
.sync2 .quota-table tbody tr:last-child td { border-bottom: 0; }
.sync2 .quota-table tfoot td { border-bottom: 0; border-top: 1px solid var(--color-line-soft); padding-top: 10px; color: var(--color-ink-soft); }
.sync2 .quota-table tfoot td:nth-child(2) { color: var(--color-ink); font-weight: 600; }
@media (max-width: 600px) { .sync2 .quota-table__bar { display: none; } }

/* 30-Tage-Verlauf: gestapelte Säulen je Tag, Sperrstufen als Schraffur */
.sync2 .quota-chart { position: relative; display: flex; align-items: flex-end; gap: 3px; height: 150px; border-bottom: 1px solid var(--color-line); }
.sync2 .quota-chart__zone { position: absolute; left: 0; right: 0; top: 0; background: repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.035) 0 3px, transparent 3px 7px); pointer-events: none; }
.sync2 .quota-chart__mark { position: absolute; right: 2px; margin-bottom: 2px; font-size: 0.66rem; color: var(--color-ink-faint); pointer-events: none; }
.sync2 .quota-chart__day { position: relative; z-index: 1; flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column-reverse; }
.sync2 .quota-chart__day span { display: block; flex: none; }
.sync2 .quota-chart__day { border-radius: 3px 3px 0 0; transition: background-color 0.12s; }
.sync2 .quota-chart__day:hover { background: rgba(255, 255, 255, 0.06); }
.sync2 .quota-chart__day:hover span { filter: brightness(1.15); }
.sync2 .quota-chart__axis { display: flex; gap: 3px; margin-top: -4px; }
.sync2 .quota-chart__axis span { flex: 1; min-width: 0; text-align: center; font-size: 0.66rem; color: var(--color-ink-faint); white-space: nowrap; overflow: visible; }

/* Karten-Inhalte unter dem Status-Callout eines Reiters */
.sync2 .card > .sync-callout + * { margin-top: 18px; }
.sync2 .section-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; }
.sync2 .section-bar .hint { margin: 0; }
.sync2 .section-bar form { margin: 0; }

/* M3 linear progress indicator (https://m3.material.io/components/progress-indicators):
   4px-Spur mit abgerundeter Aktivfläche. */
.sync2 .progress-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px 24px; margin-bottom: 18px; }
.sync2 .progress { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.sync2 .progress__head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.sync2 .progress__label { font-size: 0.85rem; font-weight: 600; color: var(--color-ink); }
.sync2 .progress__value { font-size: 0.85rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
.sync2 .progress__track { height: 4px; border-radius: var(--radius-pill); background: var(--color-panel-raised); overflow: hidden; }
.sync2 .progress__bar { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--color-brick); transition: width 0.3s ease; }

/* Tagesbudget: MD3-Feld und Knopf auf einer Grundlinie */
.sync2 .budget-form { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin: 0; }
.sync2 .budget-form .field { margin: 0; width: 220px; max-width: 100%; }
/* Verbrauchsverlauf unten in der Kontingent-Karte */
.sync2 .quota-history { display: flex; flex-direction: column; gap: 8px; padding-top: 14px; }
/* Tooltip eines Verlaufstags (data-tip-template, assets/js/tooltip.js) */
.ui-tip--rich:not([hidden]) { display: grid; gap: 4px; min-width: 190px; padding: 8px 10px; white-space: normal; }
.ui-tip .quota-tip__head { display: flex; justify-content: space-between; gap: 16px; padding-bottom: 4px; margin-bottom: 2px; border-bottom: 1px solid var(--color-line); color: var(--color-ink-soft); }
.ui-tip .quota-tip__row { display: grid; grid-template-columns: 10px 1fr auto; align-items: center; gap: 8px; font-weight: 400; }
.ui-tip .quota-tip__row i { width: 10px; height: 10px; border-radius: 3px; background: var(--quota-other); }
.ui-tip .quota-tip__row i.quota__seg--core { background: var(--quota-core); }
.ui-tip .quota-tip__row i.quota__seg--background { background: var(--quota-background); }
.ui-tip .quota-tip__row i.quota__seg--manual { background: var(--quota-manual); }
.ui-tip b { font-weight: 600; font-variant-numeric: tabular-nums; }

/* ============================================================
   Minifiguren-Übersicht (minifigures.php) - Filterleiste und .panel wie
   die übrigen Listen, Hinweis-Callout aus .sync2
   ============================================================ */
.mfig .mfig-callout { margin-bottom: 16px; }

/* --- Tabelle --- */
.mfig .mfig-table th.mfig-col-title { width: 34%; }
.mfig .mfig-table .mfig-col-select { width: 34px; padding-right: 0; }
.mfig .mfig-table .mfig-col-img { width: 66px; padding-right: 4px; }
.mfig .mfig-table .mfig-col-actions { width: 1%; white-space: nowrap; text-align: right; }
.mfig .mfig-table input[type="checkbox"] { width: 18px; height: 18px; margin: 0; accent-color: var(--color-brick); cursor: pointer; vertical-align: middle; }
.mfig .mfig-table tbody tr.is-selected > td { background: rgba(57, 166, 254, 0.07); }
.mfig .mfig-table tbody tr.is-selected > td.mfig-col-select { box-shadow: inset 3px 0 0 var(--color-brick); }
.mfig .mfig-thumb { display: block; width: 54px; height: 54px; object-fit: contain; background: #fff; border-radius: var(--radius-sm); }
.mfig .mfig-name { display: block; font-weight: 600; color: var(--color-ink); line-height: 1.35; text-wrap: pretty; }
.mfig .mfig-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 10px; margin-top: 4px; font-size: 0.76rem; }
.mfig .mfig-no { color: var(--color-brick); text-decoration: none; font-variant-numeric: tabular-nums; }
.mfig .mfig-no:hover { color: #5cb6ff; }
.mfig .mfig-parts-toggle { appearance: none; display: inline-flex; align-items: center; gap: 2px; padding: 3px 6px 3px 8px; margin: 0; border: 1px solid var(--color-line); border-radius: var(--radius-pill); background: transparent; color: var(--color-ink-soft); font: inherit; font-size: 0.72rem; font-weight: 600; cursor: pointer; }
.mfig .mfig-parts-toggle:hover { color: var(--color-ink); border-color: var(--color-brick); background: var(--state-hover); }
.mfig .mfig-parts-toggle svg { transition: transform 0.15s; }
.mfig .mfig-parts-toggle[aria-expanded="true"] { color: var(--color-on-primary-container); background: var(--color-primary-container); border-color: transparent; }
.mfig .mfig-parts-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.mfig .mfig-strong { font-weight: 700; color: #fff; }
.mfig .mfig-value { display: block; font-weight: 600; color: var(--color-ink); white-space: nowrap; }
.mfig .mfig-sub { display: block; margin-top: 2px; font-size: 0.72rem; color: var(--color-ink-soft); white-space: nowrap; }
.mfig .mfig-diff.is-pos { color: var(--color-ok); }
.mfig .mfig-diff.is-neg { color: var(--color-danger); }
.mfig .mfig-actions { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.mfig .mfig-table .mfig-col-cond { width: 1%; white-space: nowrap; }
/* Zustand per renderConditionBadge() wie in den übrigen Listen - die
   kleine Großbuchstaben-Pille aus .sync2 .badge darf hier nicht greifen. */
.mfig .badge.pick-items-condition-badge { display: inline-flex; align-items: center; padding: 3px 10px; font-size: 0.88rem; font-weight: 600; text-transform: none; letter-spacing: normal; }
/* Stückzahl als randlose MD3-Tonfläche wie das Suchfeld, ohne Zahlen-Pfeilchen */
.mfig .mfig-qty { width: 56px; height: 36px; padding: 0 8px; border: none; border-radius: var(--radius-pill); background: var(--color-surface-container-high); color: var(--color-ink); text-align: center; font: inherit; font-size: 0.88rem; font-weight: 600; font-variant-numeric: tabular-nums; appearance: textfield; -moz-appearance: textfield; transition: box-shadow 0.15s; }
.mfig .mfig-qty::-webkit-outer-spin-button,
.mfig .mfig-qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.mfig .mfig-qty:hover { box-shadow: inset 0 0 0 1px var(--color-line); }
.mfig .mfig-qty:focus { outline: none; box-shadow: 0 0 0 3px var(--state-focus); }
.mfig .icon-btn.mfig-ignore { width: 36px; height: 36px; background: var(--color-surface-container-high); }
.mfig .icon-btn.mfig-ignore:hover { color: var(--color-danger); background: rgba(240, 98, 94, 0.1); }

/* --- Stückliste (aufgeklappt) --- */
/* Zugeklappt bleibt zu - auch in der Kartenansicht, deren tr-Regel
   (display:block) sonst das hidden-Attribut überstimmt. */
.mfig .mfig-table tr.mfig-parts-row[hidden] { display: none; }
.mfig .mfig-parts-row > td,
.mfig .mfig-parts-row:hover > td { background: var(--color-panel-raised); padding: 12px 14px 14px; }
.mfig .mfig-parts { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
.mfig .mfig-part { display: flex; align-items: center; gap: 10px; min-width: 0; padding: 8px 12px 8px 8px; border-radius: var(--radius-sm); border: 1px solid var(--color-outline-variant); background: var(--color-panel); color: var(--color-ink); text-decoration: none; transition: border-color 0.15s; }
.mfig .mfig-part:hover { border-color: var(--color-brick); }
.mfig .mfig-part__img { flex: 0 0 auto; width: 40px; height: 40px; object-fit: contain; background: #fff; border-radius: 6px; }
.mfig .mfig-part__body { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.mfig .mfig-part__name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 0.8rem; font-weight: 600; line-height: 1.3; }
.mfig .mfig-part__meta { font-size: 0.72rem; color: var(--color-ink-soft); line-height: 1.4; }
.mfig .mfig-part__qty { flex: 0 0 auto; align-self: flex-start; font-size: 0.8rem; font-weight: 700; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }

/* --- Leerzustand --- */
.mfig .mfig-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 44px 20px 36px; text-align: center; color: var(--color-ink-soft); font-size: 0.86rem; }
.mfig .mfig-empty__icon { display: flex; align-items: center; justify-content: center; width: 56px; height: 56px; margin-bottom: 8px; border-radius: 50%; background: var(--color-panel-raised); color: var(--color-brick); }
.mfig .mfig-empty strong { color: var(--color-ink); font-size: 1rem; }

/* Mobil: Trefferzahl als eigene Zeile, darunter alle fünf Knöpfe in einer
   Reihe - sonst bricht der Start-Knopf allein in die nächste Zeile. */
@media (max-width: 600px) {
    .mfig .order-pick-actions { flex-wrap: wrap; justify-content: flex-end; }
    .mfig .order-pick-actions .filter-total { flex: 1 1 100%; justify-content: center; margin-left: 0; }
}
@media (max-width: 760px) {
    .mfig .mfig-parts { grid-template-columns: minmax(0, 1fr); }
    .mfig .mfig-sub, .mfig .mfig-value { display: inline; margin: 0 0 0 6px; }
    /* In der Karte markiert der Kartenrahmen die Auswahl - eingefärbte
       Einzelzellen sähen dort wie Flicken aus. */
    .mfig .mfig-table tbody tr.is-selected { border-color: var(--color-brick); box-shadow: inset 3px 0 0 var(--color-brick); }
    .mfig .mfig-table tbody tr.is-selected > td,
    .mfig .mfig-table tbody tr.is-selected > td.mfig-col-select { background: transparent; box-shadow: none; }
    /* Aktionszeile der Karte: volle Breite (width:1% gilt nur in der Tabelle),
       Mengenfeld ohne die allgemeine 110px-Mindestbreite breiter Kartenzellen */
    .mfig .mfig-table.cards-ready td.mfig-col-actions { width: auto; }
    .mfig .mfig-table.cards-ready td.mfig-col-actions .mfig-actions { justify-content: flex-end; }
    .mfig .mfig-table.cards-ready td.mfig-col-actions input.mfig-qty { min-width: 0; min-height: 0; width: 64px; height: 40px; }
    .mfig .mfig-table.cards-ready .icon-btn.mfig-ignore { width: 40px; height: 40px; }
}

/* ============================================================
   Eingabefelder mit eigener Schriftgröße (Nachzügler)
   Die 16px-Regel im 600px-Block oben verhindert, dass iOS beim Antippen
   hineinzoomt. Felder mit eigener Größe als inline-style (Schriftgrößen-
   Auswahl im Beschreibungs-Editor, XML-Feld beim Import) oder mit einer
   spezifischeren Regel weiter unten (Stückzahl auf minifigures.php,
   Kategorie-Eingabe) kamen daran vorbei. Steht bewusst am Dateiende.
   ============================================================ */
@media (max-width: 600px) {
    .mfig .mfig-qty,
    .tag-input-typer,
    textarea,
    input[style*="font-size"],
    select[style*="font-size"] {
        font-size: 16px !important;
    }
}

/* Formatierungsleiste der Beschreibungs-Editoren (ebay_listing_edit.php,
   ebay_text_snippet_edit.php). Alles steht als inline-style am Element,
   daher !important. Auf dem Handy liefen die Auswahlmenüs mit fester Breite
   ("Schriftgr…") und der rechtsbündige HTML-/Vorlagen-Block quer durch die
   Knopfzeile. Jetzt: Knöpfe in einer Zeile, Menüs teilen sich die nächste,
   HTML-Umschalter und Vorlage die letzte. */
@media (max-width: 600px) {
    #desc-format-buttons,
    #snip-format-buttons {
        flex: 1 1 100%;
    }
    #desc-toolbar select,
    #snip-toolbar select {
        flex: 1 1 130px;
        width: auto !important;
        min-width: 0;
        padding: 6px 10px !important;
    }
    #desc-toolbar > span:last-child {
        flex: 1 1 100%;
        margin-left: 0 !important;
    }
    /* Trennstrich vor den Menüs - die stehen jetzt in der nächsten Zeile. */
    #desc-format-buttons > span:nth-of-type(2),
    #snip-format-buttons > span:nth-of-type(2) {
        display: none;
    }
}

/* ============================================================
   Bestätigungsdialog im Tool (M3 "basic dialog"), gebaut von
   appConfirm() in assets/js/app-dialog.js. Natives <dialog> -
   Fokusfalle, Escape und ::backdrop liefert der Browser.
   ============================================================ */
.app-dialog {
    width: min(440px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    padding: 24px;
    border: none;
    border-radius: 28px;
    background: var(--color-surface-container-high);
    color: var(--color-ink);
    box-shadow: 0 12px 40px rgba(0,0,0,0.5);
    animation: app-dialog-in 160ms ease-out;
}
.app-dialog::backdrop {
    background: rgba(0,0,0,0.55);
    backdrop-filter: blur(2px);
}
@keyframes app-dialog-in {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: scale(1); }
}
.app-dialog-title {
    margin: 0 0 14px;
    font-size: 1.3rem;
    font-weight: 500;
    line-height: 1.3;
}
.app-dialog-body p {
    margin: 0 0 10px;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--color-ink-soft);
}
.app-dialog-note {
    margin: 4px 0 10px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: rgba(240,98,94,0.12);
    color: var(--color-danger);
    font-size: 0.88rem;
    line-height: 1.45;
    font-weight: 500;
}
.app-dialog-copy {
    width: 100%;
    margin: 4px 0 10px;
    padding: 9px 16px;
    border: none;
    border-radius: var(--radius-pill);
    background: var(--color-panel-raised);
    color: var(--color-ink);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 0.82rem;
}
.app-dialog-actions {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 20px;
}

/* Ladeansicht nach "Bestätigen" (busyText / data-confirm-busy): drei
   Steine in den Logo-Blautönen, die sich nacheinander stapeln. */
.app-dialog.is-busy { outline: none; }
.app-dialog-busy {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    min-height: 150px;
}
.app-dialog-busy-text {
    margin: 0;
    font-size: 0.95rem;
    color: var(--color-ink);
}
.app-dialog-bricks {
    display: flex;
    flex-direction: column-reverse;
    align-items: center;
    height: 60px;
}
.app-dialog-bricks span {
    position: relative;
    width: 44px;
    height: 15px;
    margin-top: 5px;
    border-radius: 3px;
    background: var(--color-brick);
    opacity: 0;
    animation: app-dialog-brick 1.8s ease-out infinite;
}
.app-dialog-bricks span::before,
.app-dialog-bricks span::after {
    content: "";
    position: absolute;
    top: -5px;
    width: 10px;
    height: 5px;
    border-radius: 2px 2px 0 0;
    background: inherit;
}
.app-dialog-bricks span::before { left: 8px; }
.app-dialog-bricks span::after  { right: 8px; }
.app-dialog-bricks span:nth-child(2) { background: var(--color-brick-dark); animation-delay: 0.3s; }
.app-dialog-bricks span:nth-child(3) { background: var(--color-stud); animation-delay: 0.6s; }
@keyframes app-dialog-brick {
    0%       { opacity: 0; transform: translateY(-18px); }
    15%, 80% { opacity: 1; transform: none; }
    100%     { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .app-dialog-bricks span { animation: none; opacity: 1; }
}

/* Beleg-Vorschau als Fenster über order_detail.php: großer Dialog, darin
   invoice_preview.php bzw. invoice_cancel_preview.php mit embed=1 im iframe.
   Grau, Rundung und Titel wie die übrigen Dialoge (.app-dialog); die
   eingebettete Seite trägt denselben Grundton, damit Rahmen und Inhalt
   ineinander übergehen statt zwei Flächen zu zeigen. */
.app-dialog.invoice-preview-dialog {
    width: min(1100px, calc(100vw - 32px));
    height: calc(100vh - 48px);
    max-height: none;
    padding: 24px 0 0;
    display: none;
    flex-direction: column;
    overflow: hidden;
}
.app-dialog.invoice-preview-dialog[open] { display: flex; }
/* Ein Dialog im iframe (Sicherheitsabfrage) dunkelt nur den Frame ab - die
   Kopfzeile darüber bekommt dieselbe Abdunklung wie .app-dialog::backdrop. */
.app-dialog.invoice-preview-dialog.is-dimmed::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--preview-head-h, 72px);
    background: rgba(0,0,0,0.55);
    backdrop-filter: blur(2px);
    z-index: 1;
}
/* Kompaktes Fenster lädt noch unsichtbar (openInvoicePreview()). */
html.is-loading-preview, html.is-loading-preview * { cursor: progress !important; }
/* Formular statt PDF (shipping_label_create.php): schmaler und nur so hoch,
   wie das Formular samt aufgeklapptem Produktmenü braucht. */
.app-dialog.invoice-preview-dialog.is-compact {
    width: min(680px, calc(100vw - 32px));
    height: min(560px, calc(100vh - 48px));
}
.invoice-preview-dialog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    /* Titel und Schließen-Knopf mit demselben Randabstand wie der Inhalt
       darunter (body.embed-layout main: 24px). */
    padding: 0 24px 12px;
}
.invoice-preview-dialog-head .app-dialog-title { margin: 0; }
/* Der Knopf-Hover (surface-container-high) ist genau die Dialogfläche - der
   Kreis verschwände beim Überfahren. */
.invoice-preview-dialog-head .icon-link-btn:hover { background: #4a4f57; color: var(--color-ink); }
.invoice-preview-dialog-frame {
    flex: 1 1 auto;
    width: 100%;
    border: none;
    background: var(--color-surface-container-high);
}
body.modal-open { overflow: hidden; }
/* Seite im Vorschaufenster (layout_header.php, $embedLayout): nur der Inhalt,
   genau so hoch wie das Fenster - das PDF (.docprev-frame) füllt den Rest. */
body.embed-layout main {
    max-width: none;
    height: 100vh;
    height: 100dvh;
    padding: 0 24px 24px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

/* --- Versandlabel für eine Bestellung (shipping_label_create.php) ---
   Oben Bestellung/Versandart und Portokasse als zwei Blöcke nebeneinander,
   darunter Empfänger, Produkt/Zusatzleistung/Gewicht und frei stehend die
   Knöpfe. Im Vorschaufenster wie die Rechnungsvorschau: die Blöcke sind
   Tonkarten wie .docprev-sum, die Eingabefelder liegen direkt auf der
   Dialogfläche, die Knöpfe rechtsbündig ohne Karte. */
.label-create { display: flex; flex-direction: column; gap: 12px; }
.label-create .panel, .label-create .alert { margin-bottom: 0; }
.label-create form { display: flex; flex-direction: column; gap: 12px; }
.label-create-head { display: flex; gap: 12px; }
.label-create-head > .label-create-box:first-child { flex: 1 1 auto; min-width: 0; }
.label-create-head > .label-create-box + .label-create-box { flex: 0 0 auto; }
.label-create-box { padding: 14px 18px; overflow: visible; }
.label-create-box .docprev-figs { margin-left: 0; }
.label-create-sep { color: var(--color-ink-faint); }
.label-create-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 12px; }
body.embed-layout .label-create { gap: 16px; }
body.embed-layout .label-create form { gap: 16px; }
body.embed-layout .label-create-head { gap: 16px; }
body.embed-layout .label-create-box {
    background: var(--color-panel-raised);
    border: none;
    border-radius: 16px;
    box-shadow: none;
}
body.embed-layout .label-create-fields {
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
}
.label-create-fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 150px;
    gap: 12px;
    padding: 14px 18px;
    overflow: visible;
}
.label-create-fields .field { margin-bottom: 0; min-width: 0; }
.label-create-fields .md3-dropdown,
.label-create-fields .md3-dropdown-trigger { width: 100%; }
.label-create-product { grid-column: 1 / -1; }
/* Im Fenster ist die Dialogfläche selbst schon surface-container-high - die
   Hover-/Fokusfarbe der Felder wäre davon nicht zu unterscheiden. Fokus wie
   ein aufgeklapptes Auswahlmenü: Fläche bleibt, dazu der blaue Rand. */
body.embed-layout .label-create-fields input:hover,
body.embed-layout .label-create-fields .md3-dropdown-trigger:hover { background: var(--color-line); }
body.embed-layout .label-create-fields input:focus {
    background: var(--color-panel-raised);
    box-shadow: inset 0 0 0 1px var(--color-brick);
}
@media (max-width: 560px) {
    .label-create-fields { grid-template-columns: minmax(0, 1fr) 110px; }
    .label-create-actions .btn { flex: 1 1 auto; justify-content: center; text-align: center; }
}

/* --- Beleg-Vorschau (invoice_preview.php, invoice_cancel_preview.php) ---
   Eckdaten-Zeile, PDF-Betrachter (includes/doc_preview_viewer.php) und
   Knopfleiste. Im Vorschaufenster als Spalte über die volle Höhe. */
.docprev { display: flex; flex-direction: column; gap: 12px; }
.docprev > .panel, .docprev > .alert { margin-bottom: 0; flex-shrink: 0; }
/* Wächst auf die Fensterhöhe, schrumpft aber nie unter den Inhalt - bei
   niedrigem Fenster scrollt dann main, statt dass sich die Knopfleiste über
   das PDF schiebt. */
body.embed-layout .docprev { flex: 1 0 auto; }
/* Eckdaten in einer Zeile je Beleg: Steuerart-Icon, Bestellung (Plattform,
   Bestellnummer und Name in einer Schrift), rechts die Zahlen. Mobil
   rutschen die Zahlen als Dreierraster unter Icon und Bestellung. */
.docprev-sum { padding: 12px 18px; overflow: visible; }
.docprev-sum-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 16px;
}
.docprev-sum-row + .docprev-sum-row { margin-top: 8px; }
.docprev-sum-badges { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
/* Kreise so groß wie die Icons der Übersichtskacheln in order_detail.php
   (.order-summary-icon: 44px, Icon 22px). */
.docprev-sum-badges .badge-icon-only { width: 44px; height: 44px; }
.docprev-sum-badges .badge-icon-only svg { width: 22px; height: 22px; }
.docprev-sum-order {
    flex: 1 1 0;
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 8px;
    min-width: 0;
    font-size: 0.9rem;
}
.docprev-sum-order [aria-hidden] { color: var(--color-ink-faint); }
.docprev-sum-row .docprev-figs { margin-left: auto; }
/* Belegnummer neben dem Titel (Fensterkopf bzw. <h1>). */
.docprev-title-number {
    margin-left: 6px;
    font-family: var(--font-mono);
    font-size: 0.8em;
    font-weight: 500;
    color: var(--color-ink-soft);
}
.docprev-doc-number { font-family: var(--font-mono); font-weight: 600; font-size: 0.95rem; }
.docprev-figs { display: flex; flex-wrap: wrap; gap: 6px 22px; margin: 0; }
/* Feste Mindestbreite: bei zwei Belegen stehen die Spalten dann untereinander. */
.docprev-figs > div { display: flex; flex-direction: column; min-width: 76px; }
.docprev-figs dt { font-size: 0.7rem; color: var(--color-ink-faint); }
.docprev-figs dd { margin: 0; font-size: 0.9rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.docprev-figs .is-total dd { font-weight: 700; }

.docprev-viewer {
    display: flex;
    flex-direction: column;
    padding: 10px;
    /* .panel scrollt sonst waagerecht und schneidet das Layout-Menü ab. */
    overflow: visible;
}
body.embed-layout .docprev > .docprev-viewer { flex: 1 1 auto; min-height: 0; }
.docprev-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 0 0 10px 6px;
}
.docprev-bar-start, .docprev-bar-end { display: flex; align-items: center; gap: 8px; min-width: 0; }
.docprev-bar .seg label { gap: 6px; padding: 5px 14px 5px 8px; }
.docprev-bar .seg .docprev-doc-number { font-size: 0.82rem; }
.docprev-layout { display: flex; align-items: center; gap: 8px; min-width: 0; }
.docprev-layout-label { font-size: 0.78rem; color: var(--color-ink-soft); }
/* Gleiche Höhe wie die Icon-Leiste daneben (34px Knöpfe + 2px Rand). */
.docprev-layout .md3-dropdown-trigger {
    min-width: 0;
    max-width: 220px;
    height: 38px;
    box-sizing: border-box;
    padding: 0 10px 0 14px;
    font-size: 0.82rem;
}
.docprev-actions { padding: 2px; }
.docprev-actions .order-action-btn { width: 34px; height: 34px; }
.docprev-frame {
    display: block;
    width: 100%;
    height: 820px;
    border: none;
    border-radius: 12px;
    background: #fff;
}
body.embed-layout .docprev-frame { flex: 1 1 auto; height: auto; min-height: 380px; }

.docprev-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 10px 16px;
    padding: 12px 16px;
    overflow: visible;
}
.docprev-foot-extra { flex: 1 1 280px; min-width: 0; }
.docprev-foot-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
.docprev-lines > summary {
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--color-ink-soft);
    margin-top: 10px;
}
.docprev-lines > summary:hover { color: var(--color-ink); }
.docprev-lines table { margin-top: 8px; }
.docprev-refund { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; }
.docprev-refund-check { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 0.88rem; cursor: pointer; }
.docprev-refund-check input { width: auto; margin: 0; accent-color: var(--color-brick); }

/* Im Vorschaufenster im Stil der übrigen Dialoge (.app-dialog): der Inhalt
   liegt direkt auf der grauen Dialogfläche statt in Panels, nur die Eckdaten
   bilden eine Tonkarte (wie .app-dialog-copy im Kopierdialog), die Knöpfe
   stehen rechtsbündig ohne eigene Karte wie in .app-dialog-actions. */
body.embed-layout { background: var(--color-surface-container-high); }
body.embed-layout .docprev { gap: 16px; }
body.embed-layout .docprev > .panel {
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
}
body.embed-layout .docprev > .docprev-sum {
    background: var(--color-panel-raised);
    border-radius: 16px;
    padding: 14px 18px;
}
body.embed-layout .docprev-bar { padding: 0 0 10px; }
/* Der Auswahl-Auslöser hat sonst genau das Grau der Dialogfläche und
   verschwindet darin. */
body.embed-layout .docprev-layout .md3-dropdown-trigger { background: var(--color-panel-raised); }
body.embed-layout .docprev-foot { padding: 4px 0 0; }

@media (max-width: 600px) {
    .app-dialog.invoice-preview-dialog,
    .app-dialog.invoice-preview-dialog.is-compact { width: 100vw; height: 100dvh; max-width: 100vw; border-radius: 0; }
    .app-dialog.invoice-preview-dialog { padding-top: 16px; }
    .invoice-preview-dialog-head { padding-left: 16px; padding-right: 16px; }
    body.embed-layout main { padding: 0 16px 16px; }
    body.embed-layout .docprev > .docprev-sum { padding: 12px 14px; }
    .docprev-sum, .docprev-foot { padding: 12px; }
    .docprev-viewer { padding: 8px; }
    .docprev-layout-label { display: none; }
    /* Zahlen als Raster unter Icon und Bestellung statt einer umbrechenden Reihe. */
    .docprev-sum-row .docprev-figs {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 6px 10px;
        width: 100%;
        margin-left: 0;
    }
    .docprev-figs dt { font-size: 0.66rem; }
    .docprev-figs dd { font-size: 0.84rem; }
    .docprev-sum-order { font-size: 0.84rem; }
    /* Zwei Belegnummern passen nicht neben den Titel - sie stehen ohnehin
       im Umschalter über dem PDF. */
    .invoice-preview-dialog-head .app-dialog-title { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 1.1rem; }
    .docprev-figs > div { min-width: 0; }
    .docprev-figs dd { white-space: normal; overflow-wrap: anywhere; }
    .docprev-sum-row + .docprev-sum-row { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--color-line); }
    .docprev-bar { gap: 8px; }
    .docprev-bar-end { width: 100%; justify-content: space-between; }
    .docprev-bar-end .docprev-actions { margin-left: auto; }
    .docprev-foot-actions { width: 100%; }
    .docprev-foot-actions .btn { flex: 1 1 auto; justify-content: center; text-align: center; }
}

/* Mengenfeld der Storno-Spalte in order_detail.php: M3-Feld (.md3-field am
   <td>), kompakt und zentriert. */
#items-table .cancel-col.md3-field input {
    width: 64px;
    padding: 6px 10px;
    text-align: center;
}

/* ============================================================
   Statistik (statistik.php) - gekapselt unter .st
   ============================================================ */
.st { --st-gap: 14px; }
.st-filter { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 18px; }
.st-seg { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 3px; padding: 3px; border: 1px solid var(--color-line); border-radius: var(--radius-pill); background: var(--color-panel-raised); }
.st-seg > a, .st-custom > summary {
    display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: var(--radius-pill);
    font-size: 0.82rem; font-weight: 600; color: var(--color-ink-soft); text-decoration: none; white-space: nowrap;
    cursor: pointer; transition: background 0.15s, color 0.15s;
}
.st-seg > a:hover, .st-custom > summary:hover { color: var(--color-ink); }
.st-seg > a.is-on, .st-custom > summary.is-on { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.st-custom { position: relative; }
.st-custom > summary { list-style: none; }
.st-custom > summary::-webkit-details-marker { display: none; }
.st-custom-form {
    position: absolute; z-index: 30; top: calc(100% + 8px); left: 0; display: flex; flex-direction: column; gap: 10px;
    padding: 14px; min-width: 220px; background: var(--color-surface-container-high); border: 1px solid var(--color-line);
    border-radius: var(--radius); box-shadow: var(--elevation-1);
}
.st-custom-form label { display: flex; flex-direction: column; gap: 4px; margin: 0; font-size: 0.78rem; color: var(--color-ink-soft); }

.st-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.st-kpi {
    min-width: 0; padding: 14px 16px; background: var(--color-panel); border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius); color: inherit; text-decoration: none;
}
.st-kpi-link { transition: border-color 0.15s; }
.st-kpi-link:hover { border-color: var(--color-brick); }
.st-kpi-label { font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-ink-soft); }
.st-kpi-value { margin: 4px 0 6px; font-size: 1.5rem; font-weight: 700; color: #ffffff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-kpi-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; min-height: 22px; }
.st-kpi-cmp { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.st-kpi-prev { font-size: 0.74rem; color: var(--color-ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-delta { font-size: 0.78rem; color: var(--color-ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-delta.is-up { color: var(--color-ok); }
.st-delta.is-down { color: var(--color-danger); }
.st-spark { flex: none; width: 84px; height: 22px; }
.st-spark polyline { fill: none; stroke: var(--color-brick); stroke-width: 1.6; vector-effect: non-scaling-stroke; stroke-linejoin: round; }

.st-sec { display: flex; align-items: center; gap: 10px; margin: 30px 0 14px; font-size: 1.05rem; }
.st-sec svg { width: 20px; height: 20px; flex: none; color: var(--color-brick); }
.st-sec::after { content: ""; flex: 1; border-top: 1px solid var(--color-line); }

.st-grid { display: grid; gap: var(--st-gap); margin-bottom: var(--st-gap); }
.st-grid-21 { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
.st-grid-11 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.st-card { min-width: 0; padding: 16px 18px; background: var(--color-panel); border: 1px solid var(--color-outline-variant); border-radius: var(--radius); }
.st-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.st-head h3 { margin: 0; font-size: 0.95rem; font-weight: 600; color: var(--color-ink); }
.st-soft { font-size: 0.78rem; color: var(--color-ink-soft); }
.st-note { font-size: 0.75rem; color: var(--color-ink-faint); }
.st-link { font-size: 0.8rem; color: var(--color-brick); text-decoration: none; }
.st-link:hover { color: #5cb6ff; }
.st-empty { padding: 28px 10px; text-align: center; font-size: 0.85rem; color: var(--color-ink-soft); }
.st-ok { color: var(--color-ok); }
.st-bad { color: var(--color-danger); }
.st-nowrap { white-space: nowrap; flex: none; }

.st-toggle { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--color-line); border-radius: var(--radius-pill); background: var(--color-panel-raised); }
.st-toggle button { border: 0; background: transparent; padding: 4px 11px; border-radius: var(--radius-pill); font: inherit; font-size: 0.75rem; font-weight: 600; color: var(--color-ink-soft); cursor: pointer; }
.st-toggle button:hover { color: var(--color-ink); }
.st-toggle button.is-on { background: var(--color-primary-container); color: var(--color-on-primary-container); }

.st-chart { position: relative; height: 210px; }
.st-chart-lg { height: 250px; }
.st-chart-sm { height: 170px; }
.st-chart-donut { height: 150px; margin-bottom: 8px; }
.st-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin-top: 10px; font-size: 0.78rem; color: var(--color-ink-soft); }
.st-legend .st-note { margin-left: auto; }
.st-swatch { display: inline-block; width: 12px; height: 3px; margin-right: 6px; vertical-align: middle; border-radius: 2px; }
.st-swatch.is-dashed { height: 0; border-top: 2px dashed var(--color-ink-faint); border-radius: 0; }
.st-dot { display: inline-block; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%; vertical-align: middle; flex: none; }
.st-c-bricklink { background: var(--color-brick); }
.st-c-brickowl { background: var(--color-ok); }
.st-c-ebay { background: var(--color-warn); }

.st-rows { display: flex; flex-direction: column; }
.st-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; padding: 7px 0; border-top: 1px solid var(--color-line-soft); font-size: 0.85rem; color: var(--color-ink); text-decoration: none; }
.st-row:first-child { border-top: 0; }
.st-row > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-row.is-dim { opacity: 0.45; }
.st-row-link { margin: 0 -8px; padding-left: 8px; padding-right: 8px; border-radius: var(--radius-sm); }
.st-row-link:hover { background: var(--state-hover); }
.st-item { display: flex; align-items: center; gap: 10px; min-width: 0; }
.st-item .thumb--sm { flex: none; }
.st-item-text { display: flex; flex-direction: column; min-width: 0; }
.st-item-name, .st-item-text .sku { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-item-name { font-weight: 500; }
.st-row .badge { margin-right: 6px; }

.st-heat { width: 100%; border-collapse: separate; border-spacing: 3px; table-layout: fixed; background: transparent; }
.st-heat th { padding: 0 2px; font-size: 0.7rem; font-weight: 500; color: var(--color-ink-faint); text-align: center; background: transparent; border: 0; }
.st-heat tbody th { width: 28px; text-align: left; }
.st-heat td {
    height: 26px; padding: 0; border: 0; border-radius: 4px; text-align: center; font-size: 0.7rem;
    background: rgba(57, 166, 254, var(--a)); color: #04141f;
}
.st-heat td.is-lo { color: var(--color-ink);
}

.st-stack { display: flex; height: 14px; overflow: hidden; border-radius: 7px; gap: 2px; margin-bottom: 12px; }
.st-stack-thin { height: 8px; margin-bottom: 6px; }
.st-s-new { background: var(--color-warn); }
.st-s-reserved { background: var(--color-stud); }
.st-s-shipped { background: var(--color-brick); }
.st-s-completed { background: var(--color-ok); }
.st-s-cancelled { background: var(--color-ink-faint); }

.st-bar { display: grid; grid-template-columns: 96px minmax(0, 1fr) 70px; align-items: center; gap: 10px; margin-bottom: 9px; font-size: 0.82rem; }
.st-bar > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-track { height: 8px; overflow: hidden; border-radius: 4px; background: var(--color-panel-raised); }
.st-track > span { display: block; height: 100%; border-radius: 4px; background: var(--color-brick); }
.st-track > span.is-noneu { background: var(--color-ok); }
.st-track > span.is-rest { background: var(--color-ink-faint); }
.st-num { text-align: right; white-space: nowrap; }
.st-subhead { margin: 14px 0 6px; font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-ink-soft); }
.st-split { display: flex; justify-content: space-between; font-size: 0.78rem; color: var(--color-ink-soft); }

.st-figs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-bottom: 12px; text-align: center; }
.st-figs strong { display: block; font-size: 1.25rem; font-weight: 700; color: #ffffff; white-space: nowrap; }
.st-figs strong.st-ok { color: var(--color-ok); }
.st-figs strong.st-bad { color: var(--color-danger); }
.st-figs span { font-size: 0.74rem; color: var(--color-ink-soft); }

.st-flow { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3px; }
.st-flow > div { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; background: var(--color-primary-container); }
.st-flow > div:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.st-flow > div:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; background: var(--color-panel-raised); }
.st-flow span { font-size: 0.72rem; color: var(--color-ink-soft); }
.st-flow strong { font-size: 1.1rem; color: var(--color-on-primary-container); }
.st-flow > div:last-child strong { color: #ffffff; }

@media (max-width: 1100px) {
    .st-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
    .st-grid-21, .st-grid-11 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 600px) {
    .st-filter { flex-direction: column; align-items: stretch; }
    .st-seg { border-radius: var(--radius); }
    .st-kpi { padding: 12px; }
    .st-kpi-value { font-size: 1.25rem; }
    .st-spark { width: 44px; }
    .st-kpi-prev { white-space: normal; }
    .st-kpi .st-delta { white-space: normal; }
    .st-card { padding: 14px; }
    .st-flow { grid-template-columns: minmax(0, 1fr); }
    .st-flow > div, .st-flow > div:first-child, .st-flow > div:last-child { border-radius: var(--radius-sm); }
    .st-bar { grid-template-columns: 80px minmax(0, 1fr) 62px; }
    .st-legend .st-note { margin-left: 0; }
    .st-custom-form { left: auto; right: 0; }
}

/* ============================================================
   Lager (storage.php, storage_setup.php) - gekapselt unter .stg / .stg-*
   Schubladen-Farbe kommt als --fill aus PHP (storageFillColor: grün -> rot).
   ============================================================ */
.stg { min-width: 0; }
.stg-intro { margin: -4px 0 14px; font-size: 0.86rem; }
.stg-mt { margin-top: 14px; }
.stg-h3 { margin: 26px 0 10px; font-size: 0.95rem; }
.stg-table-wrap { overflow-x: auto; }

/* --- Regalansicht ------------------------------------------------- */
.stg-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.stg-search-count { font-size: 0.82rem; white-space: nowrap; }
.stg-shelf { display: flex; align-items: flex-end; gap: 14px; overflow-x: auto; padding: 4px 2px 14px; }
.stg-shelf-row { flex: none; width: 92px; display: flex; flex-direction: column; gap: 6px; }
.stg-shelf-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; font-size: 0.82rem; padding: 0 2px; }
.stg-shelf-stack { display: flex; flex-direction: column; gap: 3px; }
.stg-shelf-mag { display: block; border-radius: 4px; outline: 2px solid transparent; outline-offset: 1px; transition: outline-color 120ms ease; }
.stg-shelf-mag:hover { outline-color: var(--color-brick); }
.stg-shelf-gap { position: relative; display: flex; flex-direction: column; gap: 3px; border-radius: 4px; background: repeating-linear-gradient(45deg, var(--color-line-soft) 0 2px, transparent 2px 7px); box-shadow: inset 0 0 0 1px var(--color-line); }
.stg-shelf-gap > .stg-mag { visibility: hidden; }
.stg-shelf-gap-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 0.72rem; color: var(--color-ink-faint); }
.stg-shelf-row.is-missing { justify-content: flex-end; color: var(--color-ink-soft); text-decoration: none; }
.stg-shelf-missing { height: 120px; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; font-size: 0.74rem; border: 1px dashed var(--color-line); border-radius: 6px; padding: 6px; }
.stg-shelf-row.is-missing:hover .stg-shelf-missing { border-color: var(--color-brick); color: var(--color-ink); }
/* Etagen (storage.js): je --per Reihen eine Etage mit eigener Bodenlinie; die Reihen
   teilen sich die Breite, Schubladen behalten ihr Seitenverhältnis. */
.stg-shelf.is-etagen { display: flex; flex-direction: column; align-items: stretch; gap: 18px; overflow: visible; }
.stg-etage { display: flex; align-items: flex-end; gap: 14px; padding-bottom: 16px; border-bottom: 2px solid var(--color-line); }
.stg-etage:last-child { border-bottom: none; padding-bottom: 0; }
.stg-shelf.is-etagen .stg-shelf-row { width: calc((100% - (var(--per) - 1) * 14px) / var(--per)); min-width: 0; }
.stg-shelf.is-etagen .stg-cell { height: auto; aspect-ratio: 2.75; }
/* Kopfzeile der Regalansicht: Überschrift | Regler mittig | Kennzahlen rechts */
.stg-head { display: grid; grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr); align-items: center; gap: 12px 24px; }
.stg-head h1 { margin: 0; }
.stg-head .filter-total { justify-self: end; }
.stg-per { display: inline-flex; align-items: center; gap: 12px; font-size: 0.95rem; white-space: nowrap; cursor: pointer; }
.stg-per input { width: 220px; height: 24px; margin: 0; padding: 0; border: none; background: transparent; accent-color: var(--color-brick); cursor: pointer; }
.stg-per input:focus { outline: none; box-shadow: none; border: none; }
.stg-per-min { min-width: 20px; text-align: right; color: var(--color-ink-soft); }
.stg-per output { min-width: 20px; font-weight: 700; color: var(--color-ink); }
/* Zu schmal für drei Spalten: Überschrift oben, Regler links und Kennzahlen rechts darunter. */
@media (max-width: 1440px) {
    .stg-head { grid-template-columns: auto minmax(0, 1fr); }
    .stg-head h1 { grid-column: 1 / -1; }
}
@media (max-width: 700px) {
    .stg-head { grid-template-columns: minmax(0, 1fr); }
    .stg-head .filter-total { justify-self: start; max-width: 100%; white-space: normal; height: auto; min-height: 36px; flex-wrap: wrap; }
    .stg-per input { width: 180px; }
}

/* --- Magazin (klein in Regal/Leiste, groß in der Magazinansicht) --- */
.stg-mag { display: flex; flex-direction: column; gap: 2px; padding: 2px; background: #0b0b0c; border: 1px solid var(--color-line); border-radius: 4px; }
.stg-band { display: grid; gap: 1px; }
.stg-cell { display: block; min-width: 0; background: var(--fill, transparent); border-radius: 1px; }
.stg-band--small .stg-cell { height: 5px; }
.stg-band--large .stg-cell { height: 10px; }
.stg-cell.is-empty { background: transparent; box-shadow: inset 0 0 0 1px var(--color-line); }
.stg-cell.is-missing { background: repeating-linear-gradient(45deg, var(--color-line-soft) 0 2px, transparent 2px 4px); }
.stg-shelf.is-searching .stg-cell { opacity: 0.18; }
.stg-shelf.is-searching .stg-cell.is-hit { opacity: 1; box-shadow: 0 0 0 1px #ffffff; }
.stg-shelf.is-searching .stg-shelf-mag.has-hit { outline-color: #ffffff; }
/* Magazinansicht mit ?q=: dasselbe für Leiste und großes Magazin */
.stg-magview.is-searching .stg-cell:not(.is-missing) { opacity: 0.22; }
.stg-magview.is-searching .stg-cell.is-hit { opacity: 1; }
.stg-magview.is-searching .stg-rowstrip .stg-cell.is-hit { box-shadow: 0 0 0 1px #ffffff; }
.stg-magview.is-searching .stg-mag--large .stg-cell.is-hit:not(.is-active) { outline: 2px solid #ffffff; outline-offset: 1px; }

.stg-mag--large { gap: 8px; padding: 8px; border-radius: var(--radius-sm); }
.stg-mag--large .stg-band { gap: 6px; }
.stg-mag--large .stg-cell { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; border: none; border-radius: 6px; cursor: pointer; color: #101012; font: inherit; padding: 0; }
/* Seitenverhältnis wie in der Regalübersicht (5px/10px hoch bei 6/3 Spalten = ca. 2,75 : 1) */
.stg-mag--large .stg-cell, .stg-rowstrip .stg-cell { height: auto; aspect-ratio: 2.75; }
.stg-mag--large .stg-cell.is-empty { color: var(--color-ink-soft); }
.stg-mag--large .stg-cell:hover { filter: brightness(1.12); }
.stg-mag--large .stg-cell:focus-visible { outline: 2px solid var(--color-brick); outline-offset: 2px; }
.stg-mag--large .stg-cell.is-active { outline: 3px solid #ffffff; outline-offset: 2px; }
.stg-cell-no { font-weight: 700; font-size: 1rem; line-height: 1; }
.stg-cell-lots { font-size: 0.76rem; line-height: 1; opacity: 0.8; }
/* Mehr Lots als erlaubt: Lot-Zahl dunkel hinterlegt, sticht auf jeder Füllgrad-Farbe hervor. */
.stg-cell-lots.is-over { display: inline-block; padding: 2px 6px; border-radius: var(--radius-pill); background: #101012; color: #ffffff; font-weight: 700; opacity: 1; }

.stg-legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 12px 0 0; font-size: 0.78rem; color: var(--color-ink-soft); }
.stg-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.stg-legend-swatch { width: 14px; height: 10px; border-radius: 2px; flex: none; }
.stg-legend-swatch.is-empty { box-shadow: inset 0 0 0 1px var(--color-line); }
.stg-legend-swatch.is-unknown { background: var(--color-outline-variant); }
.stg-legend-gradient { width: 64px; height: 10px; border-radius: 2px; flex: none; background: linear-gradient(90deg, hsl(120 70% 48%), hsl(60 70% 48%), hsl(0 70% 48%)); }

/* --- Magazinansicht: Leiste | Magazin | Seitenblatt ---------------- */
.stg-magview { display: grid; grid-template-columns: 150px minmax(0, 1fr) 380px; gap: 24px; align-items: start; }
.stg-magtitle { display: flex; align-items: center; gap: 12px; }
.stg-magtitle .place-icon--lg { width: 32px; height: 32px; }
.stg-rowstrip { display: flex; flex-direction: column; gap: 5px; position: sticky; top: 16px; }
.stg-rowstrip-mag { display: block; border-radius: 4px; outline: 2px solid transparent; outline-offset: 1px; }
.stg-rowstrip-mag:hover { outline-color: var(--color-line); }
.stg-rowstrip-mag.is-active { outline-color: var(--color-brick); }
.stg-magmain { min-width: 0; }

.stg-sheet { display: flex; flex-direction: column; min-width: 0; background: var(--color-panel); border: 1px solid var(--color-outline-variant); border-radius: var(--radius); position: sticky; top: 16px; max-height: calc(100vh - 32px); }
.stg-sheet[hidden] { display: none; }
.stg-sheet-bar { display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 18px; border-bottom: 1px solid var(--color-line-soft); flex: none; }
.stg-sheet-bar-title { flex: 1; font-weight: 700; font-size: 0.95rem; }
.stg-sheet-close { appearance: none; display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; border: none; border-radius: 50%; background: transparent; color: var(--color-ink-soft); cursor: pointer; }
.stg-sheet-close:hover { background: var(--state-hover); color: var(--color-ink); }
.stg-magview .stg-sheet:not(.is-open) .stg-sheet-close { visibility: hidden; }
.stg-sheet-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.stg-sheet--overlay { position: fixed; top: 0; right: 0; bottom: 0; width: min(420px, 100%); max-height: none; border-radius: 0; border-width: 0 0 0 1px; box-shadow: var(--elevation-3); z-index: 71; }

.stg-sheet-head { padding: 16px 18px 14px; border-bottom: 1px solid var(--color-line-soft); }
.stg-sheet-title { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.stg-sheet-code { font-size: 1.25rem; font-weight: 700; }
/* Rundes Lagerplatz-Icon, toolweit (renderPlaceIcon() / placeIcon() in scan.js):
   gedeckte, dunkle Töne, damit es nicht mit Status-, Plattform- oder Pickfarben kollidiert. */
.place-icon { display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px; border-radius: 50%; color: #ececed; vertical-align: -4px; user-select: none; }
.place-icon svg { display: block; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.place-icon--k { background: #4e6178; }
.place-icon--g { background: #55684e; }
.place-icon--b { background: #7a684a; }
.cond-icon.badge-new { color: var(--color-ok); }
.cond-icon.badge-used { color: var(--color-warn); }
.cond-icon svg { width: 65%; height: 65%; fill: currentColor; stroke: none; }
/* Größere Variante für Überschriften (Schubladen-Kopf, Magazinansicht). */
.place-icon--lg { width: 26px; height: 26px; vertical-align: calc(0.36em - 13px); } /* Mitte auf Versalhöhe der umgebenden Schrift */
.stg-size-pill { font-size: 0.72rem; padding: 2px 8px; border-radius: var(--radius-pill); background: var(--color-surface-container-high); color: var(--color-ink-soft); }
.stg-sheet-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 14px; }
.stg-stat { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: var(--radius-sm); background: var(--color-panel-raised); }
.stg-stat-label { font-size: 0.7rem; color: var(--color-ink-soft); }
.stg-stat-value { font-weight: 700; font-size: 0.92rem; }
.stg-stat.is-full .stg-stat-value { color: var(--color-danger); }
.stg-fillbar { height: 6px; margin-top: 10px; border-radius: 3px; background: var(--color-panel-raised); overflow: hidden; }
.stg-fillbar span { display: block; height: 100%; }
.stg-sheet-note { margin: 8px 0 0; font-size: 0.74rem; }
.stg-sheet-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; margin-top: 12px; font-size: 0.8rem; }
.stg-level { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.stg-level .btn { min-width: 2.4em; justify-content: center; }
.stg-sheet-warn { margin: 10px 0 0; padding: 8px 10px; border-radius: var(--radius-sm); background: rgba(224, 168, 62, 0.16); font-size: 0.78rem; }
.stg-lots { list-style: none; margin: 0; padding: 6px 0; }
.stg-lot-link { display: flex; align-items: center; gap: 12px; padding: 8px 18px; color: inherit; text-decoration: none; }
.stg-lot-link:hover { background: var(--state-hover); }
.stg-lot-thumb { width: 44px; height: 36px; flex: none; object-fit: contain; border-radius: 4px; background: #ffffff; }
span.stg-lot-thumb { background: var(--color-panel-raised); }
.stg-lot-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.stg-lot-name { font-size: 0.86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stg-lot-meta { font-size: 0.74rem; color: var(--color-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stg-lot-qty { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 0.82rem; }

/* --- Sonderorte ------------------------------------------------------ */
.stg-specials { margin-top: 20px; }
.stg-special-list { display: flex; flex-wrap: wrap; gap: 8px; }
.stg-special { appearance: none; display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px; border-radius: var(--radius-pill); border: 1px solid var(--color-line); background: var(--color-panel-raised); color: var(--color-ink); font: inherit; font-size: 0.82rem; cursor: pointer; }
.stg-special:hover, .stg-special.is-active { border-color: var(--color-brick); }
.stg-special.is-hit { border-color: #ffffff; box-shadow: 0 0 0 1px #ffffff; }

/* --- Einrichtung ----------------------------------------------------- */
.stg-editor { border-color: var(--color-brick); }
.stg-editor-fields { display: grid; grid-template-columns: 120px 180px minmax(0, 1fr); gap: 0 16px; align-items: start; }
.stg-field-wide { grid-column: 1 / -1; }
.stg-seq-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.stg-check { margin: 4px 0 16px; padding: 14px 16px; border-radius: var(--radius-sm); background: rgba(63,196,136,0.08); border: 1px solid rgba(63,196,136,0.3); }
.stg-check.has-errors { background: rgba(240,98,94,0.08); border-color: rgba(240,98,94,0.3); }
.stg-check-ok { margin: 0; color: var(--color-ok); }
.stg-check-list { margin: 0; padding-left: 18px; }
.stg-check-list.is-error { color: var(--color-danger); }
.stg-check-list.is-warn { color: var(--color-warn); margin-top: 8px; }
.stg-plan { margin: 12px 0 0; padding-left: 26px; font-size: 0.84rem; columns: 2 280px; }
.stg-plan li { margin: 2px 0; }
.stg-plan-type { display: inline-block; min-width: 110px; }
.stg-editor-actions { display: flex; gap: 10px; }
.stg-row-actions { display: flex; gap: 8px; justify-content: flex-end; }
.stg-row-actions form { margin: 0; }
.stg-baseline { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.stg-baseline-facts { display: flex; flex-wrap: wrap; gap: 10px; }
.stg-baseline-facts > div { display: flex; flex-direction: column; gap: 2px; padding: 10px 14px; border-radius: var(--radius-sm); background: var(--color-panel-raised); font-size: 0.78rem; }
.stg-baseline-facts strong { font-size: 0.95rem; }
.stg-limits { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0 16px; }
.stg-limits .field { width: 150px; }
.stg-limits .btn { margin-bottom: 16px; }

/* --- Pickplatz und Reserve ------------------------------------------- */
.stg-lot-split { font-size: 0.74rem; color: var(--color-ink-soft); }
.stg-lot-split .is-here { color: var(--color-ink); font-weight: 600; }
.stg-lot-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 18px 8px 74px; }
.stg-pp-slot, .stg-pp-start { padding: 0 18px 10px; }
.stg-sheet-head .stg-pp-start { padding: 12px 0 0; }
.stg-move { margin-top: 12px; padding: 10px 12px; border-radius: var(--radius-sm); background: rgba(224, 168, 62, 0.16); font-size: 0.82rem; }
.stg-move p { margin: 0 0 6px; }
.stg-move-hint { color: var(--color-warn); }
.stg-pending { border-bottom: 1px dashed var(--color-line); }
.stg-pending-head { margin: 10px 18px 0; font-size: 0.74rem; font-weight: 700; color: var(--color-ink-soft); }
.stg-pp { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--color-panel-raised); border: 1px solid var(--color-line); font-size: 0.8rem; }
.stg-pp-lot { margin: 0; }
.stg-pp-suggest { display: flex; flex-direction: column; gap: 6px; }
.stg-pp-option, .stg-pp-hit { appearance: none; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; width: 100%; padding: 8px 10px; border-radius: var(--radius-sm); border: 1px solid var(--color-line); background: var(--color-panel); color: var(--color-ink); font: inherit; font-size: 0.8rem; text-align: left; cursor: pointer; }
.stg-pp-option:hover, .stg-pp-hit:hover, .stg-pp-option.is-chosen { border-color: var(--color-brick); }
.stg-pp-results { display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow-y: auto; }
.stg-pp-fields { display: flex; flex-wrap: wrap; gap: 10px; }
.stg-pp-fields label, .stg-pp-searchlabel { display: flex; flex-direction: column; gap: 4px; color: var(--color-ink-soft); font-size: 0.74rem; }
.stg-pp-fields .stg-pp-code { width: 120px; }
.stg-pp-fields .stg-pp-pieces { width: 90px; }
.stg-pp-basis { margin: 0; font-size: 0.74rem; }
.stg-pp-check { margin: 0; padding-left: 18px; color: var(--color-ink-soft); }
.stg-pp-check:empty { display: none; }
.stg-pp-check .is-error, .stg-pp-error { color: var(--color-danger); }
.stg-pp-error { margin: 0; }
.stg-pp-empty { margin: 0; }
.stg-pp-actions { display: flex; gap: 8px; }
.stg-split-inputs { display: flex; flex-wrap: wrap; gap: 8px; }
.stg-split-inputs label { display: inline-flex; align-items: center; gap: 6px; }
.stg-split-inputs input { width: 90px; }
[data-split-pick].is-negative { color: var(--color-danger); }
.subnav__count { min-width: 20px; padding: 1px 7px; border-radius: var(--radius-pill); background: rgba(224, 168, 62, 0.16); color: var(--color-warn); font-size: 0.72rem; font-weight: 700; text-align: center; }
.pick-place-hint { font-size: 0.78rem; color: var(--color-warn); }

/* --- Nachschub und Pickzeiten ---------------------------------------- */
.stg-repl-list { list-style: none; margin: 0; padding: 0; }
.stg-repl { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.4fr) 270px; align-items: center; gap: 10px 18px; padding: 12px 0; border-top: 1px solid var(--color-line-soft); }
.stg-repl:first-child { border-top: none; }
.stg-repl-part { display: flex; align-items: center; gap: 12px; min-width: 0; color: inherit; text-decoration: none; }
.stg-repl-facts { display: flex; flex-direction: column; gap: 3px; font-size: 0.82rem; min-width: 0; }
.stg-repl-facts .text-faint { font-size: 0.74rem; }
.stg-repl-action { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin: 0; font-size: 0.82rem; }
.stg-tag-slow { display: inline-block; padding: 2px 8px; border-radius: var(--radius-pill); background: rgba(224, 168, 62, 0.16); color: var(--color-warn); font-size: 0.72rem; font-weight: 600; white-space: nowrap; }

@media (max-width: 1200px) {
    .stg-magview { grid-template-columns: minmax(0, 1fr) 360px; }
    .stg-rowstrip { display: none; }
}
@media (max-width: 900px) {
    .stg-magview { grid-template-columns: minmax(0, 1fr); }
    .stg-magview .stg-sheet { position: fixed; top: auto; left: 0; right: 0; bottom: 0; max-height: 70vh; border-radius: var(--radius) var(--radius) 0 0; box-shadow: var(--elevation-3); z-index: 71; transform: translateY(100%); transition: transform 220ms cubic-bezier(0.2, 0, 0, 1); }
    .stg-magview .stg-sheet.is-open { transform: none; }
    .stg-editor-fields { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .stg-repl { grid-template-columns: minmax(0, 1fr); }
    .stg-repl-action { justify-content: space-between; }
}
@media (max-width: 600px) {
    .stg-mag--large { padding: 6px; gap: 6px; }
    .stg-mag--large .stg-band { gap: 4px; }
    .stg-mag--large .stg-band--small .stg-cell { height: 40px; }
    .stg-mag--large .stg-band--large .stg-cell { height: 64px; }
    .stg-cell-no { font-size: 0.74rem; }
    .stg-cell-lots { display: none; }
    .stg-cell-lots.is-over { display: inline-block; font-size: 0.66rem; padding: 1px 5px; }
}

/* =====================================================================
   Wareneingang: Teilescan (scan_session.php, scan_sessions.php) -
   gekapselt unter .scan / .scan-*
   ===================================================================== */
.scan { min-width: 0; }
.scan kbd, .scan-form kbd { display: inline-block; min-width: 1.4em; padding: 0 5px; border: 1px solid var(--color-outline-variant); border-bottom-width: 2px; border-radius: 5px; font-size: 0.72rem; font-weight: 600; line-height: 1.5; font-family: inherit; text-align: center; color: var(--color-ink-soft); background: var(--color-panel-raised); }
.scan-small { font-size: 0.76rem; }
.scan-hint { font-size: 0.82rem; margin: 0 0 8px; }
.scan-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px 20px; flex-wrap: wrap; margin-bottom: 16px; }
.scan-head-main { min-width: 0; }
.scan-title { display: flex; align-items: center; gap: 10px; margin: 0 0 6px; }
.scan-title .place-icon { position: relative; top: -0.07em; } /* Mitte der Zeile liegt knapp unter der Versalmitte */
.scan-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; font-size: 0.86rem; }
.scan-head-actions { display: flex; gap: 8px; align-items: center; }
.scan-head-actions form { margin: 0; }

/* Beim Scannen die ganze Breite: Kamera bzw. Teil links, zuletzt gescannt rechts. */
main:has(.scan.is-live) { max-width: none; }
.scan .panel { overflow: visible; }
#scanListToggle[aria-expanded="true"] { background: var(--color-primary-container); color: var(--color-on-primary-container); }

.scan-work { display: grid; grid-template-columns: 210px minmax(0, 1fr) 400px; gap: 16px; align-items: start; }
.scan-edit-btn { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; padding: 0; }
.scan-work-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.scan-work-main > .panel, .scan-recent, .scan-places, .scan-stats { margin-bottom: 0; }

/* Sortierplätze (links): große Platznummer, Schublade, Lots und Füllbalken grün -> rot */
.scan-places { position: sticky; top: 16px; display: flex; flex-direction: column; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); min-width: 0; padding: 16px 12px; }
.scan-places-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 4px 10px; }
.scan-places-add { width: 32px; height: 32px; }
.scan-places-form { display: flex; flex-direction: column; gap: 6px; margin: 0 0 10px; }
.scan-places-form[hidden] { display: none; }
.scan-places-form input { width: 100%; }
.scan-places-form .btn { flex: 1; justify-content: center; }
.scan-places-form-actions { display: flex; gap: 6px; }
.scan-places-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.scan-place { position: relative; display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 10px; align-items: center; padding: 8px; border: 2px solid transparent; border-radius: var(--radius-sm); background: var(--color-panel-raised); }
.scan-work.is-detail .scan-place { cursor: pointer; }
.scan-work.is-detail .scan-place:hover { border-color: var(--color-outline-variant); }
.scan-place-no { display: grid; place-items: center; height: 52px; border-radius: var(--radius-sm); background: var(--color-panel); font-size: 2rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.scan-place-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.scan-place-code { font-weight: 700; font-size: 0.98rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.scan-place-size { margin-left: 5px; }
.scan-place.is-full .scan-place-code .scan-place-size { text-decoration: none; }
.scan-place-count { font-size: 0.78rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
.scan-place-bar { display: block; height: 5px; border-radius: 3px; background: var(--color-line-soft); overflow: hidden; }
.scan-place-bar > span { display: block; height: 100%; border-radius: 3px; }
.scan-place.is-target { border-color: var(--color-stud); background: var(--color-primary-container); color: var(--color-on-primary-container); }
.scan-place.is-target .scan-place-no { background: var(--color-stud); color: var(--color-primary-container); }
.scan-place.is-target .scan-place-count { color: inherit; opacity: 0.85; }
.scan-place.is-full { opacity: 0.55; }
.scan-place.is-sated { border-style: dashed; border-color: var(--color-outline-variant); }
.scan-place.is-sated .scan-place-count { color: var(--color-warn, #e0a83e); font-weight: 600; }
.scan-place[draggable="true"] { cursor: grab; }
.scan-place.is-dragging { opacity: 0.4; border-style: dashed; border-color: var(--color-outline-variant); }
.scan-place.is-full .scan-place-code { text-decoration: line-through; }
/* X: Platz aus der Leiste nehmen (z. B. voll). Erscheint beim Darüberfahren, auf Touch immer. */
.scan-place-remove { position: absolute; top: 3px; right: 3px; display: grid; place-items: center; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--color-ink-soft); cursor: pointer; opacity: 0; }
.scan-place:hover .scan-place-remove, .scan-place-remove:focus-visible { opacity: 1; }
.scan-place-remove:hover { background: var(--state-hover); color: var(--color-danger); }
.scan-place.is-target .scan-place-remove { color: inherit; }
.scan-place .scan-place-code { padding-right: 16px; }
@media (hover: none) { .scan-place-remove { opacity: 0.7; } }
.scan-cam { position: relative; padding: 16px; }

/* Kamera so groß, wie das Fenster erlaubt. Nach dem Foto läuft das Video
   unsichtbar weiter (display:none hielte bei manchen Browsern die Bilder
   an, dann fotografierte die nächste Leertaste ein altes Bild). */
/* Bühne im Seitenverhältnis der Kamera (scan.js setzt --scan-cam-ratio): das ganze Bild, ohne Balken. */
.scan-stage { position: relative; aspect-ratio: var(--scan-cam-ratio, 16 / 9); background: #111; border-radius: var(--radius-sm); overflow: hidden; user-select: none; }
.scan-work.is-detail .scan-stage { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.scan-stage video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.scan-crop { position: absolute; border: 2px solid var(--color-stud); box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.38); border-radius: 6px; cursor: move; touch-action: none; }
.scan-crop[hidden] { display: none; }
.scan-crop-handle { position: absolute; right: 3px; bottom: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--color-stud); cursor: nwse-resize; }
.scan-cam-select { position: absolute; top: 10px; right: 10px; width: auto; max-width: 50%; z-index: 2; }
.scan-cam-select[hidden] { display: none; }
.scan-stage-msg { position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); max-width: calc(100% - 32px); padding: 8px 16px; border-radius: var(--radius-pill); background: rgba(0, 0, 0, 0.7); color: #fff; font-size: 0.9rem; text-align: center; }
.scan-stage-msg[hidden] { display: none; }
.scan-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; }
.scan-flash.is-on { animation: scanFlash 260ms ease-out; }
@keyframes scanFlash { from { opacity: 0.55; } to { opacity: 0; } }

.scan-search { position: relative; margin-top: 12px; }
/* Teil-Ansicht: Kamera und Suche weg (unsichtbar statt display:none, s. o.). */
.scan-work.is-detail .scan-cam { position: absolute; width: 1px; height: 1px; padding: 0; border: 0; overflow: hidden; opacity: 0; pointer-events: none; }
.scan-search-results { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; right: 0; max-height: 320px; overflow-y: auto; background: var(--color-panel-raised); border: 1px solid var(--color-outline-variant); border-radius: var(--radius-sm); box-shadow: var(--elevation-1); }
.scan-search-results[hidden] { display: none; }
.scan-result { display: block; width: 100%; text-align: left; padding: 8px 12px; border: 0; border-bottom: 1px solid var(--color-line-soft); background: transparent; color: inherit; font: inherit; font-size: 0.86rem; cursor: pointer; }
.scan-result:hover { background: var(--state-hover); }
.scan-detail[hidden] { display: none; }

/* Lagerort groß (links) | Teil mit Alternativen (Mitte) | Farbe, Zustand, Menge, Preis (rechts) */
.scan-detail-grid { display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.7fr) minmax(0, 0.85fr); grid-template-areas: "loc part fields"; gap: 24px; align-items: start; }
.scan-col-loc { grid-area: loc; }
.scan-col-part { grid-area: part; }
.scan-col-fields { grid-area: fields; }
.scan-col { min-width: 0; }
.scan-col-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px 10px; margin-bottom: 10px; }
.scan-col-title { margin: 0; font-size: 1rem; }
.scan-part-info { margin-bottom: 12px; }
.scan-part-no .sku { font-size: 1.5rem; font-weight: 800; }
.scan-part-no a.sku { color: inherit; text-decoration: none; }
.scan-part-no a.sku:hover { color: var(--color-brick); text-decoration: underline; text-underline-offset: 3px; }
.scan-part-alt { font-size: 0.82rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
.scan-part-name { margin: 2px 0 4px; font-size: 0.92rem; }
.scan-part-name a { color: inherit; text-decoration: none; }
.scan-part-name a:hover { color: var(--color-brick); text-decoration: underline; text-underline-offset: 3px; }

/* Treffer und Alternativen als Bildkacheln unter den Teil-Angaben */
.scan-cands { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.scan-cands:empty { display: none; }
.scan-cand { position: relative; aspect-ratio: 5 / 4; border: 4px solid transparent; border-radius: var(--radius-sm); background: #fff; overflow: hidden; cursor: pointer; }
.scan-cand:hover { border-color: var(--color-outline-variant); }
.scan-cand.is-selected { border-color: var(--color-stud); }
.scan-cand img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: 14px 14px 30px; }
.scan-cand.no-img::before { content: 'kein Bild'; position: absolute; inset: 0; display: grid; place-items: center; color: #8a8a8a; font-size: 0.85rem; }
.scan-cand-key { position: absolute; top: 6px; left: 6px; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: rgba(0, 0, 0, 0.62); color: #fff; font-size: 0.9rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.scan-cand.is-selected .scan-cand-key { background: var(--color-stud); color: var(--color-primary-container); }
.scan-cand-pct { position: absolute; left: 6px; bottom: 6px; padding: 1px 7px; border-radius: 5px; background: rgba(0, 0, 0, 0.5); color: #fff; font-size: 0.8rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.scan-cand-no { position: absolute; right: 6px; bottom: 6px; padding: 1px 7px; border-radius: 5px; background: rgba(0, 0, 0, 0.72); color: #fff; font-size: 0.82rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.scan-cand.is-stock::after { content: ''; position: absolute; top: 9px; right: 9px; width: 10px; height: 10px; border-radius: 50%; background: var(--color-ok); box-shadow: 0 0 0 2px #fff; }
.scan-stock { font-size: 0.74rem; color: var(--color-ink-soft); }
.scan-stock.is-in { color: var(--color-ok); font-weight: 600; }

.scan-loc-options { display: flex; flex-wrap: wrap; gap: 6px; }
.scan-loc-options { margin-top: 6px; }
.scan-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1px solid var(--color-outline-variant); border-radius: var(--radius-pill); background: transparent; color: inherit; font: inherit; font-size: 0.8rem; cursor: pointer; }
.scan-chip:hover { background: var(--state-hover); }
.scan-chip.is-active { border-color: var(--color-stud); background: var(--color-primary-container); color: var(--color-on-primary-container); }
.scan-chip.is-full { opacity: 0.6; text-decoration: line-through; }
.scan-chip small { color: inherit; opacity: 0.75; }
.scan-chip input { width: auto; margin: 0; }
/* Lagerort-Vorschläge (Stufe 4) */
/* Lagerort und gewählte Farbe untereinander, beide über die ganze Spaltenbreite:
   der Lagerort groß, die Farbe flacher darunter. Die Farbe füllt ihr Feld ganz,
   damit eine falsch erkannte Farbe neben dem echten Teil sofort auffällt. */
.scan-hero-pair { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.scan-hero-pair > .scan-loc-hero { margin-bottom: 0; }
.scan-color-hero { container-type: inline-size; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; width: 100%; padding: 12px 14px; border: 1px solid var(--color-outline-variant); border-radius: var(--radius); font: inherit; text-align: center; cursor: pointer; color: #fff; }
.scan-color-hero.is-light { color: #1b1b1b; }
.scan-color-hero.is-empty { background: var(--color-surface-container-high); color: var(--color-ink-soft); }
.scan-color-hero-label { font-size: 0.8rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.85; }
.scan-color-hero-name { font-size: clamp(1.15rem, 7cqi, 1.9rem); font-weight: 800; line-height: 1.1; overflow-wrap: anywhere; }
.scan-color-hero-score { font-size: 0.95rem; font-weight: 600; font-variant-numeric: tabular-nums; opacity: 0.85; }
.scan-color-hero-score:empty { display: none; }
.scan-color-hero.is-unknown { outline: 3px dashed var(--color-warn); outline-offset: 3px; }
.scan-color-hero-warn { padding: 3px 10px; border-radius: 999px; background: var(--color-warn); color: #1b1b1b; font-size: 0.82rem; font-weight: 700; }
.scan-color-hero-warn[hidden] { display: none; }
.scan-loc-hero { container-type: inline-size; display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 24px 16px; margin-bottom: 12px; border-radius: var(--radius); background: var(--color-primary-container); color: var(--color-on-primary-container); text-align: center; }
.scan-loc-hero.is-empty { background: var(--color-surface-container-high); color: var(--color-ink-soft); }
.scan-loc-hero-no { display: grid; place-items: center; min-width: 1.2em; height: 1.2em; padding: 0 0.12em; border-radius: 0.14em; background: var(--color-stud); color: var(--color-primary-container); font-size: clamp(2rem, 16cqi, 3.6rem); font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
.scan-loc-hero-no[hidden] { display: none; }
.scan-loc-hero-code { font-size: clamp(2.4rem, 25cqi, 5.6rem); font-weight: 800; line-height: 1.05; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.scan-suggests { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.scan-suggest { display: flex; align-items: flex-start; gap: 8px; width: 100%; padding: 6px 10px; border: 1px solid var(--color-outline-variant); border-radius: var(--radius-sm); background: transparent; color: inherit; font: inherit; font-size: 0.85rem; text-align: left; cursor: pointer; }
.scan-suggest:hover { background: var(--state-hover); }
.scan-suggest.is-active { border-color: var(--color-stud); background: var(--color-primary-container); color: var(--color-on-primary-container); }
.scan-suggest-text { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; min-width: 0; }
.scan-suggest-label { font-size: 0.75rem; opacity: 0.75; }
.scan-suggest-text small { flex-basis: 100%; opacity: 0.8; }
.scan-suggest-hint { color: var(--color-warn); opacity: 1 !important; }
.scan-suggest-box, .scan-suggest-warn { padding: 6px 10px; border-radius: var(--radius-sm); background: rgba(224, 168, 62, 0.16); font-size: 0.82rem; }
/* Füllmenge am gewählten Ort: vorher -> nachher, darunter der Balken der Schublade. */
.scan-fill { container-type: inline-size; padding: 10px; border: 1px solid var(--color-outline-variant); border-radius: var(--radius); background: var(--color-surface-container-high); }
.scan-fill[hidden] { display: none; }
.scan-fill-row { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 4px; }
.scan-fill-side { display: flex; flex-direction: column; min-width: 0; }
.scan-fill-side.is-after { align-items: flex-end; text-align: right; }
.scan-fill-big { font-size: clamp(1.1rem, 11cqi, 1.6rem); font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.scan-fill-big.is-over { color: var(--color-danger); }
.scan-fill-sub { font-size: 0.82rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
.scan-fill-arrow { color: var(--color-ink-soft); }
.scan-fill-bar { display: flex; height: 6px; margin-top: 8px; border-radius: 3px; overflow: hidden; background: var(--color-outline-variant); }
.scan-fill-bar .is-base { background: var(--color-ink-soft); }
.scan-fill-bar .is-moved { background: var(--color-warn); }
.scan-fill-bar .is-added { background: var(--color-ok); }
.scan-fill-note { margin-top: 6px; font-size: 0.8rem; color: var(--color-warn); }
.scan-fill-note.is-danger { color: var(--color-danger); font-weight: 600; }
.scan-suggest.is-disabled { cursor: default; color: var(--color-ink-soft); opacity: 0.6; }
.scan-suggest.is-disabled:hover { background: transparent; }

.scan-drawer-choices { display: flex; flex-wrap: wrap; gap: 6px; }
.scan-drawer-choices[hidden] { display: none; }
.scan-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: -1px; margin-right: 4px; flex: none; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14); }

/* Farbe: Eingabefeld mit Liste samt Farbfläche (wie der Farbfilter der Artikelübersicht) */
.scan-color-combo { position: relative; }
.scan-color-combo-swatch { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 22px; height: 22px; border-radius: 5px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14); pointer-events: none; }
.scan-color-combo input { width: 100%; padding-left: 42px; }
.scan-color-combo-score { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); padding: 1px 7px; border-radius: var(--radius-pill); background: var(--color-surface-container-high); color: var(--color-ink-soft); font-size: 0.76rem; font-variant-numeric: tabular-nums; pointer-events: none; }
.scan-color-combo-score:not([hidden]) + input { padding-right: 64px; }
.scan-color-combo-score[hidden] { display: none; }
.scan-color-list { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0; max-height: 340px; overflow-y: auto; overscroll-behavior: contain; margin: 0; padding: 6px; list-style: none; background: var(--color-surface-container-high); border: 1px solid var(--color-outline-variant); border-radius: var(--radius); box-shadow: var(--elevation-3); }
.scan-color-list[hidden] { display: none; }
.scan-color-opt { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: var(--radius-sm); font-size: 0.86rem; cursor: pointer; }
.scan-color-opt:hover { background: var(--state-hover); }
.scan-color-opt.is-active { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.scan-color-opt-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scan-color-opt-score { flex: none; font-size: 0.76rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.scan-color-opt-id { flex: none; font-size: 0.76rem; opacity: 0.6; font-variant-numeric: tabular-nums; }
.scan-color-sep { margin: 6px 0 2px; padding: 6px 8px 2px; border-top: 1px solid var(--color-outline-variant); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-ink-soft); }
.scan-color-opt.is-unknown { opacity: 0.6; }
.scan-color-empty { padding: 10px 8px; font-size: 0.85rem; color: var(--color-ink-soft); }

.scan-col-fields { display: flex; flex-direction: column; gap: 22px; }
.scan-field { min-width: 0; }
.scan-loc-field { display: flex; flex-direction: column; align-items: center; text-align: center; }
.scan-loc-field input { width: 100%; max-width: 160px; text-align: center; font-weight: 700; }
.scan-loc-full { margin-top: 6px; font-size: 0.78rem; }
.scan-loc-outside { margin-bottom: 14px; }
.scan-loc-field .scan-loc-options { justify-content: center; margin-top: 10px; }
.scan-field > label { display: block; font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-ink-soft); margin-bottom: 8px; }
.scan-field > label kbd { text-transform: none; letter-spacing: 0; }
.scan-field .seg { margin: 0; }
.scan-qty { display: flex; align-items: center; gap: 8px; }
.scan-qty .btn { width: 40px; height: 40px; padding: 0; justify-content: center; border-radius: 50%; font-size: 1.1rem; }
.scan-qty input { width: 96px; text-align: center; font-weight: 700; }
.scan-price { padding: 14px 16px; border-radius: var(--radius); background: var(--color-surface-container-high); font-size: 0.86rem; }
.scan-price-main { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.scan-price-label { font-weight: 700; }
.scan-price .scan-price-main input { flex: 0 0 auto; width: 84px; text-align: right; font-weight: 700; }
.scan-price.md3-field input:hover, .scan-price.md3-field input:focus { background: var(--color-panel); }
.scan-price-avg { margin-top: 8px; line-height: 1.5; }
/* Marktreichweite: Stufe nur als Farbpunkt (Farben wie .pg-range-badge), mittig neben den Monaten. */
.scan-range { display: inline-flex; align-items: center; gap: 7px; vertical-align: top; }
.scan-range-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; }
.scan-range-dot.is-fast { background: var(--color-ok); }
.scan-range-dot.is-normal { background: #7fc4ff; }
.scan-range-dot.is-slow { background: var(--color-warn); }
.scan-range-dot.is-stale, .scan-range-dot.is-none { background: var(--color-danger); }
.scan-add { width: 100%; justify-content: center; min-height: 48px; font-size: 0.95rem; }
.scan-add kbd { margin-left: 8px; color: inherit; background: transparent; border-color: currentColor; opacity: 0.8; }

/* Rechts: zuletzt gescannt, neuester oben */
.scan-side { position: sticky; top: 16px; display: flex; flex-direction: column; gap: 12px; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); min-width: 0; }
.scan-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); padding: 14px 8px; }
.scan-stats:empty { display: none; }
.scan-stat { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0; padding: 0 6px; text-align: center; }
.scan-stat + .scan-stat { border-left: 1px solid var(--color-line-soft); }
.scan-stat strong { font-size: 1.35rem; font-weight: 800; line-height: 1.15; font-variant-numeric: tabular-nums; white-space: nowrap; }
.scan-stat span { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--color-ink-soft); }
.scan-recent { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; padding: 16px; }
.scan-recent-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: 10px; }
.scan-recent-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; list-style: none; margin: 0 -6px; padding: 0 6px; }
.scan-recent-item { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 10px; align-items: center; padding: 8px; border-radius: var(--radius-sm); cursor: pointer; }
.scan-recent-item + .scan-recent-item { margin-top: 4px; }
.scan-recent-item:hover { background: var(--state-hover); }
.scan-recent-item.is-latest { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.scan-recent-item.is-flash { animation: scanRecentIn 600ms ease-out; }
@keyframes scanRecentIn { from { transform: translateX(16px); opacity: 0; } to { transform: none; opacity: 1; } }
.scan-recent-item img { width: 52px; height: 44px; object-fit: contain; background: #fff; border-radius: 6px; }
.scan-recent-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: 0.82rem; }
.scan-recent-top { display: flex; align-items: baseline; gap: 8px; }
.scan-recent-qty { font-weight: 800; font-size: 0.95rem; font-variant-numeric: tabular-nums; }
.scan-recent-loc { margin-left: auto; font-weight: 700; white-space: nowrap; }
.scan-recent-name, .scan-recent-color { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scan-recent-color { opacity: 0.8; }
.scan-recent-empty { margin: 8px 0; font-size: 0.86rem; }
.scan-recent-empty[hidden] { display: none; }
.scan-recent-foot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--color-line-soft); font-size: 0.78rem; }

.scan-list-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; margin-bottom: 10px; }
.scan-list-head h2 { margin: 0; }
.scan-list-close { margin-left: auto; }
.scan-list-panel[hidden] { display: none; }
.scan-list-wrap { overflow-x: auto; }
table.scan-list { min-width: 920px; }
.scan-list td { vertical-align: middle; }
.scan-col-img { width: 52px; }
.scan-col-del { width: 44px; }
.scan-list .scan-cell-input { width: 74px; padding: 5px 10px; font-size: 0.86rem; }
.scan-cell-qty { display: inline-flex; align-items: center; gap: 4px; }
.scan-list .scan-cell-qty .scan-cell-input { width: 48px; padding: 5px 4px; text-align: center; -moz-appearance: textfield; }
.scan-cell-qty .scan-cell-input::-webkit-inner-spin-button, .scan-cell-qty .scan-cell-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.scan-cell-step { display: grid; place-items: center; width: 26px; height: 26px; padding: 0; border: 1px solid var(--color-outline-variant); border-radius: 50%; background: var(--color-panel-raised); color: var(--color-ink); font-size: 1rem; line-height: 1; cursor: pointer; }
.scan-cell-step:hover { background: var(--color-panel); border-color: var(--color-stud); }
.scan-list .scan-cell-loc { width: 110px; }
.scan-list-name { font-weight: 600; }
.scan-list-bl { font-size: 0.82rem; color: var(--color-brick); text-decoration: none; }
.scan-list-bl:hover { text-decoration: underline; text-underline-offset: 3px; }
.scan-list td:nth-child(3), .scan-list td:nth-child(4) { white-space: nowrap; }
/* Abgeschlossene Liste: unter 760px Karten wie die übrigen Tabellen statt Querscrollen */
@media (max-width: 760px) {
    table.scan-list.cards-ready { min-width: 0; }
    /* Titel ist der Name; die BL-Nummer darunter bleibt klein und blau wie am Desktop */
    table.scan-list.cards-ready td.card-cell-title .card-val > .scan-list-bl { display: block; font-size: 0.85rem; font-weight: 600; color: var(--color-brick); }
}
.scan-list tr.is-new td { background: var(--color-primary-container); }
.scan-form .seg { margin: 0; }
/* Feldtitel wie bei .md3-field, auch über Zustand und Schubladen */
.scan-form .field > label { font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; }
.scan-delete-form { margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--color-line-soft); }

/* Schmaler: Lagerort bleibt links, rechts oben die Felder (Übernehmen ohne Scrollen), darunter das Teil. */
@media (max-width: 1500px) {
    .scan-detail-grid { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); grid-template-areas: "loc fields" "loc part"; gap: 20px; }
    .scan-cands { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 10px; }
}
@media (max-width: 1500px) {
    .scan-work { grid-template-columns: 150px minmax(0, 1fr) 340px; gap: 12px; }
    .scan-stat strong { font-size: 1.15rem; }
    .scan-places { padding: 14px 8px; }
    .scan-place { grid-template-columns: 38px minmax(0, 1fr); gap: 7px; padding: 6px; }
    .scan-place-no { height: 42px; font-size: 1.5rem; }
    .scan-place-count { font-size: 0.72rem; }
    /* Schmale Leiste: × neben der Lot-Zahl statt neben dem Code, damit der ganz bleibt. */
    .scan-place .scan-place-code { padding-right: 0; font-size: 0.9rem; }
    .scan-place-size { width: 16px; height: 16px; margin-left: 3px; vertical-align: -3px; }
    .scan-place-remove { top: auto; bottom: 11px; right: 2px; width: 20px; height: 20px; }
}
@media (max-width: 1100px) {
    .scan-work { grid-template-columns: minmax(0, 1fr); }
    .scan-side { position: static; max-height: none; }
    .scan-recent, .scan-places { position: static; max-height: 420px; }
    .scan-places-list { flex-direction: row; overflow-x: auto; }
    .scan-place { flex: 0 0 166px; }
}
@media (max-width: 700px) {
    .scan-detail-grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "loc" "part" "fields"; }
    .scan-head-actions { width: 100%; flex-wrap: wrap; }
}

/* --- Wareneingang: Startseite (intake.php) ---
   Zwei große Startkacheln nebeneinander (Teilescan, XML-Import), darunter die
   Liste aller Wareneingänge. Die Kacheln öffnen das Fenster mit der Seite im
   iframe (.intake-dialog, Grundgerüst von .invoice-preview-dialog). */
.intake-start { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-bottom: 24px; }
.intake-tile {
    position: relative;
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 24px;
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius);
    background: var(--color-panel);
    box-shadow: var(--elevation-1);
    color: var(--color-ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.intake-tile:hover { background: var(--color-panel-raised); border-color: var(--color-brick); }
.intake-tile:focus-visible { outline: 2px solid var(--color-brick); outline-offset: 2px; }
.intake-tile:disabled { opacity: 0.5; cursor: not-allowed; }
.intake-tile-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}
.intake-tile-icon svg { width: 26px; height: 26px; }
.intake-tile-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.intake-tile-text strong { font-size: 1.15rem; font-weight: 700; }
.intake-tile-text span { font-size: 0.86rem; color: var(--color-ink-soft); }
.intake-tile-note { position: absolute; top: 14px; right: 16px; padding: 2px 10px; border-radius: var(--radius-pill); background: rgba(224,168,62,0.16); color: var(--color-warn); font-size: 0.78rem; font-weight: 600; }
.intake-table tr.intake-row { cursor: pointer; }
.intake-kind { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; }
.intake-kind svg { width: 16px; height: 16px; color: var(--color-ink-soft); }
.intake-kind + .badge { margin-left: 6px; }
.intake-sub { font-size: 0.8rem; margin-top: 2px; }
/* Neuer Teilescan: Formular mit Schubladen-Chips, höher als das Label-Fenster */
/* Bis der Inhalt gemessen ist (openIntakeDialog): unsichtbar und ohne
   Einblend-Animation; die startet beim Entfernen der Klasse neu. */
.app-dialog.intake-dialog.is-measuring { visibility: hidden; animation: none; }
.app-dialog.invoice-preview-dialog.intake-dialog--scan.is-compact { width: min(620px, calc(100vw - 32px)); }
/* XML-Import im Fenster: Eingabe und Vorschau liegen direkt auf der Dialogfläche statt als Karte darin. */
body.embed-layout .import-main-panel { background: transparent; border: none !important; box-shadow: none; padding: 0; margin-bottom: 0; overflow: visible; }
@media (max-width: 760px) {
    .intake-start { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .intake-tile { padding: 18px; gap: 14px; }
    .intake-tile-icon { width: 46px; height: 46px; }
}
/* Formulare in den Fenstern von intake.php (Neuer Teilescan, Neuer XML-Import)
   im Stil des Versandlabel-Fensters: Felder direkt auf der Dialogfläche, deren
   Ton (surface-container-high) gleich der normalen Hover-Farbe ist - Hover
   deshalb eine Stufe heller, Fokus mit blauem Rand. Knöpfe rechtsbündig,
   Abbrechen neutral davor. */
.intake-embed-form .field:last-of-type { margin-bottom: 0; }
/* Feldtitel wie .md3-field auch über Ablagefläche (deren Datei-Feld trägt keine Pillenoptik) */
.intake-embed-form .field > label { font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; }
body.embed-layout .intake-embed-form .md3-field input:hover,
body.embed-layout .intake-embed-form .md3-dropdown-trigger:hover { background: var(--color-line); }
/* Große Fläche: volle Hover-Farbe wirkt zu laut, nur leicht aufhellen. */
body.embed-layout .intake-embed-form .md3-field textarea:hover { background: color-mix(in srgb, var(--color-panel-raised) 65%, var(--color-line)); }
body.embed-layout .intake-embed-form .md3-field input:focus,
body.embed-layout .intake-embed-form .md3-field textarea:focus {
    background: var(--color-panel-raised);
    box-shadow: inset 0 0 0 1px var(--color-brick);
}
.intake-embed-form .md3-dropdown,
.intake-embed-form .md3-dropdown-trigger { width: 100%; }
.intake-embed-form .md3-field textarea {
    width: 100%;
    background: var(--color-panel-raised);
    border: none;
    border-radius: 16px;
    padding: 12px 16px;
    font-family: ui-monospace, Consolas, 'Courier New', monospace;
    font-size: 0.85rem;
    resize: vertical;
    transition: background 0.15s;
}
.intake-form-actions, .scan-form-actions { justify-content: flex-end; margin: 20px 0 0; }
.import-input-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 18px; }
.import-input-head .seg { margin: 0; }
/* Fenstertitel sagt schon "Vorschau" */
body.embed-layout .import-main-panel > h2:first-child { display: none; }
.scan-last-drawers { display: flex; align-items: center; gap: 14px; margin: 4px 0 0; padding: 12px 16px; background: var(--color-panel-raised); border-radius: 16px; font-size: 0.92rem; cursor: pointer; }
.scan-last-drawers input { flex: none; width: 20px; height: 20px; margin: 0; accent-color: var(--color-brick); }
.intake-conds { white-space: nowrap; }
.intake-table th.text-center, .intake-table td.text-center { text-align: center; }
/* Die fünf Artikel mit den meisten Teilen als leicht überlappende Kreise vor dem Titel. */
.intake-name { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* Feste Breite für fünf Kreise, damit die Titel auch bei weniger Artikeln bündig stehen. */
.intake-stack { display: inline-flex; flex: none; width: 130px; }
.intake-stack-item {
    width: 34px; height: 34px; border-radius: 50%; overflow: hidden; flex: none;
    background: #fff; border: 2px solid var(--color-table);
    display: inline-flex; align-items: center; justify-content: center;
}
.intake-stack-item + .intake-stack-item { margin-left: -10px; }
.intake-stack-item img { width: 100%; height: 100%; object-fit: contain; padding: 3px; box-sizing: border-box; }

/* Gemeinsame Detailansicht Teilescan / XML-Import (app_includes/intake_detail.php). */
.intake-detail-head { display: flex; align-items: center; gap: 20px; margin-bottom: 20px; }
.intake-detail-titles { min-width: 0; }
.intake-detail-titles h1 { margin: 0 0 8px; }
.intake-detail-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; color: var(--color-ink-soft); font-size: 0.88rem; }
.intake-detail-meta .badge { margin: 0; }
.intake-detail-kpis { display: grid; grid-template-columns: repeat(var(--kpi-count, 4), minmax(0, 1fr)); }
.badge.intake-pv-badge { margin-left: 6px; font-size: 0.7rem; padding: 1px 8px; }
.intake-detail-filter { margin-bottom: 12px; }
button.notif-tab { border: 0; background: none; cursor: pointer; font-family: inherit; }
/* Positionsfilter: auch die nicht gewählten Reiter bekommen eine leichte
   eigene Fläche auf der Schiene (weißer Schleier statt fester Farbe, damit
   es auch auf der helleren Schiene im Fenster passt). Die Zahl setzt sich
   über Abstand, normale statt fetter Schrift und Weiß vom Text ab. */
.intake-detail-filter .notif-tabs { gap: 4px; }
.intake-detail-filter .notif-tab:not(.is-active) { background: rgba(255,255,255,0.05); }
.intake-detail-filter .notif-tab:not(.is-active):hover { background: rgba(255,255,255,0.09); }
.intake-tab-count { margin-left: 8px; font-weight: 400; color: #ffffff; font-variant-numeric: tabular-nums; }
.intake-detail-table th.text-center, .intake-detail-table td.text-center { text-align: center; }
.intake-detail-table td.num { white-space: nowrap; }
.intake-detail-item { display: flex; align-items: center; gap: 12px; }
.intake-detail-thumb { flex: none; }
.intake-detail-name { color: var(--color-ink); font-weight: 600; text-decoration: none; }
.intake-detail-name:hover { color: var(--color-brick); }
.intake-detail-sub { font-size: 0.78rem; margin-top: 2px; }
.intake-qty { font-weight: 600; }
/* Lagerort-Änderung: alt grau, Pfeil nach unten, neu fett. */
.intake-loc-move { display: inline-flex; flex-direction: column; align-items: center; gap: 1px; line-height: 1.3; }
.intake-loc-move svg { color: var(--color-ink-soft); }
.intake-loc-move .text-soft { font-size: 0.82rem; }
.intake-qty.is-plus { color: var(--color-ok); }
.intake-qty.is-minus { color: var(--color-danger); }
@media (max-width: 760px) {
    .intake-detail-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .intake-detail-filter .notif-tabs { overflow-x: auto; max-width: 100%; scrollbar-width: none; }
}
.badge.intake-cond { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border-radius: 50%; }
.badge.intake-cond + .badge.intake-cond { margin-left: 4px; }
.badge.intake-cond svg { margin: 0 !important; vertical-align: 0 !important; width: 15px; height: 15px; }
.scan-last-drawers small { display: block; margin-top: 2px; font-size: 0.8rem; }
/* Vorschau im Fenster: Kennzahlen und Hinweisblöcke als Tonkarten wie im
   Versandlabel-Fenster (.label-create-box), nicht als Karten mit Rahmen. */
body.embed-layout .import-main-panel .kpi-card,
body.embed-layout .import-main-panel .panel {
    background: var(--color-panel-raised);
    border-top: none;
    border-right: none;
    border-bottom: none;
    box-shadow: none;
    border-radius: 16px;
}
body.embed-layout .import-main-panel .kpi-card { border-left: none; }
/* Die Reiter-Fläche (surface-container-high) ist genau die Fensterfläche - eine Stufe dunkler wie die Kacheln. */
body.embed-layout .notif-tabs { background: var(--color-panel-raised); }
