/* UB Deck — 슬라이드 애니메이션 (오브젝트 · 차트 · 페이지 전환)
 * 정본은 ui/anim.css, build.sh 가 web/ 로 복사.
 *
 * 적용 방식: 슬라이드 루트에 .ub-a-<모드> 를 붙이면 그 안의 오브젝트가 순차 등장한다.
 *   모드: none | fade | rise(기본) | pop | wipe
 * 전환: 무대/발표 컨테이너에 .ub-t-<모드> 를 붙인다.
 *   모드: none | fade | slide(기본) | zoom | flip
 * 지속시간은 --a-dur, 간격은 --a-gap 으로 조절(설정에서 주입).
 * ------------------------------------------------------------------ */

:root{
  --a-dur: 520ms;    /* 오브젝트 등장 시간 */
  --a-gap: 70ms;     /* 오브젝트 간 간격 */
  --t-dur: 420ms;    /* 페이지 전환 시간 */
  --a-ease: cubic-bezier(.22,.68,.28,1);
}

/* 모션 최소화면 전부 끈다 */
@media (prefers-reduced-motion: reduce){
  .ub-a-fade > *, .ub-a-rise .ub-o, .ub-a-pop .ub-o, .ub-a-wipe .ub-o{
    animation:none !important; opacity:1 !important; transform:none !important; clip-path:none !important;
  }
  .ub-t-fade,.ub-t-slide,.ub-t-zoom,.ub-t-flip{ animation:none !important }
  .ub-a .track > span, .ub-a svg rect.ub-bar, .ub-a svg text.ub-barval,
  .ub-a svg.ub-donut-svg, .ub-a svg polyline.ub-line, .ub-a svg circle.ub-dot, .ub-a .t-kpi{
    animation:none !important; opacity:1 !important; transform:none !important; stroke-dashoffset:0 !important;
  }
}

/* ── 오브젝트 등장 ─────────────────────────────────────────── */
/* .ub-o = 애니메이션 대상(카드·불릿·KPI·행·칩 등). anim.js 가 붙이고 --i 로 순서를 준다. */
.ub-a-rise .ub-o{
  animation: ub-o-rise var(--a-dur) var(--a-ease) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap));
}
@keyframes ub-o-rise{ from{ opacity:0; transform:translateY(18px) } }

.ub-a-fade .ub-o{
  animation: ub-o-fade var(--a-dur) var(--a-ease) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap));
}
@keyframes ub-o-fade{ from{ opacity:0 } }

.ub-a-pop .ub-o{
  animation: ub-o-pop var(--a-dur) cubic-bezier(.34,1.5,.5,1) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap));
}
@keyframes ub-o-pop{ from{ opacity:0; transform:scale(.86) } }

.ub-a-wipe .ub-o{
  animation: ub-o-wipe var(--a-dur) var(--a-ease) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap));
}
@keyframes ub-o-wipe{ from{ opacity:0; clip-path:inset(0 100% 0 0) } to{ clip-path:inset(0 0 0 0) } }

/* ── 차트 애니메이션 ───────────────────────────────────────── */
/* 원칙: '나타나는' 연출만 쓴다. 사라지는 연출은 금지 —
   확인해야 할 데이터가 안 보이면 자료로서 쓸모가 없다.
   그래서 모두 animation-fill-mode:backwards (시작 전에만 감춤, 끝나면 원래 상태). */

/* 가로 막대: 왼쪽에서 자란다 */
.ub-a .track > span{
  transform-origin:left center;
  animation: ub-bar-x calc(var(--a-dur) * 1.3) var(--a-ease) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap) + 120ms);
}
@keyframes ub-bar-x{ from{ transform:scaleX(0) } }

/* 세로 막대: 바닥에서 위로 자란다 */
.ub-a svg rect.ub-bar{
  transform-box: fill-box; transform-origin: bottom;
  animation: ub-bar-y var(--a-dur) var(--a-ease) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap) + 120ms);
}
@keyframes ub-bar-y{ from{ transform:scaleY(0) } }

/* 막대 위 값 라벨: 그 막대가 다 자란 '뒤'에 나타난다 */
.ub-a svg text.ub-barval{
  animation: ub-fade-up calc(var(--a-dur) * .6) var(--a-ease) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap) + 120ms + var(--a-dur));
}
@keyframes ub-fade-up{ from{ opacity:0 } }
/* 축 카테고리 라벨은 처음부터 보인다(기준선 역할) */

/* 도넛: svg 자체를 부드럽게 키운다.
   안쪽 <g> 는 rotate(-90 21 21) 이 걸려 있어 CSS transform 을 덮어쓰면
   회전 중심이 어긋나 그래프가 화면 밖으로 사라진다 — 절대 건드리지 말 것. */
.ub-a svg.ub-donut-svg{
  transform-origin:center;
  animation: ub-donut-in calc(var(--a-dur) * 1.1) var(--a-ease) backwards;
  animation-delay:140ms;
}
@keyframes ub-donut-in{ from{ opacity:0; transform:scale(.9) } }

/* 선 그래프: 왼쪽부터 그려진다 (길이는 anim.js 가 계산해 --len 으로 넣는다) */
.ub-a svg polyline.ub-line{
  animation: ub-line-draw var(--line-dur, 1000ms) linear backwards;
  animation-delay: var(--line-delay, 160ms);
}
@keyframes ub-line-draw{ from{ stroke-dashoffset: var(--len, 1000) } to{ stroke-dashoffset: 0 } }

/* 점: 선이 그 위치에 닿는 순간 나타난다 (--t = 0~1 진행 위치) */
.ub-a svg circle.ub-dot{
  transform-box: fill-box; transform-origin:center;
  animation: ub-dot-in 220ms var(--a-ease) backwards;
  animation-delay: calc(var(--line-delay, 160ms) + var(--t, 0) * var(--line-dur, 1000ms));
}
@keyframes ub-dot-in{ from{ opacity:0; transform:scale(.2) } }

/* KPI 숫자: 살짝 튀어오르며 */
.ub-a .t-kpi{
  animation: ub-kpi calc(var(--a-dur) * 1.1) cubic-bezier(.34,1.5,.5,1) backwards;
  animation-delay: calc(var(--i, 0) * var(--a-gap) + 80ms);
}
@keyframes ub-kpi{ from{ opacity:0; transform:translateY(10px) scale(.9) } }

/* ── 페이지 전환 ───────────────────────────────────────────── */
.ub-t-fade{ animation: ub-t-fade var(--t-dur) var(--a-ease) }
@keyframes ub-t-fade{ from{ opacity:0 } }

.ub-t-slide{ animation: ub-t-slide var(--t-dur) var(--a-ease) }
@keyframes ub-t-slide{ from{ opacity:0; transform:translateX(48px) } }
.ub-t-slide.rev{ animation-name: ub-t-slide-rev }
@keyframes ub-t-slide-rev{ from{ opacity:0; transform:translateX(-48px) } }

.ub-t-zoom{ animation: ub-t-zoom var(--t-dur) var(--a-ease) }
@keyframes ub-t-zoom{ from{ opacity:0; transform:scale(.92) } }
.ub-t-zoom.rev{ animation-name: ub-t-zoom-rev }
@keyframes ub-t-zoom-rev{ from{ opacity:0; transform:scale(1.08) } }

.ub-t-flip{ animation: ub-t-flip var(--t-dur) var(--a-ease); transform-origin:center }
@keyframes ub-t-flip{ from{ opacity:0; transform:perspective(1400px) rotateY(14deg) } }
.ub-t-flip.rev{ animation-name: ub-t-flip-rev }
@keyframes ub-t-flip-rev{ from{ opacity:0; transform:perspective(1400px) rotateY(-14deg) } }

/* ── 발표 모드 (전체화면 슬라이드) ─────────────────────────── */
#presentView{
  position:fixed; inset:0; z-index:900; background:#000; display:none;
  place-items:center; overflow:hidden; cursor:none;
}
#presentView.on{ display:grid }
#presentView.cursor{ cursor:default }
#pvStage{ position:relative; overflow:hidden }
#pvBar{
  position:fixed; left:0; right:0; bottom:0; height:48px; display:flex; align-items:center;
  justify-content:center; gap:16px; color:#8B94A3; font-size:13px; background:rgba(0,0,0,.55);
  opacity:0; transition:opacity 220ms ease; z-index:2;
}
#presentView.cursor #pvBar{ opacity:1 }
#pvBar button{ background:#1A1D23; border:1px solid #2A2F39; color:#E6E9EF; border-radius:8px; padding:5px 12px }
#pvBar .grow{ flex:0 0 auto }
#pvNotes{
  position:fixed; left:0; right:0; bottom:48px; max-height:26vh; overflow:auto; padding:14px 22px;
  background:rgba(0,0,0,.72); color:#C9D2DE; font-size:15px; line-height:1.7; white-space:pre-wrap;
  display:none; z-index:2;
}
#presentView.notes #pvNotes{ display:block }
#pvProgress{ position:fixed; left:0; top:0; height:3px; background:var(--accent,#2776FF); z-index:3;
  transition:width 260ms ease }
