/* ------------------------------------------------------------------
   fx: 버스, 페이지 전환, 스크롤 등장, 테마 전환
   ------------------------------------------------------------------ */

/* 버스 ------------------------------------------------------------- */
.bus { display: block; width: 100%; height: auto; overflow: visible; }
.bus__wheel { animation: bus-wheel .55s linear infinite; }
.bus__body { animation: bus-bob .42s ease-in-out infinite alternate; transform-origin: 120px 84px; }
@keyframes bus-wheel { to { transform: rotate(360deg); } }
@keyframes bus-bob { from { transform: translateY(0); } to { transform: translateY(-1.5px); } }

/* 홈: 버스가 지나다니는 도로 띠 */
.road { position: relative; height: 72px; overflow: hidden; border-top: 2px solid var(--line-strong); background: var(--bg); }
.road::before { content: ""; position: absolute; left: 0; right: 0; bottom: 14px; border-top: 3px dashed var(--line-2); }
.road::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 12px; background: repeating-linear-gradient(90deg, var(--line-strong) 0 24px, transparent 24px 48px); opacity: .15; }
.road__bus { position: absolute; bottom: 10px; left: 0; width: 190px; animation: road-drive 18s linear infinite; animation-delay: -5s; will-change: transform; }
.road__bus--2 { width: 150px; animation-duration: 27s; animation-delay: -19s; opacity: .55; bottom: 22px; filter: grayscale(1); }
.road__sign { position: absolute; left: var(--gutter); top: 10px; display: flex; gap: 8px; align-items: center; }
.road__stop { position: absolute; right: calc(var(--gutter) + 24px); bottom: 14px; width: 3px; height: 40px; background: var(--line-strong); }
.road__stop::before { content: "BUS"; position: absolute; left: -14px; top: -14px; width: 32px; height: 16px; background: var(--accent); color: var(--accent-fg); font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; text-align: center; line-height: 16px; }
@keyframes road-drive { from { transform: translateX(-220px); } to { transform: translateX(100vw); } }

/* 페이지 전환 오버레이 ---------------------------------------------- */
.fx { position: fixed; inset: 0; z-index: 70; pointer-events: none; display: none; overflow: hidden; }
.fx[data-type] { display: block; }
.fx__panel, .fx__bus, .fx__bars, .fx__glitch { display: none; }

/* bus: 버스가 검은 커튼을 끌고 지나간다 */
.fx[data-type="bus"] .fx__panel, .fx[data-type="bus"] .fx__bus { display: block; }
.fx__panel { position: absolute; inset: 0; background: var(--ink); transform: translateX(-100%); }
.fx__bus { position: absolute; bottom: 12vh; left: 0; width: min(280px, 55vw); transform: translateX(-100%); filter: drop-shadow(4px 4px 0 var(--accent)); }
.fx[data-type="bus"][data-phase="cover"] .fx__panel { animation: fx-cover .44s var(--ease) forwards; }
.fx[data-type="bus"][data-phase="cover"] .fx__bus { animation: fx-bus-in .44s linear forwards; }
.fx[data-type="bus"][data-phase="reveal"] .fx__panel { animation: fx-reveal .44s var(--ease) forwards; }
.fx[data-type="bus"][data-phase="reveal"] .fx__bus { transform: translateX(100vw); }
@keyframes fx-cover { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes fx-reveal { from { transform: translateX(0); } to { transform: translateX(100%); } }
@keyframes fx-bus-in { from { transform: translateX(-100%); } to { transform: translateX(100vw); } }

/* bars: 가로 막대가 번갈아 들어왔다 나간다 */
.fx[data-type="bars"] .fx__bars { display: grid; }
.fx__bars { position: absolute; inset: 0; grid-template-rows: repeat(6, 1fr); }
.fx__bars i { display: block; background: var(--ink); transform: translateX(-101%); }
.fx__bars i:nth-child(even) { transform: translateX(101%); background: var(--ink-2); }
.fx__bars i:nth-child(3) { background: var(--accent); }
.fx[data-type="bars"][data-phase="cover"] .fx__bars i { animation: fx-bar-in .36s var(--ease) forwards; }
.fx[data-type="bars"][data-phase="reveal"] .fx__bars i { animation: fx-bar-out-r .36s var(--ease) forwards; }
.fx[data-type="bars"][data-phase="reveal"] .fx__bars i:nth-child(even) { animation-name: fx-bar-out-l; }
.fx__bars i:nth-child(2) { animation-delay: .03s !important; } .fx__bars i:nth-child(3) { animation-delay: .06s !important; }
.fx__bars i:nth-child(4) { animation-delay: .09s !important; } .fx__bars i:nth-child(5) { animation-delay: .12s !important; } .fx__bars i:nth-child(6) { animation-delay: .15s !important; }
@keyframes fx-bar-in { to { transform: translateX(0); } }
@keyframes fx-bar-out-r { from { transform: translateX(0); } to { transform: translateX(101%); } }
@keyframes fx-bar-out-l { from { transform: translateX(0); } to { transform: translateX(-101%); } }

/* glitch: 색 조각이 번쩍인다 */
.fx[data-type="glitch"] .fx__glitch { display: block; }
.fx__glitch { position: absolute; inset: 0; }
.fx__glitch i { position: absolute; left: 0; right: 0; display: block; mix-blend-mode: multiply; opacity: 0; }
:root[data-theme="dark"] .fx__glitch i { mix-blend-mode: screen; }
.fx__glitch i:nth-child(1) { top: 12%; height: 10%; background: var(--accent); }
.fx__glitch i:nth-child(2) { top: 38%; height: 6%; background: var(--cyan); }
.fx__glitch i:nth-child(3) { top: 58%; height: 14%; background: var(--ink); }
.fx__glitch i:nth-child(4) { top: 80%; height: 5%; background: var(--lime); }
.fx[data-type="glitch"] .fx__glitch i { animation: fx-glitch .34s steps(3, end) both; }
.fx[data-type="glitch"] .fx__glitch i:nth-child(2) { animation-delay: .04s; } .fx[data-type="glitch"] .fx__glitch i:nth-child(3) { animation-delay: .08s; } .fx[data-type="glitch"] .fx__glitch i:nth-child(4) { animation-delay: .02s; }
@keyframes fx-glitch { 0% { opacity: 0; transform: translateX(-6%); } 20% { opacity: .9; transform: translateX(3%); } 60% { opacity: .7; transform: translateX(-2%) scaleY(1.4); } 100% { opacity: 0; transform: translateX(5%); } }

/* slide / fade: 본문 자체가 움직인다 */
.app.fx-out-slide { animation: fx-slide-out .2s var(--ease) forwards; }
.app.fx-in-slide { animation: fx-slide-in .32s var(--ease) both; }
.app.fx-out-fade { animation: fx-fade-out .12s linear forwards; }
.app.fx-in-fade { animation: fx-fade-in .22s linear both; }
@keyframes fx-slide-out { to { opacity: 0; transform: translateX(-28px); } }
@keyframes fx-slide-in { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes fx-fade-out { to { opacity: 0; } }
@keyframes fx-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* 새 페이지 섹션이 차례로 올라온다 */
.app.is-enter > * { animation: fx-enter .5s var(--ease) both; }
.app.is-enter > *:nth-child(2) { animation-delay: .06s; } .app.is-enter > *:nth-child(3) { animation-delay: .12s; }
.app.is-enter > *:nth-child(4) { animation-delay: .18s; } .app.is-enter > *:nth-child(n+5) { animation-delay: .22s; }
@keyframes fx-enter { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* 스크롤 등장 */
.rv { opacity: 0; transform: translateY(14px); transition: opacity .55s var(--ease) var(--d, 0ms), transform .55s var(--ease) var(--d, 0ms); }
.rv.is-in { opacity: 1; transform: none; }

/* 테마 전환 */
html.theme-anim, html.theme-anim *, html.theme-anim *::before, html.theme-anim *::after { transition: background-color .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease), fill .4s var(--ease) !important; }

@media (prefers-reduced-motion: reduce) {
  .bus__wheel, .bus__body, .road__bus { animation: none !important; }
  .road__bus { transform: translateX(var(--gutter)); }
  .app.is-enter > * { animation: none; }
  .rv { opacity: 1; transform: none; transition: none; }
}
