/* Valmier fx — polish + motion layer on top of app.css.
   Everything here is decoration: remove this file and the panel still works.
   Each user can switch animations off on the account page → <html class="calm"> (bottom of file).
   The device's reduce-motion setting is deliberately ignored (owner's choice, 2026-10-05). */

/* ============ living sky behind every page ============ */
body { background: var(--abyss); }
body::before, body::after { content: ""; position: fixed; pointer-events: none; z-index: -1; }
body::before { /* aurora: two dusk clouds drifting */
  inset: -20vh -20vw auto; height: 80vh;
  background:
    radial-gradient(40% 50% at 78% 30%, rgba(196, 22, 58, .38), transparent 70%),
    radial-gradient(35% 45% at 25% 20%, rgba(122, 44, 102, .42), transparent 70%),
    radial-gradient(30% 40% at 55% 0%, rgba(242, 134, 42, .14), transparent 70%);
  animation: aurora 26s ease-in-out infinite alternate; will-change: transform;  /* no live blur: the gradients are soft already */
}
body::after { /* film grain */
  inset: 0; opacity: .03;  /* no full-screen blending: it cost frames on every repaint */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@keyframes aurora {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(-4vw, 3vh, 0) scale(1.08); }
  100% { transform: translate3d(3vw, -2vh, 0) scale(1.02); }
}

/* ============ cards: gradient hairline + cursor spotlight ============ */
.card, .stat, .tile, .login .login-card, dialog.modal {
  border: 1px solid transparent;
  background:
    linear-gradient(180deg, var(--night-2), var(--night)) padding-box,
    linear-gradient(160deg, rgba(255, 255, 255, .13), rgba(255, 255, 255, .03) 38%, rgba(255, 255, 255, .02) 62%, rgba(224, 56, 43, .28)) border-box;
}
.tile { background: linear-gradient(180deg, #12080C, var(--abyss)) padding-box, linear-gradient(160deg, rgba(255,255,255,.1), rgba(255,255,255,.02) 50%, rgba(224,56,43,.22)) border-box; }
.login .login-card { background: linear-gradient(180deg, rgba(33, 16, 25, .82), rgba(20, 9, 14, .86)) padding-box, linear-gradient(160deg, rgba(255,255,255,.18), rgba(255,255,255,.03) 45%, rgba(242,134,42,.35)) border-box; }
.card.hl { background: linear-gradient(135deg, rgba(242, 134, 42, .1), var(--night) 60%) padding-box, linear-gradient(160deg, rgba(242, 134, 42, .55), rgba(242, 134, 42, .08) 50%, rgba(224, 56, 43, .3)) border-box; }
.card.danger { background: linear-gradient(135deg, rgba(240, 84, 74, .1), var(--night) 60%) padding-box, linear-gradient(160deg, rgba(240, 84, 74, .55), rgba(240, 84, 74, .08)) border-box; }

.fx-spot { position: relative; isolation: isolate; }
.fx-spot::before { /* light that follows the cursor (fx.js sets --mx/--my) */
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: -1;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, -40%), rgba(224, 56, 43, .10), transparent 45%);
  opacity: 0; transition: opacity .3s;
}
.fx-spot:hover::before { opacity: 1; }

.stat, .tile, .option { transition: transform .25s cubic-bezier(.2, .8, .2, 1), box-shadow .25s, border-color .2s, background .2s; }
.stat:hover, .tile:hover { transform: translateY(-3px); box-shadow: 0 18px 40px -22px rgba(196, 22, 58, .7); }
.option:hover { transform: translateY(-1px); }
.stat .s-ico { background: radial-gradient(circle at 30% 25%, rgba(255, 255, 255, .14), transparent 60%), var(--sky-soft); box-shadow: inset 0 1px 0 rgba(255,255,255,.08); transition: transform .35s cubic-bezier(.3, 1.6, .5, 1); }
.stat:hover .s-ico { transform: scale(1.08) rotate(-4deg); }

/* ============ hero: drifting sky, shimmer, embers ============ */
.hero {
  background:
    radial-gradient(420px 220px at 12% 0%, rgba(242, 134, 42, .34), transparent 70%),
    linear-gradient(125deg, #C4163A 0%, #8E1B45 30%, #4A1E3A 55%, #8E1B45 78%, #C4163A 100%);
  background-size: 100% 100%, 260% 260%;
  animation: sky-drift 18s ease-in-out infinite alternate;
}
@keyframes sky-drift { from { background-position: 0 0, 0% 30%; } to { background-position: 0 0, 100% 70%; } }
.hero .fx-embers { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; border-radius: inherit; }
.hero .fx-embers i {
  position: absolute; bottom: -8px; width: var(--s, 4px); height: var(--s, 4px); border-radius: 50%;
  background: radial-gradient(circle, #FFE2B8, #F2862A 55%, transparent 70%); box-shadow: 0 0 10px 2px rgba(242, 134, 42, .55);
  opacity: 0; animation: ember var(--d, 7s) linear var(--delay, 0s) infinite;
}
@keyframes ember {
  0%   { transform: translate3d(0, 0, 0); opacity: 0; }
  12%  { opacity: .9; }
  70%  { opacity: .6; }
  100% { transform: translate3d(var(--dx, 20px), -260px, 0); opacity: 0; }
}
.hero::before { /* one slow light sweep */
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, .09) 50%, transparent 65%);
  background-size: 250% 100%; animation: sweep 9s ease-in-out 1.2s infinite;
}
@keyframes sweep { 0% { background-position: 130% 0; } 40%, 100% { background-position: -130% 0; } }
.hero .amount { animation: glow-breathe 4.5s ease-in-out infinite; }
@keyframes glow-breathe { 50% { text-shadow: 0 0 44px rgba(242, 134, 42, .8); } }

/* ============ buttons ============ */
.btn { position: relative; overflow: hidden; isolation: isolate; transition: filter .15s, transform .12s cubic-bezier(.3, 1.6, .5, 1), box-shadow .2s; }
.btn::after { /* shine on hover */
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .28) 50%, transparent 70%);
  transform: translateX(120%); transition: transform 0s;
}
.btn:hover::after { transform: translateX(-120%); transition: transform .75s ease; }
.btn:active { transform: scale(.97); }
.btn.ghost::after, .btn.light::after { background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .1) 50%, transparent 70%); }
.btn.loading { pointer-events: none; color: transparent !important; }
.btn.loading::before {
  content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff; animation: spin .7s linear infinite;
}
.btn.ghost.loading::before, .btn.light.loading::before, .btn.soul.loading::before { border-color: rgba(128, 128, 128, .35); border-top-color: var(--ember); }
@keyframes spin { to { transform: rotate(360deg); } }
.icon-btn { transition: background .15s, color .15s, border-color .15s, transform .15s cubic-bezier(.3, 1.6, .5, 1); }
.icon-btn:hover { transform: translateY(-1px); }
.icon-btn:active { transform: scale(.92); }
.chip, .seg button, .ptabs button { transition: background .2s, color .2s, border-color .2s, transform .15s cubic-bezier(.3, 1.6, .5, 1); }
.chip:active, .seg button:active, .ptabs button:active { transform: scale(.94); }
.switch::after { transition: inset-inline-end .3s cubic-bezier(.3, 1.5, .5, 1), width .2s; }
.switch:active::after { width: 26px; }

/* ============ navigation ============ */
.side nav a { transition: background .2s, color .2s, transform .2s; }
.side nav a:hover:not(.on) { transform: translateX(-3px); }
.side nav a.on { view-transition-name: navpill; }
.tabbar a.on .ico { view-transition-name: tabpill; animation: pop .4s cubic-bezier(.3, 1.6, .5, 1); }
.brand img, .topbar-logo img { transition: transform .5s cubic-bezier(.3, 1.6, .5, 1); }
.brand:hover img { transform: rotate(-8deg) scale(1.06); }
@keyframes pop { 0% { transform: scale(.7); } 100% { transform: scale(1); } }
.topbar h1 { view-transition-name: pagetitle; }

/* ============ page entrance ============ */
.fx-in { animation: rise .55s cubic-bezier(.2, .8, .2, 1) both; animation-delay: calc(var(--i, 0) * 60ms); }
@keyframes rise { from { opacity: 0; transform: translateY(14px) scale(.985); } }
table.rtable tbody tr { animation: fade .45s ease both; animation-delay: calc(120ms + var(--r, 0) * 35ms); }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } }

/* bars, rings, numbers */
.bar i { transform-origin: right center; animation: grow 1s cubic-bezier(.2, .8, .2, 1) .25s both; position: relative; overflow: hidden; }
.bar i::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255,255,255,.35), transparent); transform: translateX(100%); animation: bar-shine 2.6s ease-in-out 1.4s infinite; }
@keyframes grow { from { transform: scaleX(0); } }
@keyframes bar-shine { 0% { transform: translateX(100%); } 60%, 100% { transform: translateX(-100%); } }
.ring .fill { transition: stroke-dasharray 1.3s cubic-bezier(.2, .8, .2, 1); }
.ring { animation: rise .6s cubic-bezier(.2, .8, .2, 1) .15s both; }
.pulse { animation-duration: 2.4s; }
.tag.dot::before { animation: dot-breathe 2.4s ease-in-out infinite; }
.tag.dot.gray::before { animation: none; }
@keyframes dot-breathe { 50% { box-shadow: 0 0 10px currentColor; opacity: .7; } }

/* ============ overlays ============ */
.toast { animation: toast-spring .55s cubic-bezier(.3, 1.5, .5, 1); }
@keyframes toast-spring { from { opacity: 0; transform: translate(-50%, -24px) scale(.9); } }
dialog.modal[open] { animation: modal-in .35s cubic-bezier(.3, 1.4, .5, 1); }
dialog.modal[open]::backdrop { animation: fade-bg .3s ease; }
@keyframes modal-in { from { opacity: 0; transform: translateY(16px) scale(.94); } }
@keyframes fade-bg { from { opacity: 0; } }
.side-open .side { transition: transform .35s cubic-bezier(.2, .9, .2, 1); }
.login .login-card { animation: rise .7s cubic-bezier(.2, .8, .2, 1) both; }
.login-brand img { animation: float 6s ease-in-out infinite; }
@keyframes float { 50% { transform: translateY(-6px) rotate(-2deg); } }
.fold > .card-body { animation: fade .3s ease; }
[data-ptabs].tabbed [data-panel].on { animation: fade .3s ease; }

/* ============ page-to-page transitions (Chrome/Edge 126+, Safari 18.2+) ============ */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out .18s ease both; }
::view-transition-new(root) { animation: vt-in .32s cubic-bezier(.2, .8, .2, 1) both; }
::view-transition-group(navpill), ::view-transition-group(tabpill) { animation-duration: .4s; animation-timing-function: cubic-bezier(.3, 1.2, .4, 1); }
::view-transition-group(pagetitle) { animation-duration: .3s; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; transform: translateY(8px); } }

/* ============ calm mode (account page switch) ============ */
html.calm *, html.calm *::before, html.calm *::after { animation: none !important; transition: none !important; }
html.calm body::before { display: none; }
html.calm .hero .fx-embers { display: none; }
html.calm::view-transition-group(*), html.calm::view-transition-old(*), html.calm::view-transition-new(*) { animation: none !important; }
