Analysepipeline: Snake-Layout (3x3) statt linearer Reihe
Pipeline laeuft jetzt zickzack: Reihe 1 von links nach rechts, U-Turn nach unten, Reihe 2 von rechts nach links, U-Turn nach unten, Reihe 3 wieder von links nach rechts. Karte waechst auf benoetigte Hoehe statt horizontalem Scrollen. - pipeline.js: Bloecke werden in Dreier-Gruppen aufgeteilt, Direction ltr/rtl wechselt pro Reihe. Zwischen Reihen rendert ein SVG-U-Turn-Pfeil (Bogen mit Pfeilkopf) die Verbindung. Daten-Fluss-Animation (is-flowing) funktioniert sowohl auf Inner-Pfeilen als auch auf U-Turns. - CSS: .pipeline-row mit flex-direction abhaengig von data-direction. rtl-Reihen kippen Pfeilkopf und Animation in entgegengesetzte Richtung. U-Turn-Pfad als SVG mit stroke-dasharray-Animation bei aktivem Fluss. - Mobile (<900px): Snake aufgeloest, alle Reihen werden vertikal gestapelt, U-Turns ausgeblendet — bestehende Vertikal-Stilistik bleibt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -5659,15 +5659,26 @@ body.tutorial-active .tutorial-cursor {
|
||||
}
|
||||
.pipeline-stage {
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
overflow: visible;
|
||||
}
|
||||
.pipeline-track {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
padding: var(--sp-md) 0;
|
||||
width: 100%;
|
||||
}
|
||||
.pipeline-row {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
gap: var(--sp-md);
|
||||
min-width: max-content;
|
||||
padding: var(--sp-md) 0;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.pipeline-row[data-direction="ltr"] { justify-content: flex-start; }
|
||||
.pipeline-row[data-direction="rtl"] {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.pipeline-empty {
|
||||
text-align: center;
|
||||
@@ -5797,6 +5808,61 @@ body.tutorial-active .tutorial-cursor {
|
||||
to { background-position: 12px 0; }
|
||||
}
|
||||
|
||||
/* Pfeil in rtl-Reihe: Pfeilkopf nach links, Animation rückwärts */
|
||||
.pipeline-row[data-direction="rtl"] .pipeline-arrow::after {
|
||||
border-left: none;
|
||||
border-right: 6px solid var(--border);
|
||||
right: auto;
|
||||
left: -4px;
|
||||
}
|
||||
.pipeline-row[data-direction="rtl"] .pipeline-arrow.is-flowing::after {
|
||||
border-right-color: var(--accent);
|
||||
border-left-color: transparent;
|
||||
}
|
||||
.pipeline-row[data-direction="rtl"] .pipeline-arrow.is-flowing {
|
||||
animation: pipelineFlowReverse 0.8s linear infinite;
|
||||
}
|
||||
@keyframes pipelineFlowReverse {
|
||||
from { background-position: 12px 0; }
|
||||
to { background-position: 0 0; }
|
||||
}
|
||||
|
||||
/* U-Turn-Pfeil zwischen Snake-Reihen */
|
||||
.pipeline-uturn {
|
||||
height: 36px;
|
||||
width: 100%;
|
||||
margin: var(--sp-xs) 0;
|
||||
pointer-events: none;
|
||||
overflow: visible;
|
||||
}
|
||||
.pipeline-uturn svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
.pipeline-uturn-path {
|
||||
fill: none;
|
||||
stroke: var(--border);
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
.pipeline-uturn-head {
|
||||
fill: none;
|
||||
stroke: var(--border);
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
.pipeline-uturn.is-flowing .pipeline-uturn-path {
|
||||
stroke: var(--accent);
|
||||
stroke-dasharray: 8 6;
|
||||
animation: pipelineUturnDash 0.9s linear infinite;
|
||||
}
|
||||
.pipeline-uturn.is-flowing .pipeline-uturn-head { stroke: var(--accent); }
|
||||
@keyframes pipelineUturnDash {
|
||||
to { stroke-dashoffset: -28; }
|
||||
}
|
||||
|
||||
.pipeline-loop {
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
@@ -5928,7 +5994,14 @@ body.tutorial-active .tutorial-cursor {
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.pipeline-track { flex-direction: column; min-width: auto; align-items: stretch; }
|
||||
/* Snake aufloesen — alle Reihen werden vertikal gestapelt */
|
||||
.pipeline-row,
|
||||
.pipeline-row[data-direction="rtl"] {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
.pipeline-uturn { display: none; }
|
||||
|
||||
.pipeline-block { flex: 0 0 auto; width: 100%; min-height: auto; flex-direction: row; padding: var(--sp-md); text-align: left; gap: var(--sp-md); }
|
||||
.pipeline-block-icon { width: 28px; height: 28px; margin-bottom: 0; flex-shrink: 0; }
|
||||
.pipeline-block-title { margin-bottom: 2px; }
|
||||
@@ -5941,8 +6014,10 @@ body.tutorial-active .tutorial-cursor {
|
||||
align-self: center;
|
||||
background: var(--border);
|
||||
}
|
||||
.pipeline-arrow::after {
|
||||
.pipeline-arrow::after,
|
||||
.pipeline-row[data-direction="rtl"] .pipeline-arrow::after {
|
||||
right: 50%;
|
||||
left: auto;
|
||||
top: auto;
|
||||
bottom: -4px;
|
||||
border-top: 6px solid var(--border);
|
||||
@@ -5951,12 +6026,18 @@ body.tutorial-active .tutorial-cursor {
|
||||
border-right: 4px solid transparent;
|
||||
transform: translateX(50%);
|
||||
}
|
||||
.pipeline-arrow.is-flowing {
|
||||
.pipeline-arrow.is-flowing,
|
||||
.pipeline-row[data-direction="rtl"] .pipeline-arrow.is-flowing {
|
||||
background: linear-gradient(180deg, var(--accent), var(--accent) 50%, transparent 50%, transparent);
|
||||
background-size: 100% 12px;
|
||||
animation: pipelineFlowVertical 0.8s linear infinite;
|
||||
}
|
||||
.pipeline-arrow.is-flowing::after { border-top-color: var(--accent); }
|
||||
.pipeline-arrow.is-flowing::after,
|
||||
.pipeline-row[data-direction="rtl"] .pipeline-arrow.is-flowing::after {
|
||||
border-top-color: var(--accent);
|
||||
border-right-color: transparent;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
@keyframes pipelineFlowVertical {
|
||||
from { background-position: 0 0; }
|
||||
to { background-position: 0 12px; }
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren