.movements-flow { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 8px 16px 16px; } .movements-flow-caption { margin: 0 0 12px; text-align: center; font-family: 'Georgia', serif; font-size: 13px; font-style: italic; color: rgba(201, 169, 110, 0.65); } .movements-empty { flex: 1; display: flex; align-items: center; justify-content: center; padding: 48px; text-align: center; color: rgba(201, 169, 110, 0.6); font-family: 'Georgia', serif; } .movements-flow-canvas { --stream-stroke: 54px; --portrait-size: 26px; position: relative; flex: 1; min-height: 0; width: 100%; border-radius: 8px; background: radial-gradient(ellipse 80% 60% at 50% 100%, rgba(201, 169, 110, 0.07), transparent 70%), rgba(0, 0, 0, 0.25); border: 1px solid rgba(201, 169, 110, 0.12); overflow: hidden; cursor: grab; touch-action: none; } .movements-flow-canvas.movements-flow-panning { cursor: grabbing; } .movement-lifespan-overlays { position: absolute; inset: 0; z-index: 3; pointer-events: none; } .movement-lifespan-dim { position: absolute; top: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); } .movement-lifespan-highlight { position: absolute; top: 0; bottom: 0; background: linear-gradient( 180deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.16) 40%, rgba(255, 255, 255, 0.12) 100% ); box-shadow: inset 0 0 0 2px rgba(255, 230, 180, 0.45), inset 0 0 48px rgba(255, 255, 255, 0.08); border-left: 2px solid rgba(255, 220, 160, 0.65); border-right: 2px solid rgba(255, 220, 160, 0.65); } .movements-flow-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; } .movements-flow-canvas.movements-flow-interacting { cursor: grab; } .movements-flow-canvas.movements-flow-interacting.movements-flow-panning { cursor: grabbing; } .movement-branch-fast { stroke-opacity: 0.32; stroke-width: calc(var(--stream-stroke) * 0.45); } .movement-stream-fast { stroke-opacity: 0.42; stroke-width: var(--stream-stroke); stroke-linecap: round; vector-effect: non-scaling-stroke; } .movement-branch { stroke-width: var(--stream-stroke); stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; transition: filter 0.2s ease, opacity 0.2s ease; } .movement-stream-fill { stroke-width: var(--stream-stroke); stroke-linecap: round; vector-effect: non-scaling-stroke; transition: filter 0.2s ease, opacity 0.2s ease; } .movement-stream-core { stroke-width: 2px; stroke-linecap: round; opacity: 0.22; stroke-dasharray: 8 6; animation: stream-shimmer 16s linear infinite; vector-effect: non-scaling-stroke; transition: filter 0.2s ease, opacity 0.2s ease; } .movements-flow-canvas.movements-flow-movement-hover .movement-stream-fill:not(.movement-stream-highlighted) { opacity: 0.55; } .movements-flow-canvas.movements-flow-movement-hover .movement-stream-core:not(.movement-stream-highlighted) { opacity: 0.1; } .movements-flow-canvas.movements-flow-movement-hover .movement-branch:not(.movement-branch-highlighted) { opacity: 0.45; } .movement-stream-fill.movement-stream-highlighted { filter: brightness(1.65) saturate(1.3); } .movement-stream-core.movement-stream-highlighted { opacity: 0.72; filter: brightness(1.5); stroke-width: 2.5px; } .movement-branch.movement-branch-highlighted { filter: brightness(1.55) saturate(1.2); } @keyframes stream-shimmer { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -42; } } .movements-flow-labels, .movements-flow-artists { position: absolute; inset: 0; } .movements-flow-hits { position: absolute; inset: 0; z-index: 2; pointer-events: none; } .movement-stream-hit { position: absolute; height: var(--stream-stroke); transform: translateY(-50%); pointer-events: auto; } .movements-flow-artists { opacity: 0; pointer-events: none; transition: opacity 0.18s ease; z-index: 5; } .movements-flow-canvas.movements-flow-band-hover .movements-flow-artists { opacity: 1; pointer-events: auto; } .artist-on-band { pointer-events: none; } .artist-lifespan { position: absolute; height: 0; transform: translateY(-50%); pointer-events: none; z-index: 4; } .artist-lifespan-line { position: absolute; left: 0; right: 0; top: 0; height: 4px; background: linear-gradient( 90deg, rgba(255, 255, 255, 0) 0%, var(--lifespan-color, #e8d5b5) 15%, #fff 50%, var(--lifespan-color, #e8d5b5) 85%, rgba(255, 255, 255, 0) 100% ); box-shadow: 0 0 8px rgba(255, 255, 255, 0.55), 0 0 16px var(--lifespan-color, #e8d5b5); border-radius: 2px; pointer-events: none; } .artist-on-band .artist-portrait { position: absolute; transform: translate(-50%, -50%); pointer-events: auto; } .artist-on-band .artist-portrait:hover { transform: translate(-50%, -50%) scale(1.14); } .artist-on-band-active .artist-portrait { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.85), 0 4px 24px rgba(255, 220, 160, 0.65); } .movements-flow-labels { position: absolute; inset: 0; pointer-events: none; z-index: 6; } .movement-flow-label { position: absolute; max-width: 160px; padding: 2px 6px; pointer-events: none; z-index: 6; transform: translate(-50%, -50%); } .movement-flow-label-btn { pointer-events: auto; border: none; background: rgba(12, 10, 18, 0.72); border-radius: 4px; cursor: pointer; text-align: center; transition: background 0.2s, box-shadow 0.2s; } .movement-flow-label-btn:hover { background: rgba(24, 20, 32, 0.82); box-shadow: 0 0 0 1px rgba(255, 220, 160, 0.35); } .movement-flow-label-btn:focus-visible { outline: 2px solid rgba(255, 220, 160, 0.65); outline-offset: 2px; } .movement-name { display: block; font-family: 'Georgia', serif; font-size: 12px; font-weight: 600; color: rgba(232, 213, 181, 0.95); line-height: 1.25; text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9); } .movement-era { display: block; font-size: 9px; color: rgba(201, 169, 110, 0.6); margin-top: 1px; } .artist-portrait { background: none; border: 2px solid rgba(232, 213, 181, 0.75); border-radius: 50%; width: var(--portrait-size, 26px); height: var(--portrait-size, 26px); padding: 0; cursor: pointer; overflow: visible; transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s; z-index: 5; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.55); } .artist-portrait:hover { border-color: #fff; box-shadow: 0 4px 20px rgba(201, 169, 110, 0.5); z-index: 10; } .artist-portrait img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; } .artist-portrait .artist-name { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); white-space: nowrap; font-size: 10px; color: #e8d5b5; margin-top: 4px; opacity: 0; transition: opacity 0.2s; pointer-events: none; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9); } .artist-portrait:hover .artist-name { opacity: 1; } @media (max-width: 768px) { .movements-flow-canvas { --stream-stroke: 44px; --portrait-size: 22px; } .movements-flow-caption { font-size: 12px; } .artist-portrait { width: var(--portrait-size, 22px); height: var(--portrait-size, 22px); } .movement-flow-label { max-width: 110px; } .movement-name { font-size: 10px; } }