/* uppy-motion2.css — 어피 모션 v2 (codex65, 2026-10-26)
   aboutfishing-all §10 토큰: press 120 · feedback 180 · exit 180 · enter 280 · sheet 320 · signature 400 · stagger 32ms
   v1(uppy-motion.css·uppy-motion.js·uppy-fx.js) 위에 얹는다. 기능·레이아웃·색·글꼴은 바꾸지 않는다.
   transform(개별 translate/scale 포함)·opacity만 움직인다. 동작 줄이기면 전부 끈다. */
:root{--m2-enter:280ms;--m2-sig:400ms;--m2-fb:180ms;--m2-press:120ms;--m2-ease:cubic-bezier(.16,1,.3,1);--m2-exit:cubic-bezier(.4,0,1,1);--m2-spring:cubic-bezier(.34,1.3,.64,1)}

/* ① 첫 화면 오프닝: 머리 → 내 낚시 줄 → 입력창 순서로 놓인다(처음 한 번, CSS만 — 스크립트가 늦어도 깜빡임 없음) */
.app .hd>*{animation:m2Drop var(--m2-enter) var(--m2-ease) backwards}
.app .hd>:nth-child(1){animation:m2Pop var(--m2-sig) var(--m2-spring) backwards}
.app .hd>:nth-child(2){animation-delay:60ms}.app .hd>:nth-child(3){animation-delay:110ms}.app .hd>:nth-child(4){animation-delay:140ms}
.app .hd>:nth-child(5){animation-delay:170ms}.app .hd>:nth-child(6){animation-delay:200ms}
.app .pfbar>*{animation:m2Drop var(--m2-enter) var(--m2-ease) backwards}
.app .pfbar>:nth-child(2){animation-delay:180ms}.app .pfbar>:nth-child(3){animation-delay:212ms}.app .pfbar>:nth-child(4){animation-delay:244ms}
.app .inp{animation:m2Rise var(--m2-sig) var(--m2-ease) 120ms backwards}
@keyframes m2Drop{from{opacity:0;transform:translate3d(0,-8px,0)}to{opacity:1;transform:none}}
@keyframes m2Pop{from{opacity:0;transform:scale(.6)}to{opacity:1;transform:none}}
@keyframes m2Rise{from{opacity:0;transform:translate3d(0,16px,0)}to{opacity:1;transform:none}}
/* 아바타: 첫 등장 때 한 번 퍼지는 고리 */
.app .hd .av{position:relative;overflow:visible}
.app .hd .av img{border-radius:50%}
.app .hd .av::after{content:"";position:absolute;inset:-2px;border-radius:50%;border:2px solid #6433DF;opacity:0;transform:scale(1);pointer-events:none}
.app.m2-on .hd .av::after{animation:m2Ring 900ms var(--m2-ease) 260ms 1 both}
@keyframes m2Ring{0%{opacity:.55;transform:scale(1)}100%{opacity:0;transform:scale(1.6)}}
/* 새 답이 오면 아바타 고리가 한 번 더(어피가 말했다는 표시) */
.app .hd .av.m2-say::after{animation:m2Ring 700ms var(--m2-ease) 1 both}

/* ② 머리 줄: 대화를 내리면 그림자가 생기고 아바타가 살짝 작아진다(내용 위에 떠 있음을 알림) */
.app .hd{position:relative;z-index:3}
.app .hd::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:12px;transform:translateY(100%);background:linear-gradient(rgba(26,26,26,.07),rgba(26,26,26,0));opacity:0;transition:opacity var(--m2-fb) ease-out;pointer-events:none}
.app.m2-scrolled .hd::after{opacity:1}
.app .hd .av{transition:scale var(--m2-enter) var(--m2-ease)}
.app.m2-scrolled .hd .av{scale:.86}

/* ③ 입력창: 글자를 넣으면 보내기 버튼이 켜진다 · 포커스 테두리가 퍼진다 */
.app .inp-row{position:relative}
.app .inp-row::before{content:"";position:absolute;inset:-2px;border-radius:10000px;border:2px solid #6433DF;opacity:0;transform:scale(.985);transition:opacity var(--m2-fb) ease-out,transform var(--m2-enter) var(--m2-ease);pointer-events:none}
.app .inp-row:focus-within::before{opacity:.35;transform:none}
.app .inp-row .send{transition:scale var(--m2-enter) var(--m2-spring),opacity var(--m2-fb) ease-out}
.app.m2-empty .inp-row .send{scale:.86;opacity:.55}
.app .inp-row .send:active{scale:.9}

/* ④ AI 진행 단계: 단계 사이를 잇는 선이 위에서 아래로 그려진다 */
.ag-steps li{position:relative}
.ag-steps li+li::after{content:"";position:absolute;left:6.5px;top:-7px;width:1.5px;height:8px;background:#6433DF;border-radius:2px;transform-origin:50% 0;transform:scaleY(0);opacity:.5;animation:m2Line var(--m2-enter) var(--m2-ease) 80ms forwards}
@keyframes m2Line{to{transform:scaleY(1)}}
.ag-steps li:not(.ag-done) i{position:relative}
.ag-steps li:not(.ag-done) i::after{content:"";position:absolute;inset:0;border-radius:50%;border:1.5px solid rgba(100,51,223,.25);border-top-color:#6433DF;animation:m2Spin .9s linear infinite}
@keyframes m2Spin{to{transform:rotate(360deg)}}

/* ⑤ 배 카드: 사진이 살짝 당겨졌다 제자리로(한 번) · 정가에 줄이 그어지고 쿠폰가가 올라온다 */
#chat > .card.bc-card .card-img img{transform-origin:50% 60%}
#chat > .card.bc-card.m2-in .card-img img{animation:m2Zoom 900ms var(--m2-ease) both}
@keyframes m2Zoom{from{transform:scale(1.08)}to{transform:none}}
.app.m2-on .price.cp-on .cp-was .s,.app.m2-on .price.cp-est .cp-was .s{position:relative;text-decoration:none}
.app.m2-on .price.cp-on .cp-was .s::after,.app.m2-on .price.cp-est .cp-was .s::after{content:"";position:absolute;left:-1px;right:-1px;top:52%;height:1.5px;background:currentColor;transform-origin:0 50%;transform:scaleX(1)}
.app.m2-on .price.m2-wait .cp-was .s::after{transform:scaleX(0)}
.app.m2-on .price.m2-wait .pct,.app.m2-on .price.m2-wait .f{opacity:0;translate:0 6px}
.app.m2-on .price.m2-go .cp-was .s::after{transition:transform var(--m2-sig) var(--m2-ease)}
.app.m2-on .price.m2-go .pct{transition:opacity var(--m2-fb) ease-out 260ms,translate var(--m2-enter) var(--m2-spring) 260ms}
.app.m2-on .price.m2-go .f{transition:opacity var(--m2-fb) ease-out 340ms,translate var(--m2-enter) var(--m2-spring) 340ms}

/* ⑥ 가로 목록: 끝 쪽 카드는 작게, 가운데로 올수록 제 크기(스크롤에 붙어서) + 위치 점 */
.m2-dots{display:flex;justify-content:center;gap:5px;margin:8px 0 2px;height:6px}
.m2-dots i{display:block;width:6px;height:6px;border-radius:3px;background:#E7E7E7;transition:background-color var(--m2-fb) ease-out,scale var(--m2-enter) var(--m2-ease);transform-origin:50% 50%}
.m2-dots i.on{background:#6433DF;scale:1.35}

/* ⑦ 토스트: 아래에서 튀어 오르듯(살짝 넘쳤다 제자리) */
.ptoast.show,.ptoast.on{transition-timing-function:var(--m2-spring)!important}

@media (prefers-reduced-motion: reduce){
  .app .hd>*,.app .pfbar>*,.app .inp,.app.m2-on .hd .av::after,.app .hd .av.m2-say::after,.ag-steps li+li::after,.ag-steps li:not(.ag-done) i::after,#chat > .card.bc-card.m2-in .card-img img{animation:none!important}
  .ag-steps li+li::after{transform:none}
  .app .hd .av,.app .inp-row::before,.app .inp-row .send,.m2-dots i{transition:none!important}
  .app.m2-scrolled .hd .av{scale:1}
  .app.m2-on .price.m2-wait .cp-was .s::after{transform:none}
  .app.m2-on .price.m2-wait .pct,.app.m2-on .price.m2-wait .f{opacity:1;translate:none}
}

/* ═════ 모션 v3 (codex67) — 스프링·깊이·빛 ═════ */
/* ⑧ 누름은 스프링이 맡는다(v1의 고정 축소와 겹치지 않게) */
.app.m2-on .chip:active,.app.m2-on .ctas button:active,.app.m2-on .go:active,.app.m2-on .ghost:active,.app.m2-on .cx:active{transform:none!important}
/* ⑨ 시트·확인창·페이지가 열리면 뒤 화면이 한 걸음 물러난다(무엇이 앞에 있는지 깊이로 알림) */
.app.m2-on .chat,.app.m2-on .hd,.app.m2-on .inp,.app.m2-on .pfbar{transition:transform var(--m2-sheet,320ms) var(--m2-ease),opacity var(--m2-sheet,320ms) var(--m2-ease);transform-origin:50% 0}
.app.m2-on.m2-depth .chat,.app.m2-on.m2-depth .pfbar{transform:scale(.965) translate3d(0,6px,0);opacity:.72}
.app.m2-on.m2-depth .hd{transform:scale(.98);opacity:.6}
.app.m2-on.m2-depth .inp{transform:translate3d(0,8px,0);opacity:.5}
.app.m2-on.m2-page .chat,.app.m2-on.m2-page .hd,.app.m2-on.m2-page .pfbar,.app.m2-on.m2-page .inp{transform:translate3d(-18%,0,0);opacity:.5}
/* ⑩ 예약하기 버튼: 카드가 놓인 뒤 빛이 한 번 지나간다(여기가 다음 단계) */
.app.m2-on #chat .bc-card .ctas .go{position:relative;isolation:isolate}
.app.m2-on #chat .bc-card .ctas .go::after{content:"";position:absolute;top:0;bottom:0;left:0;width:60%;background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,.38) 50%,transparent 100%);transform:translateX(-140%) skewX(-18deg);pointer-events:none}
.app.m2-on #chat .bc-card.m2-in .ctas .go::after{animation:m2Sweep 900ms cubic-bezier(.45,0,.2,1) 650ms 1 both}
@keyframes m2Sweep{to{transform:translateX(260%) skewX(-18deg)}}
/* ⑪ 사진: 받아지는 순간 흐릿한 바탕에서 제 모습으로 */
.app.m2-on img.m2-img{opacity:0;transform:scale(1.04)}
.app.m2-on img.m2-img.m2-ld{opacity:1;transform:none;transition:opacity 420ms ease-out,transform 700ms var(--m2-ease)}
/* ⑫ 기다리는 동안 머리 아바타가 숨 쉰다(찾는 중일 때만) */
.app.m2-on.m2-busy .hd .av img{animation:m2Breath 1.6s ease-in-out infinite}
@keyframes m2Breath{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
/* ⑬ 머리 상태 문구가 바뀌면 아래에서 올라와 바뀐다 */
.m2-sub{animation:m2Sub var(--m2-enter) var(--m2-ease) both}
@keyframes m2Sub{from{opacity:0;transform:translate3d(0,5px,0)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){
  .app .chat,.app .hd,.app .inp,.app .pfbar{transition:none!important;transform:none!important;opacity:1!important}
  .app #chat .bc-card .ctas .go::after{animation:none!important;display:none}
  .app img.m2-img{opacity:1!important;transform:none!important;transition:none!important}
  .app.m2-busy .hd .av img,.m2-sub{animation:none!important}
}
