/* Fincode motion layer: intro, entrances, scroll reveals and micro-interactions.
   Linked only while build.pl has $motion on (set it to 0 and rebuild to remove every effect).
   Every rule is scoped to a class that the inline guard in <head> or motion.js adds (html.fc-m and friends),
   so without JavaScript, with "reduce motion" turned on, or after a visitor pauses animations (html.fc-off),
   the site renders exactly as it does without this file. */

/* ---------------------------------------------------------------- Intro (home pages, once per session) */
/* Painted before the first frame by the inline guard; motion.js replaces it with the real intro.
   If the script never runs, the veil lets go of the page by itself after 3 seconds.
   It catches taps meanwhile, so nothing invisible underneath can be clicked. */
html.fc-intro-pending::before {
  content: ""; position: fixed; inset: 0; z-index: 2147483000; pointer-events: auto;
  background: #F4F6FB linear-gradient(170deg, #FAFBFE 0%, #F4F6FB 55%, #ECF0F8 100%);
  animation: fc-release 0s 3s forwards;
}
@keyframes fc-release { to { visibility: hidden; } }

html.fc-intro-lock { overflow: hidden; }

.fc-intro {
  position: fixed; inset: 0; z-index: 2147483001; overflow: hidden;
  color: var(--ink); font-family: var(--font); -webkit-user-select: none; user-select: none;
  cursor: default; touch-action: none;
}
.fc-intro * { box-sizing: border-box; }

.fc-intro__veil { position: absolute; inset: 0; background: #F4F6FB linear-gradient(170deg, #FAFBFE 0%, #F4F6FB 55%, #ECF0F8 100%); will-change: opacity; }
.fc-intro__sky {
  position: absolute; inset: -10%;
  background:
    radial-gradient(ellipse 55% 50% at 74% 22%, rgba(63, 88, 212, .16), transparent 70%),
    radial-gradient(ellipse 45% 40% at 18% 80%, rgba(141, 156, 255, .14), transparent 70%),
    radial-gradient(ellipse 40% 35% at 50% 46%, rgba(255, 255, 255, .9), transparent 70%);
  will-change: transform, opacity;
}
.fc-intro__grid {
  position: absolute; inset: 0;
  background-image: linear-gradient(rgba(28, 34, 40, .05) 1px, transparent 1px), linear-gradient(90deg, rgba(28, 34, 40, .05) 1px, transparent 1px);
  background-size: 56px 56px; background-position: center; will-change: opacity;
  -webkit-mask-image: radial-gradient(ellipse 58% 52% at 50% 46%, #000 10%, transparent 78%);
  mask-image: radial-gradient(ellipse 58% 52% at 50% 46%, #000 10%, transparent 78%);
}
.fc-intro__chart { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; will-change: opacity; }
.fc-intro__chart .fc-line { fill: none; stroke: url(#fc-line-grad); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fc-intro__chart .fc-area { fill: url(#fc-area-grad); }
.fc-intro__chart .fc-head { fill: var(--brand); }
.fc-intro__chart .fc-halo { fill: var(--brand); opacity: .18; }
.fc-intro__frost { display: none; position: absolute; left: 0; right: 0; top: 0; bottom: 0; opacity: 0; pointer-events: none; will-change: opacity; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
/* Android phones: no live backdrop blur (same choice as the header); the veil fade alone reveals the page. */
@media (max-width: 1000px) { @supports not (-webkit-touch-callout: none) { .fc-intro__frost { display: none !important; } } }
.fc-intro__mist {
  position: absolute; left: -30%; width: 160%; height: 62%; bottom: -20%;
  background: radial-gradient(ellipse at 50% 55%, rgba(255, 255, 255, .97) 0%, rgba(255, 255, 255, .78) 28%, rgba(255, 255, 255, .3) 50%, rgba(255, 255, 255, 0) 70%);
  opacity: 0; will-change: transform, opacity;
}

.fc-intro__sprite { position: absolute; top: 0; left: 0; transform-origin: 0 0; perspective: 1000px; will-change: transform, opacity; }
.fc-intro__mark, .fc-intro__shine { position: absolute; inset: 0; width: 100%; height: 100%; transform-origin: 50% 65%; will-change: transform, opacity, filter; }
.fc-intro__mark { filter: drop-shadow(0 10px 14px rgba(27, 42, 90, .14)); }
.fc-intro__shine {
  background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .05) 42%, rgba(255, 255, 255, .9) 49%, rgba(255, 255, 255, .14) 54%, transparent 64%);
  background-size: 320% 100%; background-position: 150% 0; mix-blend-mode: screen; opacity: 0;
  -webkit-mask: url("/assets/motion/glass-c.webp") center / 100% 100% no-repeat;
  mask: url("/assets/motion/glass-c.webp") center / 100% 100% no-repeat;
}
.fc-intro__shadow { position: absolute; left: 12%; width: 76%; top: 96%; height: 6%; border-radius: 50%; background: #1B2A5A; opacity: 0; filter: blur(10px); }
.fc-intro__reflection {
  position: absolute; top: 99%; left: 0; width: 100%; height: 34%; overflow: hidden; opacity: 0; filter: blur(2px);
  -webkit-mask-image: linear-gradient(rgba(0, 0, 0, .55), transparent 92%); mask-image: linear-gradient(rgba(0, 0, 0, .55), transparent 92%);
}
.fc-intro__reflection img { width: 100%; height: auto; transform: scaleY(-1); opacity: .5; }

.fc-intro__caption { position: absolute; left: 0; top: 0; width: 100%; padding: 0 24px; text-align: center; opacity: 0; will-change: transform, opacity; }
.fc-intro__caption p { margin: 0; font-size: clamp(19px, 2.1vw, 25px); font-weight: 560; letter-spacing: -.02em; line-height: 1.3; color: var(--ink); }
.fc-intro__caption span { display: block; margin-top: 14px; font-size: 10.5px; font-weight: 650; letter-spacing: .3em; color: var(--muted); }

.fc-intro__skip {
  position: absolute; top: max(22px, env(safe-area-inset-top)); right: max(24px, env(safe-area-inset-right));
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 16px; border-radius: 999px;
  border: 1px solid rgba(28, 34, 40, .1); background: rgba(255, 255, 255, .55);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: var(--ink-2); font: 560 13px/1 var(--font); cursor: pointer; transition: background-color .2s ease;
}
.fc-intro__skip:hover { background: #fff; }
.fc-intro__foot {
  position: absolute; left: max(32px, env(safe-area-inset-left)); right: max(32px, env(safe-area-inset-right)); bottom: max(28px, env(safe-area-inset-bottom));
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  color: var(--muted); font-size: 10px; font-weight: 650; letter-spacing: .24em; will-change: opacity;
}
.fc-intro__foot img { height: 20px; width: auto; }

@media (max-width: 600px) {
  .fc-intro__skip { top: max(14px, env(safe-area-inset-top)); right: 14px; height: 34px; padding: 0 14px; font-size: 12.5px; }
  .fc-intro__foot { left: 20px; right: 20px; bottom: max(20px, env(safe-area-inset-bottom)); font-size: 8.5px; letter-spacing: .18em; }
  .fc-intro__foot img { height: 17px; }
  .fc-intro__caption span { font-size: 9.5px; letter-spacing: .24em; }
}
@media (forced-colors: active) { html.fc-intro-pending::before, .fc-intro__veil { background: Canvas; } }

/* The logo "catches" the mark at the end of the intro. */
html.fc-m .site-header .brand { position: relative; display: inline-block; }
html.fc-m .brand.fc-land img { animation: fc-land .7s cubic-bezier(.2, .9, .3, 1.2); }
@keyframes fc-land {
  0% { transform: scale(1.06); filter: drop-shadow(0 0 0 rgba(63, 88, 212, 0)); }
  35% { filter: drop-shadow(0 0 10px rgba(63, 88, 212, .45)); }
  100% { transform: none; filter: drop-shadow(0 0 0 rgba(63, 88, 212, 0)); }
}
/* Light sweep across the logo (after landing and on hover). */
html.fc-m .site-header .brand::after {
  content: ""; position: absolute; inset: 7px 0; pointer-events: none; opacity: 0;
  background: linear-gradient(110deg, transparent 35%, rgba(255, 255, 255, .95) 50%, transparent 65%) 160% 0 / 300% 100% no-repeat;
  -webkit-mask: url("/assets/logo-koyu.png") center / contain no-repeat; mask: url("/assets/logo-koyu.png") center / contain no-repeat;
}
html.fc-m .site-header .brand.fc-land::after { animation: fc-sweep .9s .15s ease-out; }
@media (hover: hover) and (pointer: fine) { html.fc-m .site-header .brand:hover::after { animation: fc-sweep .9s ease-out; } }
@keyframes fc-sweep { 0% { opacity: 1; background-position: 160% 0; } 100% { opacity: 1; background-position: -60% 0; } }

/* ---------------------------------------------------------------- Hero entrance (all pages) */
/* html.fc-m is set in <head> before the first frame, so the hero never flashes sharp → blurred → sharp.
   Only filter and translate animate: the hero text and image are painted at once (no opacity), which keeps
   Largest Contentful Paint as fast as before. */
html.fc-m :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > * {
  animation: fc-up 1s cubic-bezier(.16, 1, .3, 1) both, fc-unblur .55s cubic-bezier(.16, 1, .3, 1) both;
}
html.fc-m :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > :nth-child(2) { animation-delay: 70ms; }
html.fc-m :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > :nth-child(3) { animation-delay: 140ms; }
html.fc-m :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > :nth-child(4) { animation-delay: 210ms; }
html.fc-m :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > :nth-child(5) { animation-delay: 280ms; }
html.fc-m :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > :nth-child(n+6) { animation-delay: 340ms; }
html.fc-m .hero-visual .phone { animation: fc-rise 1.25s cubic-bezier(.16, 1, .3, 1) .12s both; }
html.fc-m .hero-visual .phone-back { animation-delay: .26s; }

/* During the intro the entrance waits (3s failsafe if motion.js never runs); fc-go restarts it under a new name. */
html.fc-hold :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > *,
html.fc-hold .hero-visual .phone { animation-delay: 3s !important; }
html.fc-go :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > * { animation-name: fc-up-2, fc-unblur-2; }
html.fc-go .hero-visual .phone { animation-name: fc-rise-2; }

@keyframes fc-up { from { translate: 0 18px; } to { translate: none; } }
@keyframes fc-up-2 { from { translate: 0 18px; } to { translate: none; } }
@keyframes fc-unblur { from { filter: blur(9px); } to { filter: none; } }
@keyframes fc-unblur-2 { from { filter: blur(9px); } to { filter: none; } }
@keyframes fc-rise { from { translate: 0 56px; scale: .955; } to { translate: none; scale: none; } }
@keyframes fc-rise-2 { from { translate: 0 56px; scale: .955; } to { translate: none; scale: none; } }

/* Accent words: one slow light sweep after the headline settles. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  html.fc-m .hero h1 .accent {
    background: linear-gradient(100deg, var(--brand) 0 38%, #8D9CFF 47%, #C9D1FF 50%, #8D9CFF 53%, var(--brand) 62% 100%) 100% 0 / 260% 100% no-repeat;
    -webkit-background-clip: text; background-clip: text; color: transparent;
    animation: fc-shimmer 2.4s cubic-bezier(.45, 0, .2, 1) 1.1s both;
  }
  html.fc-m .hero h1 .accent::selection { color: #fff; background: var(--brand); }
  html.fc-hold .hero h1 .accent { animation-delay: 4.1s !important; }
  html.fc-go .hero h1 .accent { animation-name: fc-shimmer-2; animation-delay: 1.1s; }
}
@media (forced-colors: active), print { html.fc-m .hero h1 .accent { background: none; color: var(--brand); } }
@keyframes fc-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
@keyframes fc-shimmer-2 { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* ---------------------------------------------------------------- Hero phones: float, tilt, glare */
/* Tilt only on wide screens with a mouse (motion.js adds .fc-tilt); the phones keep their own layout transforms. */
@media (min-width: 961px) {
  html.fc-m .hero-visual.fc-tilt { transform: perspective(1400px) rotateX(var(--fc-rx, 0deg)) rotateY(var(--fc-ry, 0deg)); transform-style: preserve-3d; }
  html.fc-m .hero-visual.fc-tilt .phone-front { transform: translateZ(28px) scale(.98); }
  html.fc-m .hero-visual.fc-tilt .phone-back { transform: translateZ(0) rotate(6deg); }
}
/* Gentle float once the phones have arrived (the back phone starts later, from rest, so nothing jumps). */
html.fc-m .hero-visual .phone.fc-float { animation: fc-float 7s ease-in-out infinite; }
html.fc-m .hero-visual .phone-back.fc-float { animation-duration: 8.5s; animation-delay: 1.4s; }
@keyframes fc-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -10px; } }
html.fc-m .hero-visual .phone::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: var(--fc-glare, 0);
  background: radial-gradient(circle at var(--fc-gx, 30%) var(--fc-gy, 20%), rgba(255, 255, 255, .26), transparent 46%);
  mix-blend-mode: screen; transition: opacity .4s ease;
}

/* ---------------------------------------------------------------- Scroll reveal */
/* Added by motion.js only to elements that start below the fold, removed again once they have arrived.
   Start states first; the arrival rule carries an extra type selector so it always wins over them. */
.fc-r { opacity: 0; translate: 0 28px; }
.fc-r.fc-soft { translate: 0 14px; }
.fc-r.fc-deal { translate: 0 44px; rotate: x 18deg; transform-origin: 50% 100%; }
.fc-r.fc-pop { translate: none; scale: .6; rotate: -14deg; }
.shot:has(> .fc-deal) { perspective: 1000px; }
html .fc-r.fc-in {
  opacity: 1; translate: none; rotate: none; scale: none;
  transition: opacity .9s cubic-bezier(.16, 1, .3, 1) var(--fc-d, 0ms), translate 1s cubic-bezier(.16, 1, .3, 1) var(--fc-d, 0ms),
    rotate 1.1s cubic-bezier(.16, 1, .3, 1) var(--fc-d, 0ms), scale 1s cubic-bezier(.2, .9, .3, 1.25) var(--fc-d, 0ms);
}
html .fc-r.fc-pop.fc-in { transition: opacity .6s ease var(--fc-d, 0ms), scale 1s cubic-bezier(.2, .9, .3, 1.25) var(--fc-d, 0ms), rotate 1s cubic-bezier(.2, .9, .3, 1.25) var(--fc-d, 0ms); }
@media print { .fc-r { opacity: 1 !important; translate: none !important; rotate: none !important; scale: none !important; } }

/* ---------------------------------------------------------------- Buttons */
html.fc-m .btn-primary { position: relative; overflow: hidden; isolation: isolate; }
html.fc-m .btn-primary::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .32) 48%, transparent 64%) 170% 0 / 260% 100% no-repeat;
}
@media (hover: hover) and (pointer: fine) {
  html.fc-m .btn-primary:hover::after { animation: fc-btn-sweep .85s ease-out; }
  html.fc-m :is(.btn, .card-link, .link-light):hover .ic:has(> use[href="#i-arrow"]) { translate: 4px 0; }
  html.fc-m .btn:hover .ic:has(> use[href="#i-external"]) { translate: 2px -2px; }
}
html.fc-m :is(.btn, .card-link, .link-light) .ic { transition: translate .25s cubic-bezier(.2, .7, .3, 1); }
@keyframes fc-btn-sweep { from { background-position: 170% 0; } to { background-position: -70% 0; } }

/* ---------------------------------------------------------------- Pointer spotlight on cards */
/* Desktop widths only: at <=760px the feature cards become a plain grouped list. */
@property --fc-a { syntax: "<number>"; inherits: false; initial-value: 0; }
@media (hover: hover) and (pointer: fine) and (min-width: 761px) {
  html.fc-m :is(.card, .related a, .flow li, .side-box, .invest-card, .try), html.fc-m .band-light .side-box {
    background-image: radial-gradient(420px circle at var(--fc-mx, 50%) var(--fc-my, 50%), rgba(63, 88, 212, calc(var(--fc-a) * .085)), transparent 46%);
    transition: --fc-a .35s ease, border-color .2s ease, box-shadow .3s ease, transform .15s ease;
  }
  html.fc-m .card-dark {
    background-image: radial-gradient(380px circle at var(--fc-mx, 50%) var(--fc-my, 50%), rgba(141, 156, 255, calc(var(--fc-a) * .16)), transparent 50%);
    transition: --fc-a .35s ease, border-color .25s ease;
  }
  html.fc-m :is(.card, .related a, .flow li, .side-box, .invest-card, .try, .card-dark):hover { --fc-a: 1; }
  html.fc-m .card:hover { border-color: #CCD5EA; box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 18px 36px -18px rgba(23, 42, 120, .28); }
  html.fc-m .card-dark:hover { border-color: #3A4A78; }
  html.fc-m .card .icon-chip { transition: transform .35s cubic-bezier(.2, .8, .3, 1.3), background-color .25s ease, color .25s ease; }
  html.fc-m .card:hover .icon-chip { transform: translateY(-2px) rotate(-4deg); background: var(--brand); color: #fff; }
  html.fc-m .card-dark .svc-ic { transition: color .25s ease, transform .35s cubic-bezier(.2, .8, .3, 1.3); }
  html.fc-m .card-dark:hover .svc-ic { color: var(--brand-light); transform: scale(1.08); }
}

/* ---------------------------------------------------------------- Live market lines (dark band) */
/* Sized and placed by motion.js in the free space right of the heading. */
.fc-lines {
  position: absolute; top: 0; left: 0; pointer-events: none; opacity: 0; transition: opacity 1.2s ease;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 32%, #000 90%, transparent), linear-gradient(transparent, #000 24%, #000 80%, transparent);
  -webkit-mask-composite: source-in; mask-image: linear-gradient(90deg, transparent, #000 32%, #000 90%, transparent), linear-gradient(transparent, #000 24%, #000 80%, transparent);
  mask-composite: intersect;
}
.fc-lines.fc-on { opacity: 1; }

/* ---------------------------------------------------------------- Step lists fill as you scroll */
:is(.process-row, .rows > li).fc-step { position: relative; }
:is(.process-row, .rows > li).fc-step::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--brand), #8D9CFF);
  transform: scaleX(var(--fc-p, 0)); transform-origin: left center;
}
.process-row.fc-step .process-no { transition: color .3s ease; }
.process-row.fc-step.fc-lit .process-no { color: var(--brand); font-weight: 700; }

/* ---------------------------------------------------------------- Small touches */
html.fc-m .faq details.fc-closing summary::after { transform: none; }
html.fc-m .badge .dot { position: relative; }
html.fc-m .badge .dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: inherit; animation: fc-ping 2.4s cubic-bezier(0, 0, .2, 1) infinite; }
@keyframes fc-ping { 0% { transform: scale(1); opacity: .6; } 75%, 100% { transform: scale(2.8); opacity: 0; } }

/* Reading progress on blog posts. */
.fc-progress { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; pointer-events: none; transform: scaleX(var(--fc-read, 0)); transform-origin: left center; background: linear-gradient(90deg, var(--brand), #8D9CFF); will-change: transform; }

/* "Pause animations" control in the footer (motion.js adds it; WCAG 2.2.2). */
.fc-motion-toggle { display: inline-block; margin: -10px 0; padding: 10px 0; border: 0; background: none; color: var(--dark-ink); font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
/* Paused: endless animations stop, anything still waiting to scroll in is simply shown. */
html.fc-still .hero-visual .phone, html.fc-still .badge .dot::after { animation-play-state: paused !important; }
html.fc-m .hero-visual.fc-away .phone.fc-float, html.fc-m .badge.fc-away .dot::after { animation-play-state: paused !important; }
html.fc-still .fc-r { opacity: 1 !important; translate: none !important; rotate: none !important; scale: none !important; transition: none !important; }

/* ---------------------------------------------------------------- Page transitions */
/* Same-site navigations cross-fade (Chrome, Edge, Safari 18.2+); the header stays put. Others: no change.
   Pages without html.fc-m (no JavaScript, crawler, paused by the visitor) switch instantly as before. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  html.fc-m .site-header { view-transition-name: fc-header; }
  html.fc-m::view-transition-old(root) { animation: fc-vt-out .22s ease both; }
  html.fc-m::view-transition-new(root) { animation: fc-vt-in .42s cubic-bezier(.16, 1, .3, 1) both; }
  html:not(.fc-m)::view-transition-group(*), html:not(.fc-m)::view-transition-old(*), html:not(.fc-m)::view-transition-new(*) { animation: none; }
  html.fc-intro-pending::view-transition-group(*), html.fc-intro-pending::view-transition-old(*), html.fc-intro-pending::view-transition-new(*) { animation: none !important; }
}
@keyframes fc-vt-out { to { opacity: 0; } }
@keyframes fc-vt-in { from { opacity: 0; translate: 0 10px; } }

/* ---------------------------------------------------------------- Accessibility */
@media (prefers-reduced-motion: reduce) {
  html.fc-intro-pending::before, .fc-intro, .fc-lines, .fc-progress { display: none !important; }
  .fc-r { opacity: 1 !important; translate: none !important; rotate: none !important; scale: none !important; }
}

/* ---------------------------------------------------------------- Light mode */
/* html.fc-lite (2 GB RAM or less, Save-Data, 2G): the head guard skips the intro; here the hero only slides
   (no blur) and nothing moves endlessly. motion.js also leaves out the tilt and the live chart. */
html.fc-lite :is(.hero-copy, .page-hero > .container:not(.page-hero-grid), .page-hero-grid > :first-child) > * { animation-name: fc-up !important; }
html.fc-lite .hero-visual .phone.fc-float, html.fc-lite .badge .dot::after { animation: none !important; }
