/* 화면 전환 · 등장 모션 · 로딩 표시 (motion.js와 짝)
   원칙: transform·opacity만 움직인다(레이아웃을 흔들지 않음) · 120~320ms · 등장 지연 합계 400ms 이하
   · 감속 곡선 cubic-bezier(.2,.7,.2,1) · prefers-reduced-motion이면 움직이지 않는다(로딩 표시는 정적으로).
   html.ax-m = motion.js가 실행됨. 페이지 CSS보다 먼저 읽히므로 덮어쓰는 규칙은 html.ax-m으로 우선순위를 올린다. */

:root {
  --ax-ease: cubic-bezier(.2, .7, .2, 1);
  --ax-ease-in: cubic-bezier(.4, 0, .9, .6);
}

/* ---------- 1. 페이지 전환 (같은 사이트 이동 · Chrome·Edge 126+) ----------
   상단 바는 제자리에 두고(이름 붙여 따로 캡처), 이전 화면이 위로 살짝 빠지며 걷히는 동안 새 화면 블록이 그 아래에서
   함께 올라온다(교차 전환, 순차 등장 2). 지원하지 않는 브라우저는 2만 보인다.
   로그인 ↔ 업무 화면, 뒤로·앞으로, 축소 배율에서는 motion.js가 전환을 건너뛴다(바로 바뀌고 2만 보인다). */
@view-transition { navigation: auto; }
.topbar { view-transition-name: ax-topbar; }
.ax-bar { view-transition-name: ax-bar; }

/* 전환 중(의사 요소가 화면을 덮는 동안)에는 클릭이 화면 요소에 닿지 않으므로 전환 자체는 짧게(약 0.17초) 끝내고,
   나머지 등장은 새 화면의 순차 등장(2)이 맡는다 */
::view-transition-group(root) { animation-duration: 160ms; }
/* 이전 화면을 위에 두고 빠르게 걷어 낸다(겹쳐 보이는 시간을 줄인다). 배경색이 같아 섞임 없이 보통 합성 */
::view-transition-old(root) { z-index: 1; mix-blend-mode: normal; animation: ax-vt-out 160ms cubic-bezier(.1, .5, .3, 1) both; }
::view-transition-new(root) { mix-blend-mode: normal; animation: none; }
::view-transition-group(ax-topbar), ::view-transition-old(ax-topbar), ::view-transition-new(ax-topbar),
::view-transition-group(ax-bar), ::view-transition-old(ax-bar), ::view-transition-new(ax-bar) { animation-duration: 160ms; }
@keyframes ax-vt-out { to { opacity: 0; transform: translateY(-4px); } }

/* ---------- 2. 레이아웃 순차 등장 (첫 표시 때만, 지연은 motion.js가 위치 순으로 매긴다) ---------- */
/* 블록 등장(6px 페이드업)·안쪽 항목(4px)·처음 채움·탭 교차 페이드는 motion.js가 Web Animations로 건다.
   순서를 정할 때까지(main을 다 읽고 화면 CSS를 받은 뒤 첫 작업이나 첫 그리기 직전, 늦어도 1.5초) 본문을 감춰 깜빡임을 막는다 */
html.ax-boot main.page { opacity: 0; }
@keyframes ax-rise { from { opacity: 0; transform: translateY(8px); } }
@keyframes ax-fade { from { opacity: 0; } }
/* 원본 면 뷰어: 주소를 받기 전 빈 이미지의 깨진 아이콘·대체 글자와 흰 종이(무대)가 잠깐 보이지 않게 */
.vw-stage img:not([src]), .pv-stage img:not([src]) { visibility: hidden; }
html.ax-m .vw-stage:has(> img:not([src])) { background: transparent; box-shadow: none; }
/* 기록물 상세 머리: 둘째 줄(등록·면수)과 검수 진행 줄의 자리를 자료를 받기 전부터 잡아 둔다
   (채워질 때 머리가 18px 커지며 아래 작업 영역이 밀리지 않게. 12px·14px 글자 × 줄 높이 1.5) */
html.ax-m #rv-sub:empty { min-height: 18px; }
html.ax-m #rv-prog:empty { min-height: 21px; }
/* 카운트업 중인 숫자: 자리 폭이 흔들리지 않게(최종 폭은 motion.js가 잡는다) */
.ax-count { display: inline-block; font-variant-numeric: tabular-nums; text-align: right; }

/* ---------- 3a. 상단 진행 막대 (Teal 얇은 막대) ----------
   진행·사라짐은 motion.js가 requestAnimationFrame으로 그린다(CSS 전환·애니메이션 없음: 화면 이동 중 새로 시작한
   CSS 애니메이션이 있으면 전환 때 화면이 잠깐 비는 경우가 있었다). */
.ax-bar { position: fixed; left: 0; right: 0; top: 0; z-index: 1000; height: 3px; overflow: hidden; pointer-events: none; opacity: 0; }
.ax-bar.on { opacity: 1; }
.ax-bar > i { position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, rgba(0, 173, 181, .55), var(--teal) 30%, var(--teal) calc(100% - 64px), #7FE3E8); }
/* 앞 끝의 은은한 빛 (NProgress의 페그) */
.ax-bar > i::after { content: ""; position: absolute; right: 0; top: 0; width: 80px; height: 100%; box-shadow: 0 0 10px 1px rgba(0, 173, 181, .65); opacity: .8; }

/* ---------- 3b. 로딩 이미지 (DEEP.i 로고 마크 + 회전 링 + 맥동) ----------
   나타나기·사라지기·링 회전·맥동은 motion.js가 requestAnimationFrame으로 그린다(진행 막대와 같은 이유). */
.ax-loader { position: fixed; inset: 51px 0 0; z-index: 900; display: grid; place-items: center; pointer-events: none;
  background: rgba(238, 238, 238, .5); opacity: 0; visibility: hidden; }
.ax-loader.on { visibility: visible; }
.login-body .ax-loader { display: none; }
.ax-ld { display: grid; justify-items: center; gap: 12px; min-width: 168px; padding: 24px 30px 18px; border-radius: 14px;
  background: rgba(255, 255, 255, .94); border: 1px solid rgba(0, 0, 0, .05);
  box-shadow: 0 12px 36px rgba(34, 40, 49, .14), 0 2px 6px rgba(34, 40, 49, .06); }
.ax-ld-mark { position: relative; width: 68px; height: 68px; display: grid; place-items: center; }
.ax-ld-ring { position: absolute; inset: 0; width: 68px; height: 68px; transform: rotate(-90deg); }
.ax-ld-ring circle { fill: none; stroke-width: 3; }
.ax-ld-ring .tr { stroke: rgba(0, 173, 181, .18); }
.ax-ld-ring .arc { stroke: var(--teal); stroke-linecap: round; stroke-dasharray: 50 164; }
.ax-ld-logo { width: 40px; height: 40px; border-radius: 9px; overflow: hidden; box-shadow: 0 6px 16px rgba(0, 173, 181, .28); }
.ax-ld-logo svg { display: block; width: 40px; height: 40px; }
.ax-ld-t { font-size: 13px; font-weight: 700; color: var(--text-sub); letter-spacing: .01em; }

/* ---------- 3c. 스켈레톤 (은은한 반짝임 · transform으로만 훑는다) ---------- */
.ax-sk { position: relative; display: block; height: 12px; min-width: 14px; max-width: 100%; border-radius: 6px; overflow: hidden; background: #ECEEF1; }
.ax-sk::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .75), transparent); animation: ax-sweep 1.4s ease-in-out infinite; }
@keyframes ax-sweep { to { transform: translateX(100%); } }
/* 데이터가 150ms 안에 오면 스켈레톤을 보이지 않는다(짧은 로딩에 깜빡이지 않게) */
.ax-sk-wait { animation: ax-fade 200ms ease-out 150ms both; }
tr.ax-sk-row td { height: 49px; vertical-align: middle; }
tr.ax-sk-row:nth-child(even) td { background: var(--surface); }
.ax-skc { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; border: 1px solid var(--border-soft); border-left: 3px solid #DCE2E8; border-radius: var(--radius); background: var(--surface); min-height: 96px; }
.ax-skc .ax-sk:first-child { width: 38%; height: 14px; }
.ax-skc .ax-sk.s { width: 62%; }
/* 기록물 목록: 처음 불러오는 동안 상태 필터의 건수(0)와 없을 수도 있는 단추(등록·오류)를 감춰, 값이 들어올 때 덜 흔들리게 */
.rl-panel:has(tbody tr.ax-sk-row) #rl-status button[data-optional] { display: none; }
.rl-panel:has(tbody tr.ax-sk-row) #rl-status b { opacity: 0; }

/* ---------- 4. 마이크로 인터랙션 ---------- */
/* 버튼: 누르면 살짝 눌림 */
html.ax-m .btn { transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .14s var(--ax-ease); }
html.ax-m .btn:active:not([disabled]):not(.disabled) { transform: translateY(1px) scale(.985); }
/* 카드: 은은한 떠오름 (그림자는 각 화면의 호버 그림자를 그대로 쓴다) */
html.ax-m a.kpi { transition: border-color .15s, box-shadow .2s, transform .2s var(--ax-ease); }
html.ax-m a.kpi:hover { transform: translateY(-2px); }
html.ax-m .pp-cell { transition: background-color .15s, transform .2s var(--ax-ease); }
html.ax-m .pp-cell:hover { transform: translateY(-2px); }
html.ax-m .pp-gcard { transition: border-color .14s, box-shadow .2s, transform .2s var(--ax-ease); }
html.ax-m .pp-gcard:hover { transform: translateY(-2px); }
html.ax-m .pf-step { transition: box-shadow .2s, border-color .2s, transform .2s var(--ax-ease); }
html.ax-m .pf-step:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(34, 40, 49, .08); }
html.ax-m .rn-type { transition: border-color .12s, background-color .12s, box-shadow .2s, transform .2s var(--ax-ease); }
html.ax-m .rn-type:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(34, 40, 49, .07); }
/* 표의 행: 배경을 부드럽게 바꾸고 첫 칸에 Teal 선 */
html.ax-m .tbl tr.clickable td { transition: background-color .14s ease, box-shadow .14s ease; }
html.ax-m .tbl tr.clickable:hover td:first-child { box-shadow: inset 3px 0 0 var(--teal); }
/* 상단 메뉴의 하위 메뉴: 페이드 + 살짝 내려오며 열림 */
html.ax-m .nav .sub { display: block; visibility: hidden; opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity .16s var(--ax-ease), transform .16s var(--ax-ease), visibility 0s linear .16s; }
html.ax-m .nav .item:hover .sub, html.ax-m .nav .item:focus-within .sub { visibility: visible; opacity: 1; transform: none; pointer-events: auto; transition-delay: 0s; }
/* 접기·펼치기 내용 */
html.ax-m details[open] > :not(summary) { animation: ax-drop 200ms var(--ax-ease) both; }
@keyframes ax-drop { from { opacity: 0; transform: translateY(-4px); } }
/* 모달: 배경 페이드 + 창 페이드·확대 */
html.ax-m .modal-back.open { animation: ax-fade 180ms var(--ax-ease) both; }
html.ax-m .modal-back.open > .modal { animation: ax-pop 240ms var(--ax-ease) both; }
@keyframes ax-pop { from { opacity: 0; transform: translateY(8px) scale(.97); } }
/* 닫힌 창의 복제본(motion.js): 잠깐 흐려지며 사라진다. 누를 수 없다 */
html.ax-m .modal-back.open.ax-ghost { pointer-events: none; animation: ax-fade-out 180ms var(--ax-ease-in) both; }
html.ax-m .modal-back.open.ax-ghost > .modal { animation: ax-pop-out 180ms var(--ax-ease-in) both; }
@keyframes ax-fade-out { to { opacity: 0; } }
@keyframes ax-pop-out { to { opacity: 0; transform: translateY(4px) scale(.98); } }
/* 토스트: 오른쪽에서 밀려 들어오고, 닫힐 때 오른쪽으로 빠진다(위치는 기존 그대로 오른쪽 아래) */
html.ax-m .toast { animation: ax-toast-in 280ms var(--ax-ease) both; }
html.ax-m .toast.ax-out { animation: ax-toast-out 200ms var(--ax-ease-in) both; pointer-events: none; }
@keyframes ax-toast-in { from { opacity: 0; transform: translateX(24px); } }
@keyframes ax-toast-out { to { opacity: 0; transform: translateX(20px); } }
/* ---------- 5. 로그인 화면: 로고 → 제목 → 카드 순서로 등장, 로그인 버튼 안 작은 스피너 ---------- */
html.ax-m .login-hero > *, html.ax-m .login-card { animation: ax-rise 320ms var(--ax-ease) both; }
html.ax-m .login-hero > .hero-mark { animation-name: ax-mark; }
html.ax-m .login-hero > :nth-child(2) { animation-delay: 60ms; }
html.ax-m .login-hero > :nth-child(3) { animation-delay: 110ms; }
html.ax-m .login-hero > :nth-child(4) { animation-delay: 150ms; }
html.ax-m .login-hero > :nth-child(5) { animation-delay: 200ms; }
html.ax-m .login-card { animation-delay: 130ms; }
/* 비밀번호가 틀려 다시 그린 화면은 다시 움직이지 않는다 */
html.ax-m .login-body:has(.login-card .alert) .login-hero > *, html.ax-m .login-body:has(.login-card .alert) .login-card { animation: none; }
@keyframes ax-mark { from { opacity: 0; transform: scale(.9); } }
/* 로그인 단추 안 스피너(motion.js가 넣고 rAF로 돌린다): 글자 왼쪽에 겹쳐 두어 단추 안 배치가 흔들리지 않게 */
.btn.ax-busy { position: relative; }
.ax-bspin { position: absolute; left: 50%; top: 50%; width: 14px; height: 14px; margin: -7px 0 0 -54px;
  border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff; border-radius: 50%; }

/* ---------- 6. 움직임 줄이기: 전환·등장·카운트업을 끄고 로딩 표시는 정적으로 ---------- */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  .ax-sk-wait, html.ax-m .toast, html.ax-m .modal-back.open, html.ax-m .modal-back.open > .modal,
  html.ax-m details[open] > :not(summary), html.ax-m .login-hero > *, html.ax-m .login-card { animation: none !important; }
  .ax-sk::after { animation: none; }
  html.ax-m .nav .sub { transition: none; }
  html.ax-m .btn:active:not([disabled]):not(.disabled), html.ax-m a.kpi:hover, html.ax-m .pp-cell:hover, html.ax-m .pp-gcard:hover,
  html.ax-m .pf-step:hover, html.ax-m .rn-type:hover { transform: none; }
  html.ax-m .nav .sub { transform: none; }
}
