/* === Stadt und Gemeinschaft Wien — Shared Component Patterns === */
/* ==========================================================================
   Consolidated patterns used across multiple page-specific CSS files.
   Loaded after base.css, before page-specific styles.
   ========================================================================== */


/* --- Card surface ---
   Shared base for card-like containers (white bg, subtle border, rounded).
   Page-specific overrides (border-top, border-left colours, padding)
   are applied in their respective CSS files.
   ------------------------------------------------------------------ */

.doc-body, .facs-viewer, .index-table-wrap,
.stats-kpi, .stats-chart-card, .stats-collection-card,
.explore-panel, .explore-hub-card, .explore-header-unified, .explore-filter-header,
.start-entry-card {
    background: var(--color-bg-card);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}


/* --- Tooltip base ---
   Shared structure for all tooltip variants (edition, statistics, exploration).
   Per-variant font-size, padding, max-width, and transform stay in their
   respective CSS files.
   ------------------------------------------------------------------ */

.stats-tooltip, .explore-tooltip {
    position: fixed;
    z-index: var(--z-tooltip);
    /* Visuell konsistent mit der tip-Popover-Familie: helles Card mit
       Border und dezentem Schatten. Wird von chart-helpers.js fuer
       Statistik-Mouseover und von Exploration-JS fuer Visualisierungs-
       Hover gerendert. Hover-Hints fuer einfache UI-Elemente nutzen
       stattdessen [data-hint] mit der .tip-hint-Klasse aus tip.css. */
    background: var(--color-bg-card);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    font-family: var(--font-sans);
    border-radius: 4px;
    box-shadow: 0 8px 28px rgba(44, 40, 37, 0.10), 0 1px 3px rgba(44, 40, 37, 0.06);
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

/* WCAG 1.4.13: tooltip hoverable + persistent when visible */
.stats-tooltip.visible, .explore-tooltip.visible {
    opacity: 1;
    pointer-events: auto;
}


/* --- Cross-cutting JS-rendered table patterns ---
   Used by table-infra, drill-down, register, index, exploration-* and
   chart-helpers when injecting HTML at runtime. Replacing prior
   inline-style strings.
   ------------------------------------------------------------------ */

/* Centred placeholder text for loading / empty states inside tables and
   chart containers. Always paired with colspan on the wrapping <td>. */
.cell-placeholder {
    text-align: center;
    padding: 2rem;
    color: var(--color-text-muted);
}

/* Invisible sentinel row used by IntersectionObserver-driven progressive
   table rendering. Carries no visual weight. */
.table-sentinel {
    height: 1px;
    padding: 0;
    border: none;
}

/* Inline secondary text in dynamic markup (e.g. label variants). */
.text-muted-inline {
    color: var(--color-text-muted);
}


/* ==========================================================================
   Knowledge basket — site-wide collector component. A small button next to
   each source row in lists and drill-downs; a nav icon with a badge shows
   the current item count; a dedicated page (korb.html) lists the contents.
   UI label "Datenkorb" stays German; CSS class names use the English
   "basket".
   ========================================================================== */

/* Datenkorb-Knopf. Drei Zustaende teilen sich Form, Groesse und
   Position; nur die Glyphe und die Akzent-Farbe wechseln. Der Knopf
   liegt in einer eigenen schmalen Tabellenspalte (col-basket) ganz
   rechts und springt deshalb nie. */
.basket-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-left: 0;
    padding: 0;
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: 50%;
    line-height: 1;
    color: var(--color-text-muted);
    cursor: pointer;
    vertical-align: middle;
    transition: border-color var(--transition-fast),
                background-color var(--transition-fast),
                color var(--transition-fast);
}
.basket-btn-icon {
    width: 12px;
    height: 12px;
    display: block;
}
.basket-btn:hover {
    border-color: var(--anno-place);
    color: var(--anno-place);
    background: color-mix(in srgb, var(--anno-place) 8%, transparent);
}

/* Zustand "im Korb": gleiche Outline-Form, aber Border in Akzentfarbe
   und ein dezenter Tint im Inneren. Glyphe wird vom Plus zum Haekchen
   gewechselt (im JS). Kein Vollfarb-Kreis mehr - das wirkte wie ein
   anderer UI-Typ und las sich mit dem "x" als Schliessen-Knopf. */
.basket-btn.is-in {
    border-color: var(--anno-place);
    background: color-mix(in srgb, var(--anno-place) 8%, transparent);
    color: var(--anno-place);
}
/* Hover-Vorschau "Klick entfernt": Haekchen wird zum Minus, Border und
   Tint kraeftiger, damit klar ist, dass der naechste Klick etwas tut.
   Glyphen-Umschaltung ueber zwei Pfade im SVG (siehe basket.js
   SVG_CHECK) statt CSS "d:", weil das Safari-kompatibel ist. */
.basket-btn.is-in:hover {
    background: color-mix(in srgb, var(--anno-place) 14%, transparent);
}
.basket-btn-icon .glyph-minus { display: none; }
.basket-btn.is-in:hover .basket-btn-icon .glyph-check { display: none; }
.basket-btn.is-in:hover .basket-btn-icon .glyph-minus { display: inline; }

.nav-basket {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin-left: var(--space-sm);
    color: var(--color-text-inverse);
    text-decoration: none;
    padding: 6px;
    border-radius: 4px;
    transition: background-color var(--transition-fast);
}
.nav-basket:hover { background: rgba(255, 255, 255, 0.1); }
.nav-basket-counts {
    display: inline-flex;
    gap: 3px;
    margin-left: 5px;
}
.nav-basket-counts[hidden] { display: none; }
.nav-basket-pill {
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    color: #fff;
    font-family: var(--font-sans);
    font-size: 10px;
    font-weight: 600;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.nav-basket-pill--source { background: var(--anno-place); }
.nav-basket-pill--person { background: var(--anno-person); }
.nav-basket-pill--org    { background: var(--anno-org); }

/* Basket page */
.basket-page .index-header,
.basket-page .basket-header {
    margin-bottom: var(--space-md);
    text-align: left;
    border-bottom: 1px solid var(--color-border-light);
    padding-bottom: var(--space-sm);
}
.basket-page .basket-header h1 {
    margin-bottom: 4px;
}
.basket-page .basket-subtitle {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--text-sm);
    max-width: 70ch;
}
.basket-page .basket-explainer {
    margin-top: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: var(--color-bg-warm);
    border-left: 3px solid var(--color-border);
    max-width: 70ch;
    font-size: var(--text-sm);
}
.basket-page .basket-explainer p {
    margin: 0 0 var(--space-xs) 0;
    color: var(--color-text);
    line-height: 1.45;
}
.basket-page .basket-explainer p:last-child {
    margin-bottom: 0;
}
.basket-page .basket-explainer strong {
    color: var(--color-text);
    font-weight: 600;
}
.basket-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-md);
    flex-wrap: wrap;
    margin-bottom: var(--space-md);
    padding-bottom: var(--space-sm);
    border-bottom: 1px solid var(--color-border-light);
}
.basket-count {
    font-family: var(--font-sans);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}
.basket-filter {
    display: flex;
    gap: var(--space-xs);
    flex-wrap: wrap;
}
.basket-chip {
    font-family: var(--font-sans);
    font-size: var(--text-sm);
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    padding: 2px var(--space-sm);
    cursor: pointer;
    color: var(--color-text);
    transition: all var(--transition-fast);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.basket-chip:hover { background: var(--color-bg-hover); }
.basket-chip.is-active {
    background: var(--color-text);
    color: #fff;
    border-color: var(--color-text);
}
.basket-chip-count {
    font-size: var(--text-xs);
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
}
.basket-actions { display: flex; gap: var(--space-sm); flex-wrap: wrap; }
.basket-table .col-type { width: 110px; }
.explore-btn--danger {
    border-color: var(--color-border);
    color: var(--color-text-muted);
}
.explore-btn--danger:hover {
    background: color-mix(in srgb, var(--anno-fn-issuer) 10%, transparent);
    color: var(--anno-fn-issuer);
    border-color: var(--anno-fn-issuer);
}
.basket-table .col-actions { width: 36px; text-align: right; }
.basket-row-remove {
    background: transparent;
    border: 1px solid transparent;
    border-radius: 50%;
    width: 22px;
    height: 22px;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    color: var(--color-text-light);
    transition: all var(--transition-fast);
}
.basket-row-remove:hover {
    background: color-mix(in srgb, var(--anno-fn-issuer) 10%, transparent);
    color: var(--anno-fn-issuer);
    border-color: var(--anno-fn-issuer);
}
.basket-table .cell-regest {
    max-width: 480px;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

/* Basket sections (per-type)
   Card-Layout: weisser Hintergrund, Rahmen drum, sanfter Schatten. Der
   Section-Container traegt die Card-Optik, damit Header und Tabelle
   eine zusammenhaengende Flaeche bilden. */
.basket-section {
    margin-bottom: var(--space-xl);
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.basket-section-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: var(--space-md);
    flex-wrap: wrap;
    margin-bottom: 0;
    padding: var(--space-sm) var(--space-md);
    background: #fff;
    border-bottom: 1px solid var(--color-border-light);
}
.basket-section-head h2 {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-weight: 600;
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: var(--space-sm);
}
.basket-section-count {
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    font-weight: 400;
}
.basket-stat-label {
    border-bottom: 1px dotted var(--color-text-light);
    cursor: help;
}
.basket-section-derived {
    margin-left: 6px;
    font-style: italic;
}
.basket-section-actions {
    display: flex;
    gap: var(--space-sm);
    flex-wrap: wrap;
}
.basket-section-empty {
    color: var(--color-text-muted);
    font-size: var(--text-sm);
    padding: var(--space-md);
    background: #fff;
    margin: 0;
}
.basket-section .basket-table {
    background: #fff;
    margin-bottom: 0;
    width: 100%;
}
.basket-section .basket-table thead th {
    background: var(--color-bg-warm);
    padding: var(--space-xs) var(--space-md);
}
.basket-section .basket-table tbody td {
    padding: var(--space-xs) var(--space-md);
}
/* Nicht sortierbare Header (Regest, aus Quelle, Aktionen) tragen keinen
   Pointer, damit nur die data-sort-Spalten als klickbar lesbar sind. */
.basket-table th:not([data-sort]) { cursor: default; }
.basket-section .basket-table tbody tr:hover td {
    background: var(--color-bg-warm);
}
.basket-section .basket-table th[data-hint],
.basket-section .basket-table .col-source a[data-hint] {
    cursor: help;
}

/* Derived rows: italic and dimmed; "aus Quelle" cell smaller and muted. */
.basket-row-derived {
    font-style: italic;
    color: var(--color-text-muted);
}
.basket-row-derived a {
    color: inherit;
}
.basket-table .col-source {
    font-size: var(--text-xs);
    color: var(--color-text-muted);
    max-width: 220px;
}

/* Derived-only basket button: abgeleitet aus einer gesammelten Quelle,
   nicht selbst gesammelt. Border bleibt durchgezogen, Glyphe ist ein
   gestricheltes Plus (siehe basket.js SVG_DASHED_PLUS). Akzentfarbe
   dezent, damit der State zwischen "absent" und "is-in" sitzt. */
.basket-btn.is-derived {
    border-color: var(--color-border-dark);
    color: var(--color-text-muted);
    background: transparent;
}
.basket-btn.is-derived:hover {
    border-color: var(--anno-place);
    color: var(--anno-place);
    background: color-mix(in srgb, var(--anno-place) 8%, transparent);
}

/* Sortier-Pfeile fuer alle .sortable-table-Tabellen projektweit. Die
   gruppen-aware Sortier-Logik lebt jeweils pro Page (profile.js,
   document.js, ...), die optische Anzeige der Sortierrichtung ist
   gemeinsam. Variante an org-Profilseiten zieht ueber spezifischere
   Selektoren ihre eigene Akzentfarbe. */
.sortable-table th[data-sort] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.sortable-table th[data-sort]::after {
    content: ' \2195';
    margin-left: 0.25em;
    opacity: 0.35;
    font-size: 0.85em;
    transition: opacity var(--transition-fast, 0.15s), color var(--transition-fast, 0.15s);
}
.sortable-table th[data-sort]:hover::after { opacity: 0.7; }
.sortable-table th.sorted-asc::after {
    content: ' \2191';
    opacity: 1;
    color: var(--anno-person);
}
.sortable-table th.sorted-desc::after {
    content: ' \2193';
    opacity: 1;
    color: var(--anno-person);
}
