// ============================================================================= // Team Wheel Component (SCSS) // ============================================================================= // Круговой прокручиваемый виджет сотрудников // ============================================================================= // ПЕРЕМЕННЫЕ // ============================================================================= $wheel-size: 200px; $ava-size: 52px; $arc-width: 4px; // ============================================================================= // CSS ПЕРЕМЕННЫЕ // ============================================================================= :root { --wheel-size: #{$wheel-size}; --ava-size: #{$ava-size}; --ring-bg: radial-gradient( ellipse at center, var(--bs-body-bg), color-mix(in srgb, var(--bs-body-bg) 85%, var(--bs-secondary-bg, #f7f7f9) 15%) ); --ring-border: var(--bs-border-color, rgba(0, 0, 0, 0.125)); --shadow-inset: 0 8px 24px rgba(0, 0, 0, 0.06) inset; --shadow-out: 0 4px 12px rgba(0, 0, 0, 0.05); --arc-width: #{$arc-width}; --arc-track: color-mix(in srgb, var(--bs-secondary-color) 30%, transparent); --arc-prog: var(--bs-primary); } // ============================================================================= // TEAM WRAP & WHEEL // ============================================================================= .team-wrap { width: var(--wheel-size); display: flex; flex-direction: column; align-items: center; margin-inline: auto; } .team-wheel { position: relative; width: var(--wheel-size); height: var(--wheel-size); border-radius: 50%; overflow: hidden; background: var(--ring-bg); border: 1px solid var(--ring-border); box-shadow: var(--shadow-inset); user-select: none; touch-action: none; display: flex; align-items: center; justify-content: center; } // ============================================================================= // WHEEL LAYOUT // ============================================================================= .wheel-plane { position: absolute; inset: 0; } .wheel-columns { position: absolute; inset: 10px var(--space-1); display: flex; gap: var(--space-1); justify-content: space-between; align-items: flex-start; will-change: transform; } .wheel-col { width: calc(25% - 6px); display: flex; flex-direction: column; gap: var(--space-1); align-items: center; &.col-2 { margin-top: calc(var(--ava-size) * 0.5); } &.col-3 { margin-top: calc(var(--ava-size) * 1); } &.col-4 { margin-top: calc(var(--ava-size) * 1.5); } } // ============================================================================= // WHEEL ITEMS // ============================================================================= .wheel-item { background: transparent; border: 0; padding: 0; width: var(--ava-size); height: var(--ava-size); border-radius: 50%; cursor: pointer; box-shadow: var(--shadow-out); .ava { width: 100%; height: 100%; border-radius: 50%; overflow: hidden; display: grid; place-items: center; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); img { width: 100%; height: 100%; object-fit: cover; } .bi { font-size: 1.2rem; opacity: 0.5; } } &:active { transform: scale(0.96); } } // ============================================================================= // WHEEL FOCUS (ЦЕНТРАЛЬНЫЙ ЭЛЕМЕНТ) // ============================================================================= .wheel-focus { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: var(--bs-body-bg); .focus-inner { width: 100%; height: 100%; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--bs-body-bg) 85%, #e9ecef 15%); } img { width: 100%; height: 100%; object-fit: cover; display: none; } [data-focus-fallback] { display: none; font-size: calc(var(--wheel-size) * 0.35); color: var(--bs-secondary-color); } } // ============================================================================= // SCROLL ARC (ПРОГРЕСС-ИНДИКАТОР) // ============================================================================= .scroll-arc { position: absolute; inset: 0; pointer-events: none; } .arc-track { fill: none; stroke: var(--arc-track); stroke-width: var(--arc-width); stroke-linecap: round; } .arc-prog { fill: none; stroke: var(--arc-prog); stroke-width: var(--arc-width); stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 0.12s linear; } // ============================================================================= // PROGRESS RING // ============================================================================= .progress-ring { position: absolute; inset: -1px; transform: rotate(-90deg); pointer-events: none; } .progress-ring__circle { stroke: var(--arc-track); fill: none; stroke-width: var(--arc-width); stroke-linecap: round; } .progress-ring__prog { stroke: var(--arc-prog); fill: none; stroke-width: var(--arc-width); stroke-linecap: round; transition: stroke-dashoffset 0.35s; } // ============================================================================= // CONTROLS // ============================================================================= .team-controls { margin-top: var(--space-2); display: flex; gap: var(--space-1); align-items: center; } .team-nav { padding: var(--space-1); border: 1px solid var(--bs-border-color); background: var(--bs-body-bg); border-radius: 8px; &:active:not(:disabled) { transform: scale(0.96); } &:disabled { opacity: 0.4; cursor: not-allowed; } } .team-dots { display: flex; gap: 6px; align-items: center; } .team-dot { width: 6px; height: 6px; border-radius: 50%; background: color-mix(in srgb, var(--bs-secondary-color), transparent 70%); &.active { background: var(--bs-primary); } }