/* Agent-Trace: der Lauf eines Generators auf einer Zeitachse.
 *
 * Ersetzt die vier abgehakten Punkte, die LV, LB und der Chat bisher zeigten. Vorlage ist
 * das Muster "Agent Trace" von 21st.dev, nachgebaut in reinem CSS. Uebernommen sind die
 * Optik und das Verhalten, nicht der Code: Das Vergabe-Archiv hat kein React, kein Tailwind
 * und kein npm, und dafuer eine Werkzeugkette einzufuehren waere fuer eine Fortschritts-
 * anzeige nicht zu rechtfertigen.
 *
 * Bewusst abgewichen: Die Vorlage beschriftet die Zeilen wie Funktionsaufrufe
 * (model.plan, search_docs) in Schreibmaschinenschrift. Unsere Leser sind Vergabestellen,
 * keine Entwickler. Die Beschriftung bleibt deshalb deutsch und in der Grundschrift,
 * Schreibmaschinenschrift nur dort, wo sie etwas bringt: bei Zahlen und Zeiten.
 *
 * Es gibt auf der Seite keinen dunklen Modus (archiv.html ueberschreibt :root hell, die
 * Produktseiten sind hell), deshalb ein Farbsatz statt zwei.
 */

.at {
  --at-card: #ffffff;
  --at-line: #e4eaf3;
  --at-rail: #7d8aa3;
  --at-text: #1b2742;
  --at-sub: #6a7790;
  --at-run: #2b75ff;
  --at-done: #22c55e;
  --at-fail: #e8334a;
  --at-warte: #f59e0b;
  --at-ghost: rgba(27, 39, 66, .10);

  --at-row: 46px;
  --at-pad: 12px;
  --at-gutter: 244px;
  --at-meta: 116px;

  position: relative;
  background: var(--at-card);
  border: 1px solid var(--at-line);
  border-radius: 12px;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}

/* Die Spaltenbreiten richten sich nach der Breite der KARTE, nicht nach der des Fensters.
   Dasselbe Bauteil steht mal in einer breiten Produktseite und mal in einer schmalen
   Sprechblase im Chat. */
.at[data-size="sm"] { --at-gutter: 132px; --at-meta: 58px; --at-row: 38px; }
.at[data-size="md"] { --at-gutter: 186px; --at-meta: 86px; --at-row: 42px; }
/* Ab rund 900 Pixel ist Platz fuer die volle Unterzeile. Bei 244 Pixel Spaltenbreite
   endete "Web-Suche: Profil, Aufgaben und Adresse" als "... und Adr...". */
.at[data-size="xl"] { --at-gutter: 316px; --at-meta: 132px; }
.at[data-size="sm"] .at-sub,
.at[data-size="sm"] .at-ruler,
.at[data-size="sm"] .at-grid,
.at[data-size="sm"] .at-detail { display: none; }
.at[data-size="md"] .at-sub { display: none; }

/* ---------------------------------------------------------------- Kopfzeile */
.at-head {
  display: flex; align-items: center; gap: 9px;
  padding: 9px var(--at-pad);
  border-bottom: 1px solid var(--at-line);
}
.at-dot {
  flex: none; width: 6px; height: 6px; border-radius: 50%;
  background: var(--at-sub); transition: background .3s;
}
.at[data-run="running"] .at-dot { background: var(--at-run); animation: at-pulse 1.6s ease-in-out infinite; }
.at[data-run="done"]    .at-dot { background: var(--at-done); }
/* Wartet auf einen freien Platz: orange statt blau, damit auf einen Blick klar ist,
   dass noch nichts laeuft. Der Ladekreis bleibt, es tut sich ja etwas, nur nicht hier. */
.at[data-run="queued"]  .at-dot { background: var(--at-warte); animation: at-pulse 1.6s ease-in-out infinite; }
.at[data-run="queued"]  .at-chip { color: #a45a06; border-color: rgba(245, 158, 11, .45); }
.at[data-run="queued"]  .at-spin { border-color: rgba(245, 158, 11, .22); border-top-color: var(--at-warte); }
.at[data-run="error"]   .at-dot { background: var(--at-fail); }
@keyframes at-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

.at-id { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
         font-size: 12.5px; font-weight: 600; color: var(--at-text); line-height: 1; }
.at-meta-h { font-size: 12px; color: var(--at-sub); line-height: 1;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.at[data-size="sm"] .at-meta-h { display: none; }
.at-chip {
  margin-left: auto; flex: none;
  border: 1px solid var(--at-line); border-radius: 999px;
  padding: 3px 9px; font-size: 11px; line-height: 1.3; color: var(--at-sub);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.at[data-run="done"]  .at-chip { color: var(--at-done); border-color: rgba(34,197,94,.35); }
.at[data-run="error"] .at-chip { color: var(--at-fail); border-color: rgba(232,51,74,.35); }

/* ---------------------------------------------------------- Zeitachse und Raster */
/* Lineal, Gitter, Zeitmarke und Balken teilen sich dieselbe Box, sonst stehen die
   Beschriftungen nicht ueber den Balken, zu denen sie gehoeren. */
.at-track { position: absolute; left: calc(var(--at-gutter) + var(--at-pad));
            right: calc(var(--at-meta) + var(--at-pad)); }

.at-ruler { position: relative; height: 24px; border-bottom: 1px solid var(--at-line); }
.at-ruler .at-track { top: 0; bottom: 0; }
.at-tick { position: absolute; top: 7px; transform: translateX(-50%);
           font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
           font-size: 10px; line-height: 1; color: var(--at-sub); }

.at-body { position: relative; padding: 4px 0; }
.at-grid { position: absolute; top: 0; bottom: 0; pointer-events: none; }
.at-gridline { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--at-line); opacity: .7; }

/* ------------------------------------------------------------------- Zeilen */
.at-row {
  position: relative; display: flex; align-items: center;
  height: var(--at-row); padding: 0 var(--at-pad);
  transition: background .15s;
}
.at-row[data-state="run"] { background: rgba(43,117,255,.045); }

.at-label { display: flex; align-items: center; gap: 9px;
            width: var(--at-gutter); flex: none; min-width: 0; padding-right: 10px; }
.at-ico { flex: none; width: 15px; height: 15px; color: var(--at-sub); transition: color .2s; }
.at-row[data-state="run"]   .at-ico { color: var(--at-run); }
.at-row[data-state="done"]  .at-ico { color: var(--at-done); }
.at-row[data-state="error"] .at-ico { color: var(--at-fail); }
.at-txt { min-width: 0; }
.at-t { font-size: 12.5px; font-weight: 600; color: var(--at-text); line-height: 1.25;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color .2s; }
.at-row[data-state="wait"] .at-t { color: var(--at-sub); font-weight: 500; }
.at-sub { font-size: 11px; color: var(--at-sub); line-height: 1.3; margin-top: 1px;
          white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Balkenspalte. Die Breite steht in --w, die Position in --x, beides setzt das Skript. */
.at-bars { position: relative; flex: 1; height: 100%; min-width: 0; }
.at-bar {
  position: absolute; top: 50%; height: 8px; min-width: 3px;
  transform: translateY(-50%);
  left: calc(var(--x, 0) * 100%); width: calc(var(--w, 0) * 100%);
  border-radius: 999px; overflow: hidden;
  background: var(--at-ghost);
  opacity: 0; transition: opacity .2s;
}
.at-row[data-state="run"] .at-bar,
.at-row[data-state="done"] .at-bar,
.at-row[data-state="error"] .at-bar { opacity: 1; }
.at-fill { position: absolute; inset: 0; background: var(--at-run); border-radius: inherit; }
.at-row[data-state="done"]  .at-fill { background: var(--at-done); }
.at-row[data-state="error"] .at-fill { background: var(--at-fail); }
/* Der laufende Balken bekommt einen wandernden Schimmer. Er sagt nichts ueber den
   Fortschritt aus, sondern nur, dass gearbeitet wird, und genau so ist er gemeint. */
.at-row[data-state="run"] .at-fill::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: at-shimmer 1.5s linear infinite;
}
@keyframes at-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

.at-res { display: flex; align-items: center; justify-content: flex-end; gap: 7px;
          width: var(--at-meta); flex: none; padding-left: 10px;
          opacity: 0; transition: opacity .2s; }
.at-row:not([data-state="wait"]) .at-res { opacity: 1; }
.at-detail { font-size: 11px; color: var(--at-sub);
             font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.at-dur { flex: none; font-size: 11px; color: var(--at-text); opacity: .75;
          font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.at-row[data-state="error"] .at-dur { color: var(--at-fail); opacity: 1; }

/* -------------------------------------------------------------- Zeitmarke */
.at-head-line { position: absolute; top: 0; bottom: 0; width: 1px;
                background: var(--at-run); opacity: .55; }
.at-head-tip { position: absolute; top: 0; width: 6px; height: 6px;
               margin-left: -2.5px; background: var(--at-run); transform: rotate(45deg); }
.at-play { position: absolute; top: 0; bottom: 0; pointer-events: none; }
.at-play > div { position: relative; height: 100%; width: 100%;
                 transform: translateX(calc(var(--t, 0) * 100%)); }
.at[data-run="done"] .at-play, .at[data-run="error"] .at-play { opacity: 0; transition: opacity .4s; }

/* ------------------------------------------------------------- Fusszeile */
.at-foot { display: flex; align-items: flex-start; gap: 8px;
           border-top: 1px solid var(--at-line); padding: 7px var(--at-pad);
           font-size: 11px; color: var(--at-sub); }
/* Ladekreis vor dem Hinweis. Der Punkt in der Kopfzeile pulst zwar, steht aber weit
   weg vom Text. Hier unten, direkt vor "Die KI arbeitet", sieht man es sofort. */
.at-spin { flex: none; width: 12px; height: 12px; border-radius: 50%; margin-top: 2px;
           border: 2px solid rgba(43, 117, 255, .22); border-top-color: var(--at-run);
           animation: at-rot .7s linear infinite; }
@keyframes at-rot { to { transform: rotate(360deg); } }
.at[data-run="done"] .at-spin, .at[data-run="error"] .at-spin { display: none; }
.at-clock { margin-left: auto; flex: none;
            font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
/* Der Hinweis darf umbrechen. Mit nowrap verschwand der zweite Satz (der ueber den
   Mailversand, also der beruhigende) hinter drei Punkten. */
.at-note { min-width: 0; }

/* Wer Bewegung abbestellt hat, bekommt die Anzeige ohne Puls und ohne Schimmer.
   Die Balken und die Zeiten stehen weiter da, die Information geht also nicht verloren. */
@media (prefers-reduced-motion: reduce) {
  .at-dot, .at-row[data-state="run"] .at-fill::after { animation: none; }
  /* Der Ladekreis dreht weiter, nur langsam. Ein stehender Ladekreis sagt nichts aus,
     und genau seine Aussage ist hier gebraucht. */
  .at-spin { animation-duration: 2.4s; }
}

/* Der Wirt im Chat ist eine Sprechblase: eigene Karte, eigener Rand, max-width 80%.
   Um unsere Karte gehoert beides nicht herum, und 80 Prozent sind fuer eine Zeitachse
   zu schmal. Das Skript setzt .at-host auf den Wirt, sobald es dort einzieht. */
.at-host {
  /* Die Sprechblase ist ein Flex-Element und schrumpfte auf Inhaltsbreite: 378 statt
     1072 Pixel, weil die Karte selbst keine Breite einfordert. */
  max-width: 100% !important;
  width: 100%;
  flex: 1 1 auto;
}
/* Mit !important, weil die Seiten die Sprechblase als '.cl-row.bot .cl-bubble'
   ansprechen und damit spezifischer sind als '.cl-bubble.at-host'. Ohne das blieben
   Rand und Schatten der Blase als zweiter Rahmen um unsere Karte stehen. */
.cl-bubble.at-host {
  padding: 0 !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
.at { width: 100%; }
.at-id:empty { display: none; }
