/* 공통 프로그레스 서클 — 뷰포트 위에 얹는 원형 진행 표시. 테두리 두께·색은 공통 로딩 스피너(.ui-spinner)와 같게 맞추고, 가운데에 진행률만 더한다. */ .ui-progress-circle { --ui-progress-size: 72px; display: flex; flex-direction: column; align-items: center; gap: var(--spacing-8); pointer-events: none; user-select: none; } /* 컨테이너 정중앙 오버레이 — 3D 뷰포트·지도·그래프 어디에나 같은 방식으로 얹는다. 컨테이너에 position: relative 가 있어야 한다. */ .ui-progress-circle--overlay { position: absolute; z-index: 1; inset: 0; justify-content: center; } .ui-progress-circle__dial { position: relative; width: var(--ui-progress-size); height: var(--ui-progress-size); } /* 회전 껍데기 — 진행률을 알든 모르든 **항상** 돈다(2026-09-04 사용자 지시). 무거운 단계에서 호가 안 늘어도 도넛이 멈춰 보이지 않는다. 안쪽 svg는 12시 고정이라 호·숫자는 제자리에서 갱신된다. */ .ui-progress-circle__spin { width: 100%; height: 100%; animation: ui-progress-spin 1s linear infinite; } .ui-progress-circle__svg { width: 100%; height: 100%; /* 12시 방향에서 시계 방향으로 채운다. */ transform: rotate(-90deg); } .ui-progress-circle__track { fill: none; stroke: var(--color-mist-violet); stroke-width: 8; } .ui-progress-circle__bar { fill: none; stroke: var(--color-royal-amethyst); stroke-width: 8; stroke-linecap: round; transition: stroke-dashoffset var(--transition-base); } @keyframes ui-progress-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .ui-progress-circle__percent { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--color-text-body); font-family: var(--font-body); font-size: var(--text-body-sm); font-weight: var(--font-weight-semibold); } .ui-progress-circle__label { max-width: 22ch; padding: var(--spacing-4) var(--spacing-8); border-radius: var(--radius-inputs); background: color-mix(in srgb, var(--color-surface-raised) 82%, transparent); color: var(--color-text-secondary); font-size: var(--text-caption); text-align: center; word-break: keep-all; } .ui-progress-circle__label:empty { display: none; }