/* ═══════════════════════════════════════════════════════════════════
   DASHBOARD-WIDGETS — zentrale Styles für wiederverwendbare
   Dashboard-/Report-Bausteine.

   Hier leben die Styles aller Widgets, die über mehrere Seiten hinweg
   einheitlich aussehen sollen (Karten, Grid, Charts+Legende, Verteilungs-
   balken, Pills, Tabellen-Styling, Section-Divider, Empty-States, …).

   Global via templates/includes/base.html geladen, d. h. jede Seite kann
   die Widgets ohne zusätzliches <link> nutzen.

   Template-Includes dazu:
     includes/section_divider.html        →  .section-divider
     includes/card_open.html / _close.html →  .op-card + .op-card-header
     includes/empty_state.html             →  .trend-placeholder (in .op-card)
     includes/distribution_list.html       →  .dist-row + .dist-bar-*
     includes/chart_donut.html             →  .chart-wrap + .chart-legend

   Referenz-Optik: api_crawler/onpage-dashboard.html.
   ═════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════
   GRID SYSTEM  — .op-grid
   ═══════════════════════════════════════ */
.op-grid {
    display: grid;
    gap: 1rem;
    margin-bottom: 1rem;
}

.op-grid--4     { grid-template-columns: repeat(4, 1fr); }
.op-grid--3     { grid-template-columns: repeat(3, 1fr); }
.op-grid--2     { grid-template-columns: 1fr 1fr; }
.op-grid--1     { grid-template-columns: 1fr; }
.op-grid--score { grid-template-columns: 1fr 260px; }

@media (max-width: 1200px) {
    .op-grid--4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
    .op-grid--4,
    .op-grid--3,
    .op-grid--score { grid-template-columns: 1fr; }
    .op-grid--2     { grid-template-columns: 1fr; }
}


/* ═══════════════════════════════════════
   CARD  — .op-card / -header / -title / -body
   ═══════════════════════════════════════ */
.op-card {
    background: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius);
    overflow: hidden;
}

.op-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid hsl(var(--border) / 0.4);
}

.op-card-title {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: hsl(var(--foreground));
}

.op-card-title i {
    font-size: 0.75rem;
    color: hsl(var(--muted-foreground));
}

.op-card-body         { padding: 1rem; }
.op-card-body--flush  { padding: 0; }

.op-card-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}


/* ═══════════════════════════════════════
   SECTION DIVIDER  — .section-divider
   ═══════════════════════════════════════ */
.section-divider {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: hsl(var(--muted-foreground));
    margin: 1.5rem 0 1rem;
    user-select: none;
}

.section-divider i       { font-size: 0.625rem; }
.section-divider::after  { content: ''; flex: 1; height: 1px; background: hsl(var(--border)); }


/* ═══════════════════════════════════════
   HELP BUTTON (card-header, kleiner „?")  — .op-help-btn
   Für KPI-Karten gibt es zusätzlich .kpi-help in _kpi-cards.css.
   ═══════════════════════════════════════ */
.op-help-btn {
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 50%;
    border: 1px solid hsl(var(--border));
    background: transparent;
    color: hsl(var(--muted-foreground));
    font-size: 0.5625rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.15s;
    flex-shrink: 0;
}

.op-help-btn:hover {
    border-color: hsl(var(--primary));
    color: hsl(var(--primary));
}


/* ═══════════════════════════════════════
   CHART CONTAINERS  — .chart-wrap + .chart-canvas-*
   ═══════════════════════════════════════ */
.chart-wrap {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

.chart-canvas-sm {
    position: relative;
    width: 120px;
    height: 120px;
    flex-shrink: 0;
}
.chart-canvas-sm canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }

.chart-canvas-sm-h {
    position: relative;
    width: 100%;
    height: 100px;
}
.chart-canvas-sm-h canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }

.chart-canvas-lg {
    position: relative;
    width: 100%;
    height: 240px;
}
.chart-canvas-lg canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }


/* ═══════════════════════════════════════
   CHART LEGEND  — .chart-legend + -row / -dot / -label / -val
   ═══════════════════════════════════════ */
.chart-legend {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    flex: 1;
    min-width: 0;
}

.chart-legend-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8125rem;
}

.chart-legend-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.chart-legend-label {
    flex: 1;
    color: hsl(var(--foreground));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.chart-legend-val {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    min-width: 1.5rem;
    text-align: right;
    color: hsl(var(--foreground));
}

.chart-legend-val small {
    font-weight: 400;
    color: hsl(var(--muted-foreground));
    font-size: 0.6875rem;
    margin-left: 0.125rem;
}

.dot-label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}


/* ═══════════════════════════════════════
   TREND-LEGEND PILLS (unter Card-Headern)  — .trend-legend-pill / -line
   ═══════════════════════════════════════ */
.trend-legend-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.6875rem;
    font-weight: 500;
    padding: 0.1875rem 0.5rem 0.1875rem 0.375rem;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--pill-color, hsl(var(--border))) 30%, transparent);
    background: color-mix(in srgb, var(--pill-color, hsl(var(--border))) 10%, transparent);
    color: var(--pill-color, hsl(var(--muted-foreground)));
    white-space: nowrap;
}

.trend-legend-line {
    display: inline-block;
    width: 14px;
    height: 2px;
    border-radius: 999px;
    flex-shrink: 0;
}


/* ═══════════════════════════════════════
   OP-TABLE (kompakte statische Tabellen)  — .op-table / .op-table--compact
   Hinweis: Für interaktive Tabellen IMMER InventoryTable verwenden.
   .op-table ist nur für kurze Top-N-/Static-Listen innerhalb von Cards.
   ═══════════════════════════════════════ */
.op-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8125rem;
}

.op-table th {
    padding: 0.5rem 0.75rem;
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: hsl(var(--muted-foreground));
    border-bottom: 1px solid hsl(var(--border));
    background: hsl(var(--muted) / 0.3);
    white-space: nowrap;
    user-select: none;
    text-align: left;
}

.op-table td {
    padding: 0.375rem 0.75rem;
    border-bottom: 1px solid hsl(var(--border) / 0.25);
    vertical-align: middle;
}

.op-table tbody tr:last-child td { border-bottom: none; }
.op-table tbody tr:hover          { background: hsl(var(--muted) / 0.2); }

.op-table--compact th { padding: 0.375rem 0.625rem; }
.op-table--compact td { padding: 0.3125rem 0.625rem; font-size: 0.75rem; }

.op-table a         { color: hsl(var(--foreground)); text-decoration: none; }
.op-table a:hover   { color: hsl(var(--primary)); text-decoration: underline; }

.trunc {
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* ═══════════════════════════════════════
   PILLS / BADGES  — .pill / .pill--*
   ═══════════════════════════════════════ */
.pill {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.5rem;
    border-radius: 9999px;
    font-size: 0.6875rem;
    font-weight: 500;
}

.pill--green   { background: hsl(142 71% 45% / 0.12); color: hsl(142 71% 45%); }
.pill--orange  { background: hsl(38 92% 50% / 0.12);  color: hsl(38 92% 50%); }
.pill--red     { background: hsl(0 84% 60% / 0.12);   color: hsl(0 84% 60%); }
.pill--blue    { background: hsl(217 91% 60% / 0.12); color: hsl(217 91% 60%); }
.pill--gray    { background: hsl(var(--muted));       color: hsl(var(--muted-foreground)); }
.pill--purple  { background: hsl(280 60% 55% / 0.12); color: hsl(280 60% 55%); }


/* ═══════════════════════════════════════
   DISTRIBUTION BARS  — .dist-row / .dist-bar-* / .fill-*
   ═══════════════════════════════════════ */
.dist-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0;
    font-size: 0.75rem;
}

.dist-label {
    min-width: 85px;
    color: hsl(var(--muted-foreground));
}

.dist-bar-track {
    flex: 1;
    height: 5px;
    border-radius: 3px;
    background: hsl(var(--border));
    overflow: hidden;
}

.dist-bar-fill        { height: 100%; border-radius: 3px; }
.fill-success         { background: hsl(142 71% 45%); }
.fill-warning         { background: hsl(38 92% 50%); }
.fill-destructive     { background: hsl(0 84% 60%); }
.fill-info            { background: hsl(217 91% 60%); }
.fill-muted           { background: hsl(215 20% 55%); }

.dist-count {
    min-width: 32px;
    text-align: right;
    font-weight: 600;
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
}


/* ═══════════════════════════════════════
   MINI-KPI (kleiner zentrierter Wert in Karten)
   — .mini-kpi-value / .mini-kpi-label
   ═══════════════════════════════════════ */
.mini-kpi-value {
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.mini-kpi-label {
    font-size: 0.625rem;
    color: hsl(var(--muted-foreground));
    text-transform: uppercase;
    letter-spacing: 0.04em;
}


/* ═══════════════════════════════════════
   EMPTY-STATE / PLACEHOLDER  — .trend-placeholder / -icon / -title / -sub
   Wird in allen Dashboard-Karten als „Noch keine Daten"-Slot genutzt.
   ═══════════════════════════════════════ */
.trend-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 2.25rem 1.5rem;
    text-align: center;
    min-height: 180px;
}

.trend-placeholder-icon {
    font-size: 1.5rem;
    color: hsl(var(--muted-foreground) / 0.35);
    margin-bottom: 0.25rem;
}

.trend-placeholder-title {
    font-size: 0.875rem;
    font-weight: 600;
    color: hsl(var(--foreground));
    margin: 0;
}

.trend-placeholder-sub {
    font-size: 0.75rem;
    color: hsl(var(--muted-foreground));
    margin: 0;
    max-width: 320px;
}


/* ═══════════════════════════════════════
   TREND-DIRECTION UTILITIES (optional inline in Charts/Trend-Anzeige)
   ═══════════════════════════════════════ */
.trend-up      { color: hsl(142 71% 45%); }
.trend-down    { color: hsl(0 84% 60%); }
.trend-neutral { color: hsl(var(--muted-foreground)); }


/* ═══════════════════════════════════════
   FEED-ITEMS  — .op-feed-item / -icon / -main / -line1 / -line2 / -time

   Kompakte Feed-Zeile für News-/Alert-/Activity-Cards (body_flush=True).
   Struktur:
       <div class='op-feed-item'>
           <div class='op-feed-icon op-feed-icon--danger'><i class='fa-solid …'></i></div>
           <div class='op-feed-main'>
               <div class='op-feed-line1'>…title / link / chip…</div>
               <div class='op-feed-line2'>…meta / project / status…</div>
           </div>
           <span class='op-feed-time'>{{ obj.created_at|timesince }}</span>
       </div>
   ═══════════════════════════════════════ */
.op-feed-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    border-bottom: 1px solid hsl(var(--border) / 0.6);
    transition: background 120ms;
}
.op-feed-item:last-child { border-bottom: none; }
.op-feed-item:hover      { background: hsl(var(--muted) / 0.2); }

.op-feed-icon {
    width: 2rem;
    height: 2rem;
    border-radius: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8125rem;
    flex-shrink: 0;
}
.op-feed-icon--primary { background: hsl(var(--primary) / 0.1);   color: hsl(var(--primary)); }
.op-feed-icon--success { background: hsl(142 71% 45% / 0.12);     color: hsl(142 71% 45%); }
.op-feed-icon--info    { background: hsl(217 91% 60% / 0.12);     color: hsl(217 91% 60%); }
.op-feed-icon--warning { background: hsl(38 92% 50% / 0.12);      color: hsl(38 92% 50%); }
.op-feed-icon--danger  { background: hsl(0 84% 60% / 0.12);       color: hsl(0 84% 60%); }
.op-feed-icon--muted   { background: hsl(var(--muted) / 0.4);     color: hsl(var(--muted-foreground)); }

.op-feed-main  { flex: 1; min-width: 0; }
.op-feed-line1 {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: hsl(var(--foreground));
    min-width: 0;
}
.op-feed-line1 a {
    color: hsl(var(--foreground));
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.op-feed-line1 a:hover { color: hsl(var(--primary)); }
.op-feed-line2 {
    font-size: 0.6875rem;
    color: hsl(var(--muted-foreground));
    margin-top: 0.125rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.op-feed-time {
    font-size: 0.6875rem;
    color: hsl(var(--muted-foreground));
    white-space: nowrap;
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}


/* ═══════════════════════════════════════
   BUDGET-/PROGRESS-TABELLE  — .op-budget-table

   Für Monats-/Projekt-Übersichten in Cards (body_flush=True). Linke Spalte
   zeigt Projekt+Client mit .op-status-dot, rechte Spalten zeigen Kennzahlen
   als .op-bubble. Mit .op-sep-left lassen sich Gruppen trennen.
   ═══════════════════════════════════════ */
.op-budget-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8125rem;
}
.op-budget-table thead th {
    text-align: right;
    font-weight: 600;
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: hsl(var(--muted-foreground));
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid hsl(var(--border));
}
.op-budget-table thead th:first-child   { text-align: left; }
.op-budget-table thead th.op-sep-left   { border-left: 1px solid hsl(var(--border) / 0.6); }
.op-budget-table tbody td {
    padding: 0.75rem;
    border-bottom: 1px solid hsl(var(--border) / 0.6);
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: hsl(var(--foreground));
    vertical-align: middle;
}
.op-budget-table tbody td:first-child   { text-align: left; }
.op-budget-table tbody td.op-sep-left   { border-left: 1px solid hsl(var(--border) / 0.6); }
.op-budget-table tbody tr               { transition: background 120ms; }
.op-budget-table tbody tr:hover         { background: hsl(var(--muted) / 0.2); }
.op-budget-table tbody tr:last-child td { border-bottom: none; }

.op-budget-project-cell { display: flex; align-items: center; gap: 0.75rem; }
.op-budget-project      { font-weight: 600; line-height: 1.2; }
.op-budget-project-sub  { font-size: 0.6875rem; color: hsl(var(--muted-foreground)); margin-top: 0.125rem; }


/* ═══════════════════════════════════════
   STATUS-DOT  — .op-status-dot

   Kleiner Runder Status-Indikator vor einem Projekt-/Zeilen-Label.
   ═══════════════════════════════════════ */
.op-status-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    flex-shrink: 0;
    background: hsl(var(--muted-foreground) / 0.5);
}
.op-status-dot--good    { background: hsl(142 71% 45%); box-shadow: 0 0 0 3px hsl(142 71% 45% / 0.15); }
.op-status-dot--bad     { background: hsl(0 84% 60%);   box-shadow: 0 0 0 3px hsl(0 84% 60% / 0.15); }
.op-status-dot--warn    { background: hsl(38 92% 50%);  box-shadow: 0 0 0 3px hsl(38 92% 50% / 0.15); }
.op-status-dot--neutral { background: hsl(var(--muted-foreground) / 0.5); }


/* ═══════════════════════════════════════
   BUBBLE-PILL  — .op-bubble

   Runde, tabular-nums-zentrierte Pille für Zahlen-/Status-Werte in
   .op-budget-table-Zellen. Farb-Varianten: neutral (default), muted, good,
   warn, bad.
   ═══════════════════════════════════════ */
.op-bubble {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.3125rem 0.625rem;
    border-radius: 9999px;
    font-weight: 600;
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    border: 1px solid hsl(var(--border));
    background: hsl(var(--card));
    color: hsl(var(--foreground));
    min-width: 2.5rem;
    justify-content: center;
}
.op-bubble--neutral { border-color: hsl(var(--border));            background: hsl(var(--muted) / 0.25);  color: hsl(var(--foreground)); }
.op-bubble--muted   { border-color: hsl(var(--border) / 0.6);      background: transparent;               color: hsl(var(--muted-foreground)); }
.op-bubble--good    { border-color: hsl(142 71% 45% / 0.4);        background: hsl(142 71% 45% / 0.1);    color: hsl(142 71% 45%); }
.op-bubble--warn    { border-color: hsl(38 92% 50% / 0.4);         background: hsl(38 92% 50% / 0.1);     color: hsl(38 92% 50%); }
.op-bubble--bad     { border-color: hsl(0 84% 60% / 0.4);          background: hsl(0 84% 60% / 0.1);      color: hsl(0 84% 60%); }
