/* motion-lab anatomy — 구조 분해 패널 + 모션 유닛 와이어프레임 데모
   gallery.html의 :root 토큰(--bg --ink --brand --tint --line …)을 그대로 사용 */

/* ── 카드 트리거 ── */
.anat-btn {
  align-self: flex-start; margin-top: 2px;
  font-family: inherit; font-size: 11px; font-weight: 600; letter-spacing: .06em;
  color: var(--brand); background: var(--tint); border: 0; border-radius: var(--radius);
  padding: 4px 10px; cursor: pointer; transition: background-color .2s ease, color .2s ease;
}
.anat-btn:hover { background: var(--brand); color: #fff; }

/* ── 모달 ── */
#anat { position: fixed; inset: 0; z-index: 200; background: rgba(25, 23, 49, .45); display: flex; align-items: center; justify-content: center; padding: clamp(12px, 3vw, 40px); }
#anat[hidden] { display: none; }
.an-panel {
  background: var(--bg); border: 1px solid var(--line-strong); border-radius: var(--radius);
  box-shadow: 0 32px 90px rgba(25, 23, 49, .32);
  width: min(1060px, 100%); height: 100%; max-height: 880px;
  display: flex; flex-direction: column; overflow: hidden;
}
/* 상단 고정 헤더 — 이름 + 닫기 */
.an-bar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 13px clamp(20px, 3vw, 32px); border-bottom: 1px solid var(--line); background: var(--bg); }
.an-bar .t { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.an-bar .nm { font-size: 16px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.an-close {
  font-family: inherit; font-size: 12px; font-weight: 600; letter-spacing: .08em;
  color: var(--ink); background: none; border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 8px 16px; cursor: pointer; white-space: nowrap; transition: border-color .2s ease, color .2s ease;
}
.an-close:hover, .an-close:focus-visible { border-color: var(--brand); color: var(--brand); }
.an-scroll { overflow-y: auto; overscroll-behavior: contain; padding: 0 clamp(20px, 3vw, 32px) 72px; }

/* 축 전환 탭 (모달 헤더) — 버튼 사이 1px 분리는 컨테이너 배경이 gap으로 비치는 방식 */
.an-tabs { display: flex; gap: 1px; background: var(--line-strong); border: 1px solid var(--line-strong); border-radius: var(--radius); overflow: hidden; }
.an-tabs button {
  font-family: inherit; font-size: 12px; font-weight: 600; letter-spacing: .04em;
  color: var(--muted); background: var(--bg); border: 0; padding: 8px 14px; cursor: pointer; white-space: nowrap;
}
.an-tabs button.on { color: var(--brand); background: var(--tint); }
.an-tabs button .cnt { color: var(--line-strong); margin-left: 4px; font-weight: 500; }
.an-tabs button.on .cnt { color: var(--brand); opacity: .6; }
.av[hidden] { display: none; }

.an-head { padding: clamp(20px, 3vw, 30px) 0 8px; }
.an-desc { font-size: 14px; color: var(--ink); max-width: 640px; }
.an-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.an-ev { width: 100%; font-size: 11px; color: var(--muted); margin-top: 6px; line-height: 1.7; }
.an-ev b { color: var(--ink); font-weight: 600; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; margin-right: 6px; }
.an-meta .out { font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--brand); text-decoration: none; margin-left: 8px; }
.an-meta .out:hover { color: var(--brand-deep); }

.an-sec { margin-top: clamp(36px, 5vw, 60px); }
.an-sec-h { display: grid; grid-template-columns: minmax(90px, 130px) 1fr; gap: 16px; }
.an-sec-h h2 { font-size: clamp(22px, 2.4vw, 26px); font-weight: 600; letter-spacing: -.02em; line-height: 1.3; }
.an-cap { font-size: 13px; color: var(--muted); margin-top: 6px; max-width: 640px; }

/* 유닛 행 — editorial numbered list */
.an-list { margin-top: 22px; }
.an-row { display: grid; grid-template-columns: 56px 1fr 300px; gap: clamp(16px, 3vw, 32px); padding: 24px 0; border-top: 1px solid var(--line); align-items: start; }
.an-row:last-child { border-bottom: 1px solid var(--line); }
.an-no { font-size: 34px; font-weight: 300; color: var(--muted); line-height: 1.1; font-variant-numeric: tabular-nums; }
.an-row h3 { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.an-row h3 em { font-style: normal; font-weight: 500; font-size: 11px; letter-spacing: .08em; color: var(--muted); margin-left: 8px; text-transform: uppercase; }
.an-row h3 .lvl { margin-left: 10px; }
.an-note { font-size: 13px; color: var(--ink); margin-top: 7px; }
.an-note b { color: var(--brand); font-weight: 600; }
.an-d { font-size: 12px; color: var(--muted); margin-top: 8px; max-width: 56ch; }
.an-how { font-size: 12px; color: var(--muted); margin-top: 6px; max-width: 56ch; }
.an-how b { color: var(--ink); font-weight: 600; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; margin-right: 6px; }
.an-use { font-size: 11px; color: var(--muted); margin-top: 10px; }
.an-use b { color: var(--brand); }

/* 전체 구조 체인 */
.an-f { font-size: 13px; color: var(--ink); margin-top: 6px; max-width: 640px; }
.an-chain { display: flex; align-items: stretch; overflow-x: auto; padding: 20px 0 8px; }
.an-step { flex: none; width: 184px; border: 1px solid var(--line-strong); border-radius: var(--radius); padding: 12px 14px; }
.an-step span { display: block; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.an-step b { display: block; font-size: 13px; letter-spacing: -.01em; margin-top: 2px; }
.an-step i { display: block; font-style: normal; font-size: 11px; color: var(--muted); margin-top: 5px; line-height: 1.55; }
.an-link { flex: none; width: 26px; height: 1px; background: var(--line-strong); align-self: center; }

/* ── 유닛 라이브러리 섹션 (갤러리 본문) ── */
.u-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 28px 18px; margin-top: 28px; }
.u-card { border-top: 1px solid var(--line); padding-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.u-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.u-head h3 { font-size: 13px; font-weight: 700; letter-spacing: -.01em; }
.u-card .wf { margin-top: 4px; }
.u-card p { font-size: 12px; color: var(--muted); line-height: 1.6; }
.u-use { font-size: 11px; color: var(--muted); }
.u-use b { color: var(--brand); }

@media (max-width: 768px) {
  #anat { padding: 0; }
  .an-panel { max-height: none; border: 0; border-radius: 0; }
  .an-row { grid-template-columns: 1fr; gap: 10px; }
  .an-no { font-size: 24px; }
  .an-row .wf { max-width: 440px; }
  .an-sec-h { grid-template-columns: 1fr; gap: 6px; }
}

/* ════════════════════════════════════════════════════
   와이어프레임 데모 스테이지 — 공통 어휘
   .wl 텍스트 라인 / .wb 블록 / .a 절대배치 / .rail 스크롤 레일
   스크롤 구동형은 레일(10%→90%)과 같은 타임라인을 쓴다
   ════════════════════════════════════════════════════ */
@property --wfn { syntax: '<integer>'; inherits: true; initial-value: 0; }

.wf {
  position: relative; aspect-ratio: 16/10; width: 100%;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; contain: layout paint; --t: 4.6s;
}
.wf .wl { display: block; height: 6px; border-radius: 1px; background: var(--line-strong); }
.wf .wb { display: block; background: var(--surface); border: 1px solid var(--line); border-radius: 1px; }
.wf .a { position: absolute; }
.wf .rail { position: absolute; right: 7px; top: 10%; bottom: 10%; width: 2px; background: var(--line); border-radius: 1px; }
.wf .rail i { position: absolute; left: -1.5px; width: 5px; height: 20%; border-radius: 2.5px; background: var(--brand); animation: wfRail var(--t) linear infinite; }
@keyframes wfRail { 0%, 10% { top: 0; } 90%, 100% { top: 80%; } }

/* 화면 밖 데모는 정지 (JS가 .run 토글) */
.wf:not(.run) *, .wf:not(.run) *::before, .wf:not(.run) *::after { animation-play-state: paused !important; }
@media (prefers-reduced-motion: reduce) {
  .wf *, .wf *::before, .wf *::after { animation: none !important; }
}

/* ── 페이지 설계(레이아웃) 정적 와이어프레임 어휘 ── */
.wfs { --t: 0s; } /* 정적 — 애니메이션 없음, 절전 게이트 불필요 */
.wfs .lno { font-size: 13px; font-weight: 300; color: var(--muted); font-variant-numeric: tabular-nums; font-style: normal; }
.wfs .lcard { width: 26%; height: 18%; border: 1px solid var(--line-strong); border-radius: 2px; background: var(--bg); }
.wfs .lcard.on { border-color: var(--brand); background: var(--tint); }
.wfs .lnode { width: 16px; height: 16px; border: 1.5px solid var(--line-strong); border-radius: 50%; background: var(--surface); }
.wfs .lnode.on { border-color: var(--brand); background: var(--brand); }
.wfs .lbar { width: 9%; background: var(--line-strong); border-radius: 1px 1px 0 0; }
.wfs .lbar.on { background: var(--brand); }

/* 01 smooth — 관성 스크롤: 콘텐츠가 레일(선형)을 부드럽게 뒤따름 */
.wf-smooth .smc { position: absolute; left: 12%; top: 12%; width: 70%; display: flex; flex-direction: column; gap: 8px; animation: wfSm var(--t) cubic-bezier(.33, 0, .11, 1) infinite; }
.wf-smooth .wb { flex: none; height: 30px; }
@keyframes wfSm { 0%, 10% { transform: translateY(0); } 84% { transform: translateY(-53%); } 90%, 100% { transform: translateY(-50%); } }

/* 02 preloader — 카운터 → 커튼 → 히어로 */
.wf-preloader .prc { position: absolute; inset: 0; background: var(--ink); animation: wfPrc var(--t) ease-in-out infinite; }
@keyframes wfPrc { 0%, 52% { transform: none; } 62%, 86% { transform: translateY(-101%); } 94%, 100% { transform: none; } }
.wf-preloader .prn { position: absolute; right: 9%; bottom: 10%; color: #fff; font-size: 26px; font-weight: 300; font-variant-numeric: tabular-nums; animation: wfPrn var(--t) infinite; }
.wf-preloader .prn::after { counter-reset: wfn var(--wfn); content: counter(wfn); }
@keyframes wfPrn {
  0%, 6% { --wfn: 0; opacity: 1; }
  46%, 52% { --wfn: 100; opacity: 1; }
  58% { --wfn: 100; opacity: 0; }
  94% { --wfn: 0; opacity: 0; }
  100% { --wfn: 0; opacity: 1; }
}

/* 03 reveal — 줄 단위 마스크 리빌 */
.wf-reveal .rvc { position: absolute; left: 12%; top: 30%; width: 72%; display: flex; flex-direction: column; gap: 9px; }
.wf-reveal .rvc span { display: block; height: 11px; overflow: hidden; }
.wf-reveal .rvc i { display: block; height: 11px; border-radius: 1px; background: var(--ink); transform: translateY(130%); animation: wfRv var(--t) cubic-bezier(.22, 1, .36, 1) infinite; }
.wf-reveal .rvc span:nth-child(2) i { animation-delay: .14s; }
.wf-reveal .rvc span:nth-child(3) i { animation-delay: .28s; background: var(--brand); }
@keyframes wfRv { 0% { transform: translateY(130%); } 12%, 60% { transform: none; } 74%, 100% { transform: translateY(130%); } }

/* 04 kinetic — 스크롤 속도에 반응하는 글자 탄성 */
.wf-kinetic .ktw { position: absolute; left: 12%; bottom: 14%; display: flex; font-size: 58px; font-weight: 800; letter-spacing: -.03em; line-height: 1; color: var(--ink); }
.wf-kinetic .ktw b { display: inline-block; transform-origin: 50% 100%; animation: wfKt var(--t) ease-in-out infinite; }
.wf-kinetic .ktw b:nth-child(2) { animation-delay: .07s; }
.wf-kinetic .ktw b:nth-child(3) { animation-delay: .14s; color: var(--brand); }
.wf-kinetic .ktw b:nth-child(4) { animation-delay: .21s; }
@keyframes wfKt { 0%, 14% { transform: none; } 30% { transform: scaleY(1.7) scaleX(.9); } 40% { transform: scaleY(.78); } 48% { transform: scaleY(1.12); } 56%, 100% { transform: none; } }

/* 05 physics — 중력 낙하·충돌·안착 */
.wf-physics .phw i { position: absolute; background: var(--surface); border: 1.5px solid var(--ink); border-radius: 2px; }
.wf-physics .p1 { width: 36px; height: 36px; left: 28%; top: -22%; animation: wfPh1 var(--t) ease-in infinite; }
.wf-physics .p2 { width: 26px; height: 26px; left: 46%; top: -22%; background: var(--tint); animation: wfPh2 var(--t) ease-in infinite; }
.wf-physics .p3 { width: 18px; height: 18px; left: 62%; top: -22%; background: var(--brand); border-color: var(--brand); animation: wfPh3 var(--t) ease-in infinite; }
@keyframes wfPh1 {
  0%, 6% { top: -22%; transform: rotate(0); }
  30% { top: calc(82% - 36px); transform: rotate(4deg); animation-timing-function: ease-out; }
  40% { top: calc(66% - 36px); transform: rotate(9deg); animation-timing-function: ease-in; }
  50%, 92% { top: calc(82% - 36px); transform: rotate(7deg); }
  97%, 100% { top: -22%; transform: rotate(0); }
}
@keyframes wfPh2 {
  0%, 14% { top: -22%; transform: rotate(0); }
  38% { top: calc(82% - 26px); transform: rotate(-6deg); animation-timing-function: ease-out; }
  47% { top: calc(70% - 26px); transform: rotate(-12deg); animation-timing-function: ease-in; }
  56%, 92% { top: calc(82% - 26px); transform: rotate(-9deg); }
  97%, 100% { top: -22%; transform: rotate(0); }
}
@keyframes wfPh3 {
  0%, 24% { top: -22%; transform: rotate(0); }
  46% { top: calc(82% - 18px); transform: rotate(14deg); animation-timing-function: ease-out; }
  54% { top: calc(72% - 18px); transform: rotate(24deg); animation-timing-function: ease-in; }
  62%, 92% { top: calc(82% - 18px); transform: rotate(18deg); }
  97%, 100% { top: -22%; transform: rotate(0); }
}

/* 06 marquee — 무한 벨트 */
.wf-marquee .mq { position: absolute; left: 0; display: flex; white-space: nowrap; font-weight: 800; font-size: 22px; letter-spacing: .02em; }
.wf-marquee .q1 { top: 30%; color: var(--ink); }
.wf-marquee .q2 { top: 52%; color: var(--line-strong); }
.wf-marquee .mq span { display: block; animation: wfMq 8s linear infinite; }
.wf-marquee .q2 span { animation-direction: reverse; }
@keyframes wfMq { to { transform: translateX(-100%); } }

/* 07 pin — 화면 고정 + 내부 씬 진행 */
.wf-pin .pnc { position: absolute; inset: 0; animation: wfPnc var(--t) linear infinite; }
@keyframes wfPnc { 0%, 10% { transform: none; } 90%, 100% { transform: translateY(-115%); } }
.wf-pin .pnf { position: absolute; left: 24%; top: 25%; width: 52%; height: 50%; border: 1.5px solid var(--ink); border-radius: 2px; background: var(--bg); }
.wf-pin .pns { position: absolute; inset: 14% 12%; display: flex; flex-direction: column; gap: 9px; opacity: 0; }
.wf-pin .pns .wb { flex: 1; }
.wf-pin .s1 { animation: wfPn1 var(--t) steps(1, end) infinite; }
.wf-pin .s2 { animation: wfPn2 var(--t) steps(1, end) infinite; }
.wf-pin .s3 { animation: wfPn3 var(--t) steps(1, end) infinite; }
@keyframes wfPn1 { 0%, 32% { opacity: 1; } 33%, 100% { opacity: 0; } }
@keyframes wfPn2 { 0%, 33% { opacity: 0; } 34%, 62% { opacity: 1; } 63%, 100% { opacity: 0; } }
@keyframes wfPn3 { 0%, 63% { opacity: 0; } 64%, 100% { opacity: 1; } }

/* 08 scrub — 스크롤=재생 헤드 (프레임 스텝) */
.wf-scrub .sqb { position: absolute; left: 50%; top: 50%; width: 70px; height: 70px; margin: -35px 0 0 -35px; border: 2px solid var(--ink); background: var(--surface); border-radius: 2px; animation: wfSq var(--t) infinite; }
.wf-scrub .sqb::after { content: ''; position: absolute; left: 50%; top: 6px; width: 8px; height: 8px; margin-left: -4px; border-radius: 50%; background: var(--brand); }
@keyframes wfSq { 0%, 10% { transform: rotate(0); animation-timing-function: steps(22); } 90%, 100% { transform: rotate(300deg); } }

/* 09 parallax — 레이어별 속도 차 */
.wf-parallax .pxa { position: absolute; inset: 0; --amt: 8px; animation: wfPx var(--t) linear infinite; }
.wf-parallax .pxb { --amt: 20px; animation: wfPx var(--t) linear infinite; }
.wf-parallax .pxc { --amt: 38px; background: var(--ink); border-radius: 1px; animation: wfPx var(--t) linear infinite; }
@keyframes wfPx { 0%, 10% { transform: translateY(var(--amt)); } 90%, 100% { transform: translateY(calc(-1 * var(--amt))); } }

/* 10 horizontal — 세로 입력 → 가로 이동 */
.wf-horizontal .hzt { position: absolute; left: 8%; top: 22%; height: 56%; display: flex; gap: 12px; animation: wfHz var(--t) cubic-bezier(.3, 0, .15, 1) infinite; }
.wf-horizontal .hzp { flex: none; width: 110px; border: 1px solid var(--line-strong); border-radius: 2px; padding: 10px; display: flex; flex-direction: column; gap: 8px; background: var(--bg); }
.wf-horizontal .hzp .wb { flex: 1; }
.wf-horizontal .hzp:last-child { background: var(--tint); }
@keyframes wfHz { 0%, 10% { transform: none; } 88%, 100% { transform: translateX(-215px); } }

/* 11 campath — 경로 위 카메라 */
.wf-campath .cpv { position: absolute; left: 0; top: 0; }
.wf-campath .cpv path { stroke: var(--line-strong); stroke-width: 1.5; stroke-dasharray: 3 6; fill: none; }
.wf-campath .cpd { position: absolute; left: 0; top: 0; width: 12px; height: 12px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 5px var(--tint); offset-path: path('M18,158 C96,28 208,196 300,52'); animation: wfCp var(--t) ease-in-out infinite; }
@keyframes wfCp { 0%, 8% { offset-distance: 0%; } 90%, 100% { offset-distance: 100%; } }

/* 12 hero3d — 주인공 오브젝트 관성 회전 */
.wf-hero3d .h3s { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; perspective: 520px; }
.wf-hero3d .h3c { width: 74px; height: 74px; border: 2px solid var(--ink); border-radius: 3px; background: linear-gradient(135deg, var(--tint), var(--surface)); box-shadow: 0 18px 24px -14px rgba(25, 23, 49, .35); animation: wfH3 var(--t) ease-in-out infinite; }
@keyframes wfH3 { 0% { transform: rotateY(-30deg) rotateX(10deg); } 30% { transform: rotateY(24deg) rotateX(-12deg); } 55% { transform: rotateY(38deg) rotateX(8deg); } 80% { transform: rotateY(-8deg) rotateX(-6deg); } 100% { transform: rotateY(-30deg) rotateX(10deg); } }
.wf-hero3d .h3d { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: var(--brand); animation: wfH3d var(--t) ease-in-out infinite; }
@keyframes wfH3d { 0% { left: 22%; top: 30%; } 30% { left: 72%; top: 26%; } 55% { left: 78%; top: 64%; } 80% { left: 28%; top: 68%; } 100% { left: 22%; top: 30%; } }

/* 13 distort — 커서 따라 출렁이는 표면 */
.wf-distort .dtw { position: absolute; left: 16%; top: 20%; width: 64%; height: 58%; display: flex; gap: 3px; }
.wf-distort .dtw i { flex: 1; background: var(--surface); border: 1px solid var(--line); border-radius: 1px; animation: wfDt 3.4s ease-in-out infinite; }
.wf-distort .dtw i:nth-child(odd) { --dy: -7px; }
.wf-distort .dtw i:nth-child(even) { --dy: 7px; }
.wf-distort .dtw i:nth-child(2) { animation-delay: .1s; }
.wf-distort .dtw i:nth-child(3) { animation-delay: .2s; background: var(--tint); }
.wf-distort .dtw i:nth-child(4) { animation-delay: .3s; }
.wf-distort .dtw i:nth-child(5) { animation-delay: .4s; }
.wf-distort .dtw i:nth-child(6) { animation-delay: .5s; }
@keyframes wfDt { 0%, 18%, 82%, 100% { transform: none; } 45% { transform: translateY(var(--dy)) skewY(7deg) scaleY(1.08); } }
.wf-distort .dtd { position: absolute; top: 46%; left: 6%; width: 9px; height: 9px; border-radius: 50%; background: var(--brand); animation: wfDtd 3.4s ease-in-out infinite; }
@keyframes wfDtd { 0% { left: 6%; } 50% { left: 90%; } 100% { left: 6%; } }

/* 14 particles — 유기적 점 군집 */
.wf-particles i { position: absolute; width: 5px; height: 5px; border-radius: 50%; background: var(--ink); opacity: .65; animation: wfPt var(--pd, 5s) ease-in-out infinite alternate; }
.wf-particles i:nth-child(1) { left: 18%; top: 24%; --dx: 14px; --dy: 10px; --pd: 4.2s; }
.wf-particles i:nth-child(2) { left: 34%; top: 60%; --dx: -10px; --dy: -16px; --pd: 5.1s; background: var(--brand); }
.wf-particles i:nth-child(3) { left: 52%; top: 30%; --dx: 12px; --dy: 18px; --pd: 6.0s; }
.wf-particles i:nth-child(4) { left: 70%; top: 56%; --dx: -16px; --dy: 8px; --pd: 4.6s; }
.wf-particles i:nth-child(5) { left: 26%; top: 42%; --dx: 18px; --dy: -8px; --pd: 5.6s; }
.wf-particles i:nth-child(6) { left: 62%; top: 70%; --dx: 8px; --dy: -18px; --pd: 4.9s; background: var(--brand); }
.wf-particles i:nth-child(7) { left: 80%; top: 26%; --dx: -14px; --dy: 12px; --pd: 5.4s; }
.wf-particles i:nth-child(8) { left: 44%; top: 76%; --dx: 10px; --dy: -12px; --pd: 6.3s; }
.wf-particles i:nth-child(9) { left: 58%; top: 48%; --dx: -12px; --dy: -10px; --pd: 4.4s; }
.wf-particles i:nth-child(10) { left: 14%; top: 66%; --dx: 16px; --dy: -14px; --pd: 5.8s; }
.wf-particles i:nth-child(11) { left: 74%; top: 40%; --dx: -8px; --dy: 16px; --pd: 5.2s; background: var(--brand); }
.wf-particles i:nth-child(12) { left: 40%; top: 18%; --dx: -14px; --dy: 12px; --pd: 6.6s; }
@keyframes wfPt { from { transform: none; } to { transform: translate(var(--dx), var(--dy)); } }

/* 15 mask — 도형 확장 와이프 */
.wf-mask .mka { position: absolute; inset: 0; background: var(--bg); }
.wf-mask .mkb { position: absolute; inset: 0; background: var(--ink); clip-path: circle(0% at 66% 60%); animation: wfMk var(--t) ease-in-out infinite; }
@keyframes wfMk { 0%, 10% { clip-path: circle(0% at 66% 60%); } 42%, 64% { clip-path: circle(135% at 66% 60%); } 92%, 100% { clip-path: circle(0% at 66% 60%); } }

/* 16 pagetrans — 커튼이 페이지를 갈아입힘 */
.wf-pagetrans .pta, .wf-pagetrans .ptb { position: absolute; inset: 0; background: var(--bg); }
.wf-pagetrans .pta { animation: wfPta var(--t) steps(1, end) infinite; }
.wf-pagetrans .ptb { animation: wfPtb var(--t) steps(1, end) infinite; }
@keyframes wfPta { 0%, 34% { opacity: 1; } 35%, 82% { opacity: 0; } 83%, 100% { opacity: 1; } }
@keyframes wfPtb { 0%, 34% { opacity: 0; } 35%, 82% { opacity: 1; } 83%, 100% { opacity: 0; } }
.wf-pagetrans .ptc { position: absolute; inset: 0; background: var(--brand); transform: translateX(-105%); animation: wfPtc var(--t) ease-in-out infinite; }
@keyframes wfPtc { 0%, 16% { transform: translateX(-105%); } 34% { transform: translateX(0); } 52%, 64% { transform: translateX(105%); } 82% { transform: translateX(0); } 100% { transform: translateX(-105%); } }

/* 17 cursor — 커스텀 커서 + 자석 버튼 */
.wf-cursor .csb { position: absolute; left: 50%; top: 50%; width: 96px; height: 36px; margin: -18px 0 0 -48px; border: 1px solid var(--line-strong); border-radius: 2px; display: flex; align-items: center; justify-content: center; animation: wfCsb var(--t) ease-in-out infinite; }
@keyframes wfCsb { 0%, 30% { transform: none; } 46%, 60% { transform: translate(7px, -5px); } 78%, 100% { transform: none; } }
.wf-cursor .csd { position: absolute; width: 12px; height: 12px; border-radius: 50%; background: var(--brand); animation: wfCsd var(--t) ease-in-out infinite; }
@keyframes wfCsd {
  0%, 8% { left: 12%; top: 80%; transform: scale(1); opacity: 1; }
  38% { left: 52%; top: 46%; transform: scale(1); opacity: 1; }
  48%, 62% { left: 55%; top: 43%; transform: scale(2.6); opacity: .35; }
  84%, 100% { left: 12%; top: 80%; transform: scale(1); opacity: 1; }
}

/* 18 count — 통계 카운트업 */
.wf-count .ctw { position: absolute; inset: 22% 12% 18%; display: flex; gap: 10%; }
.wf-count .ctw > div { flex: 1; border-top: 1px solid var(--ink); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.wf-count .ctn { font-size: 30px; font-weight: 300; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink); }
.wf-count .ctn::after { counter-reset: wfn var(--wfn); content: counter(wfn); }
.wf-count .c1 { animation: wfC1 var(--t) infinite; }
.wf-count .c2 { animation: wfC2 var(--t) infinite; }
.wf-count .c3 { animation: wfC3 var(--t) infinite; color: var(--brand); }
.wf-count .c3::after { content: counter(wfn) '%'; }
@keyframes wfC1 { 0%, 8% { --wfn: 0; } 50%, 92% { --wfn: 87; } 100% { --wfn: 0; } }
@keyframes wfC2 { 0%, 14% { --wfn: 0; } 56%, 92% { --wfn: 312; } 100% { --wfn: 0; } }
@keyframes wfC3 { 0%, 20% { --wfn: 0; } 62%, 92% { --wfn: 96; } 100% { --wfn: 0; } }

/* 19 draw — 선이 그려지는 차트 */
.wf-draw .dwv { position: absolute; left: 0; top: 0; }
.wf-draw .dwv polyline { fill: none; stroke: var(--brand); stroke-width: 2; stroke-dasharray: 1; stroke-dashoffset: 1; animation: wfDw var(--t) linear infinite; }
@keyframes wfDw { 0%, 10% { stroke-dashoffset: 1; } 88%, 100% { stroke-dashoffset: 0; } }
.wf-draw .dwd { position: absolute; width: 9px; height: 9px; border-radius: 50%; background: var(--brand); offset-path: path('M16,168 L78,120 L132,142 L196,66 L252,96 L306,34'); animation: wfDwd var(--t) linear infinite; }
@keyframes wfDwd { 0%, 10% { offset-distance: 0%; } 88%, 100% { offset-distance: 100%; } }

/* 20 stack — 카드 적층 교체 */
.wf-stack .stw { position: absolute; left: 20%; top: 16%; width: 60%; height: 64%; animation: wfStw var(--t) infinite; }
.wf-stack .stc { position: absolute; inset: 0; border: 1px solid var(--line-strong); border-radius: 2px; background: var(--bg); padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.wf-stack .k1 { animation: wfSt1 var(--t) ease-in-out infinite; }
.wf-stack .k2 { background: var(--surface); transform: translateY(118%); animation: wfSt2 var(--t) ease-in-out infinite; }
.wf-stack .k3 { background: var(--tint); transform: translateY(118%); animation: wfSt3 var(--t) ease-in-out infinite; }
@keyframes wfSt1 { 0%, 28% { transform: none; opacity: 1; } 44%, 100% { transform: scale(.94) translateY(-6px); opacity: .6; } }
@keyframes wfSt2 { 0%, 26% { transform: translateY(118%); } 42%, 58% { transform: translateY(7px); } 74%, 100% { transform: translateY(1px) scale(.96); opacity: .75; } }
@keyframes wfSt3 { 0%, 56% { transform: translateY(118%); } 74%, 100% { transform: translateY(14px); } }
@keyframes wfStw { 0%, 93% { opacity: 1; } 97% { opacity: 0; } 100% { opacity: 1; } }

/* 21 character — 프레임 단위 캐릭터 연기 */
.wf-character .chw { position: absolute; bottom: 21%; left: -12%; width: 34px; height: 58px; animation: wfChX 5.5s linear infinite; }
@keyframes wfChX { from { left: -12%; } to { left: 104%; } }
.wf-character .chh { position: absolute; left: 8px; top: 0; width: 18px; height: 18px; border-radius: 50%; background: var(--ink); animation: wfChB .55s steps(2, jump-none) infinite alternate; }
@keyframes wfChB { from { transform: translateY(0); } to { transform: translateY(-4px); } }
.wf-character .chb { position: absolute; left: 6px; top: 20px; width: 22px; height: 22px; border-radius: 3px; background: var(--brand); }
.wf-character .chl, .wf-character .chr { position: absolute; top: 41px; width: 4px; height: 15px; background: var(--ink); border-radius: 2px; transform-origin: 50% 0; }
.wf-character .chl { left: 10px; animation: wfChL .55s steps(2, jump-none) infinite alternate; }
.wf-character .chr { left: 20px; animation: wfChL .55s steps(2, jump-none) infinite alternate-reverse; }
@keyframes wfChL { from { transform: rotate(26deg); } to { transform: rotate(-26deg); } }

/* 22 spotlight — 빛이 닿는 곳만 드러남 */
.wf-spotlight { background: var(--ink); }
.wf-spotlight .spd .wl { background: rgba(255, 255, 255, .14); }
.wf-spotlight .spd .spb, .wf-spotlight .spl .spb { border: 1px solid rgba(255, 255, 255, .16); border-radius: 1px; }
.wf-spotlight .spl { position: absolute; inset: 0;
  -webkit-mask: radial-gradient(circle closest-side, #000 45%, transparent 74%) no-repeat 8% 70% / 190px 190px;
  mask: radial-gradient(circle closest-side, #000 45%, transparent 74%) no-repeat 8% 70% / 190px 190px;
  animation: wfSpm 6s ease-in-out infinite; }
.wf-spotlight .spl .wl { background: #fff; }
.wf-spotlight .spl .spb { border-color: rgba(255, 255, 255, .9); }
@keyframes wfSpm {
  0% { -webkit-mask-position: 8% 70%; mask-position: 8% 70%; }
  32% { -webkit-mask-position: 62% 12%; mask-position: 62% 12%; }
  62% { -webkit-mask-position: 90% 66%; mask-position: 90% 66%; }
  100% { -webkit-mask-position: 8% 70%; mask-position: 8% 70%; }
}
.wf-spotlight .spg { position: absolute; width: 130px; height: 130px; margin: -65px 0 0 -65px; border-radius: 50%; background: radial-gradient(circle, rgba(255, 255, 255, .25), transparent 70%); animation: wfSpg 6s ease-in-out infinite; }
@keyframes wfSpg { 0% { left: 10%; top: 70%; } 32% { left: 60%; top: 16%; } 62% { left: 88%; top: 64%; } 100% { left: 10%; top: 70%; } }

/* 23 explore — 자유 시점 공간 탐험 */
.wf-explore .exs { position: absolute; inset: 0; perspective: 420px; }
.wf-explore .exs i { position: absolute; width: 44px; height: 60px; border: 1.5px solid var(--line-strong); background: var(--surface); border-radius: 2px; opacity: 0; animation: wfEx 5s linear infinite; animation-delay: calc(var(--i) * -1s); }
.wf-explore .exs i:nth-child(1) { left: 14%; top: 22%; }
.wf-explore .exs i:nth-child(2) { left: 72%; top: 16%; }
.wf-explore .exs i:nth-child(3) { left: 18%; top: 60%; }
.wf-explore .exs i:nth-child(4) { left: 78%; top: 58%; }
.wf-explore .exs i:nth-child(5) { left: 45%; top: 12%; }
@keyframes wfEx { 0% { transform: translateZ(-360px); opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { transform: translateZ(230px); opacity: 0; } }
.wf-explore .exr { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border: 1.5px solid var(--brand); border-radius: 50%; }
.wf-explore .exr::before, .wf-explore .exr::after { content: ''; position: absolute; background: var(--brand); }
.wf-explore .exr::before { left: 50%; top: -7px; width: 1.5px; height: 5px; margin-left: -.75px; box-shadow: 0 26px 0 var(--brand); }
.wf-explore .exr::after { top: 50%; left: -7px; height: 1.5px; width: 5px; margin-top: -.75px; box-shadow: 26px 0 0 var(--brand); }
