/* ═══════════════════════════════════════════════════════════════
   ikusa 오프닝 시네마틱
   모든 선택자에 op- 접두어를 붙여 기존 게임 CSS와 격리한다.
   상태 클래스(op-striking / op-cutting / op-split)는 #op-overlay 에만 붙는다.

   0.00s  상단세 — 칼을 치켜들고 멈춘 한 박자
   0.23s  내려침 — 잔심 컷으로 하드컷 + 잔상 + 스냅 줌 + 칼날 섬광
   0.30s  베임   — 붉은 획 + 비말이 획을 따라 순차적으로 터진다
   0.41s  흘러내림 — 핏줄기가 중력을 받는다
   0.54s  갈라짐 — 조각이 1.22배로 부풀며 0.9초에 걸쳐 흩어진다
   0.56s  상승   — 시작 화면이 갈라짐과 겹쳐 1.25초에 걸쳐 떠오른다
   1.50s  종료   — 오버레이 DOM 제거

   움직이는 속성은 transform / opacity / clip-path 뿐이다.
   ═══════════════════════════════════════════════════════════════ */

#op-overlay{
  /* ── 조절 노브 ─────────────────────────────────────────── */
  --op-red:#c0342b;
  --op-red-hot:#ff4b3a;
  --op-paper:#f8f4e8;

  --op-wash:1;          /* 1 = 붉은 와이프(강함) · 0 = 붓 자국만(담백) · 중간값 가능 */
  --op-jodan-shift:2%;  /* 두 컷 사이 인물 위치 차이 보정 */

  /* 베는 선: 화면 비율(%)로 정의한 두 점. 원화의 붉은 획에서 실측한 값 */
  --op-cut-x1:0;   --op-cut-y1:-5.2;
  --op-cut-x2:100; --op-cut-y2:95;
  --op-nx:0.454;   --op-ny:-0.891;  /* 선의 법선. opening.js 가 화면비에 맞춰 갱신 */

  /* 이미지 경로는 opening.js 가 주입한다 (--op-f1 / --op-f2 / --op-mask / --op-soft) */

  position:fixed; inset:0; z-index:9000;
  overflow:hidden; background:var(--op-paper); cursor:pointer;
  contain:strict;
}
#op-overlay[hidden]{ display:none }

/* ── 두 조각 ─────────────────────────────────────────────────
   같은 그림을 서로 다른 clip-path 로 잘라 겹쳐 놓고,
   벤 선의 법선 방향으로 밀어내면서 부풀린다. */
.op-piece{
  position:absolute; inset:0; will-change:transform,opacity;
  transition:transform 900ms cubic-bezier(.2,.62,.28,1),
             opacity   820ms cubic-bezier(.36,.06,.5,1);
}
.op-piece--a{ clip-path:polygon(
  calc(var(--op-cut-x1)*1%) calc(var(--op-cut-y1)*1%),
  calc(var(--op-cut-x2)*1%) calc(var(--op-cut-y2)*1%), 100% 120%, 100% -20%) }
.op-piece--b{ clip-path:polygon(
  calc(var(--op-cut-x1)*1%) calc(var(--op-cut-y1)*1%),
  calc(var(--op-cut-x2)*1%) calc(var(--op-cut-y2)*1%), -20% 120%) }

.op-split .op-piece--a{
  transform:translate(calc(var(--op-nx)*44%),calc(var(--op-ny)*44%)) rotate(1.6deg) scale(1.22);
  opacity:0;
}
.op-split .op-piece--b{
  transform:translate(calc(var(--op-nx)*-44%),calc(var(--op-ny)*-44%)) rotate(-1.6deg) scale(1.22);
  opacity:0;
}

/* ── 자세 프레임을 담는 무대. 흔들림·줌은 전부 여기 ───────── */
.op-plate{
  position:absolute; inset:0;
  transform:scale(1.06);
  filter:brightness(.84) saturate(.9);
  transition:filter 160ms linear;
}
.op-striking .op-plate{ animation:op-snap 260ms cubic-bezier(.18,.9,.22,1) forwards; filter:none }
@keyframes op-snap{
  0%  { transform:scale(1.06) translate(0,0) }
  18% { transform:scale(1.008) translate(-1.3%,1.0%) }
  46% { transform:scale(1.03) translate(.6%,-.45%) }
  100%{ transform:scale(1.02) translate(0,0) }
}

/* ── 자세 2장. 크로스페이드가 아니라 하드컷 ──────────────── */
.op-frame{
  position:absolute; inset:0;
  background-size:cover; background-position:center;
  opacity:0;
}
.op-frame--jodan{
  background-image:var(--op-f1); opacity:1;
  transform:translateX(var(--op-jodan-shift));
}
.op-frame--zanshin{ background-image:var(--op-f2) }
.op-striking .op-frame--jodan  { opacity:0 }
.op-striking .op-frame--zanshin{ opacity:1 }

/* ── 잔상 — 칼이 지나간 방향 뒤로 두 겹 흐른다 ───────────── */
.op-ghost{
  position:absolute; inset:0;
  background-image:var(--op-f2); background-size:cover; background-position:center;
  opacity:0; mix-blend-mode:multiply;
}
.op-striking .op-ghost--1{ animation:op-ghost1 200ms ease-out forwards }
.op-striking .op-ghost--2{ animation:op-ghost2 240ms ease-out forwards }
@keyframes op-ghost1{ 0%{opacity:.42; transform:translate(-2.4%,-2.4%)} 100%{opacity:0; transform:none} }
@keyframes op-ghost2{ 0%{opacity:.24; transform:translate(-4.8%,-4.8%)} 100%{opacity:0; transform:none} }

/* ── 칼날 섬광 — 붉은 획과 같은 마스크를 흰색으로, 한 박자 먼저 ── */
.op-arc{
  position:absolute; inset:0; opacity:0;
  background:linear-gradient(105deg,#fff,#eaf2ff 40%,#fff);
  filter:blur(7px);
  -webkit-mask-image:var(--op-mask); mask-image:var(--op-mask);
  -webkit-mask-size:100% 100%;      mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;    mask-repeat:no-repeat;
  clip-path:polygon(0 0,-10% 0,-38% 100%,0 100%);
}
.op-striking .op-arc{ animation:op-sweep 120ms linear forwards, op-arcfade 300ms ease-out forwards }
@keyframes op-arcfade{ 0%{opacity:.95} 40%{opacity:.7} 100%{opacity:0} }

/* ── 종이에 번지는 배어듦 ───────────────────────────────────
   주의: filter + mask + mix-blend-mode 를 한 요소에 겹치면
   크로미움이 마스크를 무시한다. 흐림은 마스크 파일에 구워져 있다. */
.op-bleed{
  position:absolute; inset:0; opacity:0;
  background:var(--op-red);
  -webkit-mask-image:var(--op-soft); mask-image:var(--op-soft);
  -webkit-mask-size:100% 100%;      mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;    mask-repeat:no-repeat;
  clip-path:polygon(0 0,-10% 0,-38% 100%,0 100%);
  mix-blend-mode:multiply;
}
.op-cutting .op-bleed{ animation:op-sweep 200ms cubic-bezier(.16,.84,.3,1) forwards,
                                 op-soak 620ms ease-out 60ms forwards }
@keyframes op-soak{ 0%{opacity:0; transform:scale(1)} 100%{opacity:.5; transform:scale(1.012)} }

/* ── 붉은 와이프 — --op-wash 로 세기 조절 ────────────────── */
.op-wash{
  position:absolute; inset:0; opacity:var(--op-wash);
  background:linear-gradient(105deg,#a2281f 0%,var(--op-red) 34%,#e0402f 70%,#c33429 100%);
  clip-path:polygon(0 0,-10% 0,-38% 100%,0 100%);
}
.op-cutting .op-wash{ animation:op-sweep 165ms cubic-bezier(.16,.84,.3,1) forwards }

/* ── 붉은 획 — 섬광을 뒤따라 번진다 ─────────────────────── */
.op-slash{
  position:absolute; inset:0;
  background:linear-gradient(105deg,#a82a22 0%,var(--op-red) 38%,var(--op-red-hot) 72%,#d43a2c 100%);
  -webkit-mask-image:var(--op-mask); mask-image:var(--op-mask);
  -webkit-mask-size:100% 100%;      mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;    mask-repeat:no-repeat;
  clip-path:polygon(0 0,-10% 0,-38% 100%,0 100%);
}
.op-cutting .op-slash{ animation:op-sweep 165ms cubic-bezier(.16,.84,.3,1) forwards }

/* 획이 그어지는 방향 = 칼이 나아간 방향 */
@keyframes op-sweep{ to{ clip-path:polygon(0 0,138% 0,110% 100%,0 100%) } }

/* ── 비말 — 칼날이 지나가는 순서대로 터진다 ──────────────── */
.op-spray{ position:absolute; inset:0; pointer-events:none }
.op-drop{
  position:absolute; width:var(--s); height:var(--s);
  margin-left:calc(var(--s)/-2); margin-top:calc(var(--s)/-2);
  background:var(--op-red); border-radius:52% 44% 56% 47%;
  opacity:0; will-change:transform,opacity;
}
.op-drop--fine { background:var(--op-red-hot) }
.op-drop--flick{ height:calc(var(--s)*.34); border-radius:50%/50% }
.op-cutting .op-drop{
  animation:op-burst 420ms cubic-bezier(.09,.82,.2,1) forwards;
  animation-delay:calc(var(--t) * 165ms);   /* 획이 그 지점을 지나는 시각 */
}
@keyframes op-burst{
  0%  { opacity:0;   transform:translate(0,0) rotate(var(--rot)) scale(.15) }
  10% { opacity:1;   transform:translate(calc(var(--dx)*.3),calc(var(--dy)*.3)) rotate(var(--rot)) scale(1.15) }
  100%{ opacity:.92; transform:translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(1) }
}

/* ── 흘러내림 ───────────────────────────────────────────── */
.op-drip{
  position:absolute; width:var(--w); height:var(--h);
  background:linear-gradient(180deg,var(--op-red) 0%,var(--op-red) 62%,var(--op-red-hot) 100%);
  border-radius:0 0 50% 50% / 0 0 70% 70%;
  transform:scaleY(0); transform-origin:50% 0;
}
.op-cutting .op-drip{
  animation:op-run 460ms cubic-bezier(.45,0,.85,.35) forwards;
  animation-delay:calc(var(--t) * 165ms + 110ms);
}
@keyframes op-run{ to{ transform:scaleY(1) } }

/* ── 갈라진 틈의 발광 ───────────────────────────────────── */
.op-seam{
  position:absolute; left:50%; top:50%; width:190%; height:2px;
  transform-origin:50% 50%; opacity:0; filter:blur(1px); pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--op-red) 12%,var(--op-red-hot) 50%,var(--op-red) 88%,transparent);
  transition:opacity 160ms linear,
             height 900ms cubic-bezier(.2,.62,.28,1),
             filter 900ms linear;
}
.op-split .op-seam{ height:9vh; filter:blur(26px); animation:op-seamout 820ms ease-out forwards }
@keyframes op-seamout{ 0%{opacity:0} 11%{opacity:1} 45%{opacity:.55} 100%{opacity:0} }

.op-flash{ position:absolute; inset:0; background:#fff; opacity:0; pointer-events:none }
.op-cutting .op-flash{ animation:op-flash 200ms ease-out }
@keyframes op-flash{ 0%{opacity:0} 16%{opacity:.7} 100%{opacity:0} }

.op-skip{
  position:absolute; right:1rem; bottom:1rem; z-index:2;
  font-size:.7rem; letter-spacing:.18em; color:rgba(18,20,26,.42);
  opacity:0; animation:op-fadein 300ms ease-out 600ms forwards;
}
@keyframes op-fadein{ to{ opacity:1 } }

/* ═══ 시작 화면(허브)이 떠오른다 ═════════════════════════════
   HUB_SELECTOR 로 지정한 요소에 op-rise 가 붙는다.
   기존 허브에 이미 transform 이 걸려 있다면 이 규칙과 충돌하니
   그 경우 허브를 감싸는 래퍼를 하나 만들어 거기에 적용할 것. */
.op-hub-enter{
  opacity:0; transform:translateY(30px);
  transition:opacity 1000ms ease-out,
             transform 1250ms cubic-bezier(.14,.8,.24,1);
  will-change:opacity, transform;
}
.op-hub-enter.op-rise{ opacity:1; transform:none }
.op-hub-enter.op-instant{ transition-duration:0ms }

@media (prefers-reduced-motion:reduce){
  #op-overlay{ display:none !important }
  .op-hub-enter{ opacity:1; transform:none; transition:none }
}
