/* 인터랙션 움직임. 종이를 내려놓고, 들고, 넘기는 느낌만 쓴다.
   요소마다 이미 쓰고 있는 transform(기울기, 위치)을 덮어쓰지 않도록 translate/rotate/scale 속성으로 움직인다.
   튀거나 커지는 효과는 쓰지 않는다. 움직임 줄이기 설정이면 theme.css에서 모두 끈다. */

:root {
  --ease-settle: cubic-bezier(.2, .9, .3, 1.15);  /* 살짝 넘쳤다가 자리 잡음 (종이를 내려놓을 때) */
  --ease-paper: cubic-bezier(.3, .7, .2, 1);
}

/* ---------- 화면에 들어올 때: 종이를 위에서 툭 내려놓는다 ---------- */

@keyframes drop-in {
  from { opacity: 0; translate: 0 -14px; rotate: var(--from-tilt, -1.6deg); }
  to   { opacity: 1; translate: 0 0; rotate: 0deg; }
}

.paper-wrap,
.frame,
.ribbon,
.speaker__plate,
.polaroid,
.estate__plan,
.tag-dark,
.job,
.keywords .brush,
.deco {
  animation: drop-in .5s var(--ease-settle) both;
}

/* 순서대로 하나씩 내려놓기 */
.frame, .estate__plan { animation-delay: .02s; }
.ribbon, .speaker__plate { animation-delay: .14s; --from-tilt: 2deg; }
.tag-dark { animation-delay: .2s; }
.job { animation-delay: .24s; }
.keywords .brush:nth-child(1) { animation-delay: .3s; }
.keywords .brush:nth-child(2) { animation-delay: .36s; }
.keywords .brush:nth-child(3) { animation-delay: .42s; }
.deco { animation-delay: .5s; animation-duration: .7s; }
.paper-wrap { animation-delay: .08s; --from-tilt: 1deg; }
.tabbar { animation: drop-in .45s var(--ease-paper) both; --from-tilt: 0deg; }

.polaroid { animation-duration: .45s; }
.polaroid:nth-of-type(1) { animation-delay: .20s; }
.polaroid:nth-of-type(2) { animation-delay: .26s; }
.polaroid:nth-of-type(3) { animation-delay: .32s; }
.polaroid:nth-of-type(4) { animation-delay: .38s; }
.polaroid:nth-of-type(5) { animation-delay: .44s; }
.polaroid:nth-of-type(6) { animation-delay: .50s; }
.polaroid:nth-of-type(7) { animation-delay: .56s; }
.polaroid:nth-of-type(8) { animation-delay: .62s; }

/* 단서·기록 카드도 차례로 */
.clue, .slot { animation: drop-in .45s var(--ease-settle) both; }
.clue:nth-child(2), .slot:nth-child(2) { animation-delay: .06s; }
.clue:nth-child(3), .slot:nth-child(3) { animation-delay: .12s; }
.clue:nth-child(4), .slot:nth-child(4) { animation-delay: .18s; }
.clue:nth-child(n+5), .slot:nth-child(n+5) { animation-delay: .24s; }

/* ---------- 누를 수 있는 종이: 손끝으로 들어 올린다 ---------- */

.polaroid,
.clue:not(:disabled) {
  transition: transform .25s var(--ease-paper), filter .25s var(--ease-paper);
}

/* 마우스를 올리면 기울기가 반쯤 펴지면서 살짝 들린다 (커지지 않는다) */
@media (hover: hover) {
  .polaroid:hover { transform: translate(-50%, calc(-50% - 4px)) rotate(calc(var(--tilt) * .4)); filter: drop-shadow(0 0 10px rgba(0, 0, 0, .55)); }
  .clue:not(:disabled):hover { transform: translateY(-4px) rotate(calc(var(--tilt) * .4)); filter: drop-shadow(0 0 9px rgba(0, 0, 0, .45)); }
}

/* 누르는 순간: 종이를 바닥에 꾹 */
.polaroid:active { transform: translate(-50%, -50%) rotate(var(--tilt)); filter: drop-shadow(0 0 3px rgba(0, 0, 0, .45)); transition-duration: .08s; }
.clue:not(:disabled):active { transform: rotate(var(--tilt)); filter: drop-shadow(0 0 3px rgba(0, 0, 0, .35)); transition-duration: .08s; }

/* 물감 버튼, 밀랍 봉인: 누르면 눌리고 살짝 돌아간다 */
.brush, .seal { transition: transform .15s var(--ease-paper); }
a.brush:active, button.brush:active, .seal:active { transform: translateY(1px) rotate(-2deg); }

/* ---------- 탭: 고른 종이가 올라오고, 나머지는 내려앉는다 ---------- */

.provider span,
.choice span,
.tabbar a {
  transition: transform .3s var(--ease-settle), padding .3s var(--ease-settle), background-color .2s, color .2s;
}
/* 서류철 색인 탭은 크기(padding)를 바로 바꾸고 들림과 색만 움직인다.
   크기를 장면마다 바꾸면 찢긴 테두리 필터를 매번 다시 그려, 같은 때 그려지는 탭 내용과 겹쳐 버벅였다 (오너 지적) */
.tabs button { transition: transform .3s var(--ease-settle), background-color .2s, color .2s; }

/* 탭 내용이 바뀔 때: 새 종이가 아래에서 밀려 들어온다 */
@keyframes slide-paper {
  from { opacity: 0; translate: 0 10px; }
  to   { opacity: 1; translate: 0 0; }
}

[role='tabpanel']:not([hidden]) { animation: slide-paper .3s var(--ease-paper) both; }

/* ---------- 겹쳐 뜨는 종이: 아래에서 올라와 자리 잡고, 뒤는 어두워진다 ---------- */

@keyframes sheet-up {
  from { opacity: 0; translate: 0 40px; rotate: 1.5deg; }
  to   { opacity: 1; translate: 0 0; rotate: 0deg; }
}

@keyframes dim-in { from { background-color: rgba(10, 12, 10, 0); } }

.sheet:not([hidden]) { animation: dim-in .3s ease both; }
.sheet:not([hidden]) > .paper-wrap { animation: sheet-up .4s var(--ease-settle) both; }

/* 닫힐 때는 열릴 때의 반대로: 종이가 아래로 내려가며 사라지고, 뒤가 다시 밝아진다 (js/ui/sheet.js) */
@keyframes sheet-down {
  from { opacity: 1; translate: 0 0; rotate: 0deg; }
  to   { opacity: 0; translate: 0 40px; rotate: 1.5deg; }
}

@keyframes dim-out { to { background-color: rgba(10, 12, 10, 0); } }

.sheet.is-closing { animation: dim-out .28s ease both; }
.sheet.is-closing > .paper-wrap { animation: sheet-down .28s var(--ease-paper) both; }

/* ---------- 페이지를 떠날 때: 들어올 때의 역순으로 종이를 걷어 간다 (js/ui/leave.js) ---------- */

@keyframes lift-out {
  from { opacity: 1; translate: 0 0; rotate: 0deg; }
  to   { opacity: 0; translate: 0 -14px; rotate: var(--from-tilt, -1.6deg); }
}

.is-leaving {
  animation: lift-out var(--leave-duration, .25s) var(--ease-paper) var(--leave-delay, 0s) both !important;
}

/* ---------- 잉크 번짐: 새로 알게 된 것, 도장 ---------- */

@keyframes ink-bleed {
  0%   { opacity: 0; filter: blur(3px); scale: 1.06; }
  60%  { opacity: 1; filter: blur(.4px); }
  100% { opacity: .85; filter: none; scale: 1; }
}

.stamp, .slot:not(.slot--empty)::after { animation: ink-bleed .6s ease-out .5s both; }

@keyframes ink-write {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* 손글씨 메모는 왼쪽부터 한 글자씩 끊어서 써 내려간다. 글자 수(--chars)는 js/ui/handwrite.js가 적는다 */
.hand { animation: ink-write calc(var(--chars, 12) * 65ms) steps(var(--chars, 12)) .55s both; }

/* ---------- 잉크 선: 종이가 놓인 뒤 그 사이에 스며 나온다. 걷을 때는 제자리에서 흐려진다 ---------- */

@keyframes ink-in { from { opacity: 0; } }
@keyframes ink-out { to { opacity: 0; } }

/* ---------- 대화: 새 줄은 종이 위에 스며 나온다 ---------- */

@keyframes line-in {
  from { opacity: 0; translate: 0 4px; }
  to   { opacity: 1; translate: 0 0; }
}

.log li.is-new { animation: line-in .35s var(--ease-paper) both; }   /* 새로 올라온 줄만. 다시 그릴 때는 움직이지 않는다 */

/* ---------- 기다리는 동안: 문장은 스며 나오고, 눈금은 한 획씩 번진다 (js/ui/waiting.js) ---------- */

.wait__text.is-changing { animation: ink-in .6s ease-out both; }
.wait__tally i { animation: ink-in .4s ease-out both; }

/* ---------- 액자 속 초상이 나타날 때 (후보 셋, 오너 선택 전. profile.html?portrait=mix|develop|bleed|slip) ---------- */

/* 현상: 어둡고 누런 사진이 약품 속에서 서서히 떠오르듯 */
@keyframes portrait-develop {
  0%   { opacity: 0; filter: brightness(.15) sepia(.7) contrast(1.6); }
  35%  { opacity: 1; }
  100% { opacity: 1; filter: none; }
}
/* 잉크 번짐: 흐릿하게 번져 있다가 또렷해진다 */
@keyframes portrait-bleed {
  from { opacity: 0; filter: blur(7px); }
  to   { opacity: 1; filter: none; }
}
/* 끼워 넣기: 사진 한 장을 액자 뒤에서 밀어 넣듯 아래에서 조금 들어와 자리 잡는다 */
@keyframes portrait-slip {
  from { opacity: 0; translate: 0 7%; rotate: -1.5deg; }
  to   { opacity: 1; translate: 0 0; rotate: 0deg; }
}
/* 현상 + 잉크 번짐: 누런 기를 덜고, 어둡고 흐린 상태에서 떠오르며 또렷해진다 */
@keyframes portrait-mix {
  0%   { opacity: 0; filter: brightness(.2) sepia(.15) contrast(1.5) blur(6px); }
  35%  { opacity: 1; }
  100% { opacity: 1; filter: none; }
}
.portrait-in--mix { animation: portrait-mix 1.3s ease-out both; }
.portrait-in--develop { animation: portrait-develop 1.3s ease-out both; }
.portrait-in--bleed { animation: portrait-bleed .9s ease-out both; }
.portrait-in--slip { animation: portrait-slip .7s var(--ease-settle) both; }

/* ---------- 지도 위 사람 있는 표시: 천천히 숨 쉬듯 ---------- */

@keyframes breathe { 50% { opacity: .55; } }
.polaroid.has-people::after { animation: breathe 2.4s ease-in-out 4; }   /* 몇 번만 숨 쉬고 멈춘다 (발열 줄이기, 오너 결정) */

/* ---------- 움직임 줄이기 ---------- */

/* 글이 늘어 종이가 길어질 때: 한 줄씩 뚝뚝 늘지 않고 부드럽게 (js/ui/grow.js) */
.grows { transition: height .6s ease-in-out; }   /* 앞에서 몰아 늘면 뚝 커지는 것처럼 보여, 처음과 끝을 고르게 */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

.reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation: none !important; transition: none !important; }

/* 타자기처럼 찍는 글에서 아직 찍지 않은 뒷부분: 자리는 그대로 두고 가린다 (js/ui/typing.js) */
.untyped { visibility: hidden; }

/* 앱이 뒤로 가거나 창을 내리면 모든 움직임을 멈춘다 (발열 줄이기, js/ui/prefs.js가 html에 .is-away를 붙인다) */
html.is-away *, html.is-away *::before, html.is-away *::after { animation-play-state: paused !important; }
