/* Void Finance: motion and pointer effects for every page but the Portal (fx.js drives them; the Portal's pages
   load neither file). Nothing here is needed to read or use a page: without JavaScript, or with reduced motion,
   the pages look as site.css draws them. */

:root { --fx-ease: cubic-bezier(0.2, 0.7, 0.2, 1); }

/* --------------------------------------------------------------- presses */
/* A ripple from where a button is pressed, in the button's text colour (fx.js adds the .fx-ink layer). */
.btn, .dc-btn, .chat-cmd, .chat-tool, .nav-menu summary, .nav-links a, .ex-tab, .ex-item, a.cmd-chip, .x-chip, .fx-top { -webkit-tap-highlight-color: transparent; }
.btn, .dc-btn, .chat-cmd, .chat-tool, .nav-menu summary, .nav-links a, .ex-tab, .ex-item, a.cmd-chip, .x-chip { position: relative; isolation: isolate; }
.fx-ink { position: absolute; inset: 0; z-index: -1; overflow: hidden; border-radius: inherit; pointer-events: none; }
.fx-ink i {
  position: absolute; border-radius: 50%; pointer-events: none; opacity: 0.3;
  background: radial-gradient(closest-side, currentColor, transparent);
  transform: translate(-50%, -50%) scale(0); animation: fx-ink 0.65s var(--fx-ease) forwards;
}
@keyframes fx-ink { to { transform: translate(-50%, -50%) scale(1); opacity: 0; } }

/* -------------------------------------------------------------- buttons */
/* They lean toward a mouse (--tx, --ty from fx.js) and sink a little when pressed. */
.btn {
  translate: var(--tx, 0) var(--ty, 0);
  transition: background-color 0.2s, border-color 0.2s, color 0.2s, box-shadow 0.25s, transform 0.25s, translate 0.35s var(--fx-ease);
}
.btn:active { transform: scale(0.97); transition-duration: 0.2s, 0.2s, 0.2s, 0.25s, 0.08s, 0.35s; }
@media (hover: hover) {
  /* The sky button: a streak of light crosses it. The outlined one: a glow under the pointer. */
  .btn-primary::before {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.55) 50%, transparent 60%) 150% 0 / 250% 100% no-repeat;
  }
  .btn-primary:hover::before { background-position: -50% 0; transition: background-position 0.9s var(--fx-ease); }
  .btn-ghost::before {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity 0.3s;
    background: radial-gradient(110px circle at var(--mx, 50%) var(--my, 50%), rgba(56, 189, 248, 0.3), transparent 70%);
  }
  .btn-ghost:hover::before { opacity: 1; }
  a.cmd-chip:hover { translate: 0 -2px; background: rgba(56, 189, 248, 0.12); box-shadow: 0 8px 18px -10px rgba(56, 189, 248, 0.8); }
}
a.cmd-chip { transition: border-color 0.2s, color 0.2s, background-color 0.2s, translate 0.25s var(--fx-ease), box-shadow 0.25s; }

/* --------------------------------------------------------------- header */
.site-header { transition: background-color 0.3s, box-shadow 0.3s; }
.site-header.is-scrolled { background: rgba(6, 11, 16, 0.86); box-shadow: 0 14px 34px -22px rgba(0, 0, 0, 0.9); }
@media (prefers-reduced-motion: no-preference) {
  .nav-menu[open] .nav-menu-panel { transform-origin: 100% 0; animation: fx-menu 0.22s var(--fx-ease) both; }
  .nav-menu[open] .nav-menu-panel a { animation: fx-up 0.35s var(--fx-ease) both; }
  .nav-menu[open] .nav-menu-panel a:nth-child(2) { animation-delay: 0.03s; }
  .nav-menu[open] .nav-menu-panel a:nth-child(3) { animation-delay: 0.06s; }
  .nav-menu[open] .nav-menu-panel a:nth-child(4) { animation-delay: 0.09s; }
  .nav-menu[open] .nav-menu-panel a:nth-child(5) { animation-delay: 0.12s; }
}
@keyframes fx-menu { from { opacity: 0; transform: translateY(-6px) scale(0.97); } }
@keyframes fx-up { from { opacity: 0; transform: translateY(8px); } }

/* ------------------------------------------------------------- panels */
/* Under a mouse, a panel lights up where the pointer is, its edge brightest nearest it (fx.js adds .fx-spot and
   sets --mx, --my); the Portal window also tilts toward it (--px, --py: -1 to 1). */
.fx-glow { position: relative; isolation: isolate; }
.fx-spot {
  position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity 0.4s;
  background: radial-gradient(560px circle at var(--mx, 50%) var(--my, 50%), rgba(125, 211, 252, 0.12), transparent 45%);
}
.fx-spot::after {
  content: ""; position: absolute; inset: 0; padding: 1px; border-radius: inherit;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%), rgba(125, 211, 252, 0.8), transparent 65%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
.fx-glow.is-hot > .fx-spot { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .fx-tilt.is-tilting { transform: perspective(1200px) rotateX(calc(var(--py, 0) * var(--tilt, 3) * -1deg)) rotateY(calc(var(--px, 0) * var(--tilt, 3) * 1deg)); }
  .promo-window.fx-tilt { transition: transform 0.5s var(--fx-ease); }
}

/* --------------------------------------------------------- scroll reveal */
/* Below the fold, sections rise into view as they're reached (fx.js); the timeline's line draws itself. */
.fx-rv { transition: opacity 0.9s var(--fx-ease) var(--d, 0s), translate 0.9s var(--fx-ease) var(--d, 0s); }
.fx-rv:not(.is-in) { opacity: 0; translate: 0 26px; }
.timeline.fx-draw::before { transform: scaleX(0); transform-origin: 0 50%; transition: transform 1.6s var(--fx-ease) 0.1s; }
.timeline.fx-draw.is-in::before { transform: none; }
@media (max-width: 1099px) {
  .timeline.fx-draw::before { transform: scaleY(0); transform-origin: 50% 0; }
  .timeline.fx-draw.is-in::before { transform: none; }
}
@media print {
  .fx-rv { opacity: 1 !important; translate: none !important; }
  .timeline.fx-draw::before { transform: none !important; }
  .fx-top, .fx-aura { display: none !important; }
}

/* ------------------------------------------------------------- the day */
/* A pulse of light runs along the timeline, through the day's posts (its background moves, not its box, so nothing
   reaches past the page); each stop's dot lights under the pointer. */
.stop::before { transition: box-shadow 0.3s, scale 0.3s var(--fx-ease); }
@media (hover: hover) {
  .stop:hover::before { scale: 1.35; box-shadow: 0 0 0 5px rgba(186, 230, 253, 0.18), 0 0 16px rgba(186, 230, 253, 0.85); }
}
@media (prefers-reduced-motion: no-preference) {
  .timeline::after {
    content: ""; position: absolute; left: 0; right: 0; top: 1px; height: 7px; pointer-events: none;
    background: radial-gradient(closest-side, rgba(224, 242, 254, 0.95), rgba(186, 230, 253, 0.3) 45%, transparent) 0 0 / 120px 7px no-repeat;
    animation: fx-run-x 7s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  }
  .timeline.fx-draw:not(.is-in)::after { display: none; }
}
@keyframes fx-run-x {
  0% { background-position: 0 0; opacity: 0; }
  10%, 80% { opacity: 1; }
  100% { background-position: 100% 0; opacity: 0; }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 1099px) {
  .timeline::after { left: 1px; right: auto; top: 0; bottom: 0; width: 7px; height: auto; background-size: 7px 120px; animation-name: fx-run-y; }
}
@keyframes fx-run-y {
  0% { background-position: 0 0; opacity: 0; }
  10%, 80% { opacity: 1; }
  100% { background-position: 0 100%; opacity: 0; }
}

/* ------------------------------------------------ home: background motion */
/* The headline's green-to-sky words shimmer slowly. */
@media (prefers-reduced-motion: no-preference) {
  .hero h1 em {
    background-image: linear-gradient(95deg, #B7DDB0 0%, #7CC4E4 28%, #BAE6FD 50%, #7CC4E4 72%, #B7DDB0 100%);
    background-size: 200% 100%; animation: fx-sheen 9s ease-in-out infinite alternate;
  }
}
@keyframes fx-sheen { to { background-position: 100% 0; } }

/* The bright spot on each section's hairline sweeps along it, never past its ends: anything wider than the
   screen makes phones zoom the page out, whatever body's overflow says. */
@media (prefers-reduced-motion: no-preference) {
  .ruled::after { --reach: calc(min(100vw - 2 * var(--gutter), var(--wrap)) / 2 - 110px); animation: fx-scan 11s ease-in-out infinite; }
  #portal.ruled::after { animation-delay: -4s; }
  #automate.ruled::after { animation-delay: -7.5s; }
  #faq.ruled::after { animation-delay: -2s; }
}
@keyframes fx-scan {
  0% { transform: translateX(calc(-1 * var(--reach))); opacity: 0; }
  15%, 85% { opacity: 1; }
  100% { transform: translateX(var(--reach)); opacity: 0; }
}

/* Slow glows drifting behind the Portal and Automated Posts sections (paused while off screen, fx.js). */
.promo, .automate { isolation: isolate; }
.aurora { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.aurora i { position: absolute; width: 56vmax; height: 56vmax; border-radius: 50%; background: radial-gradient(closest-side, rgba(53, 147, 197, 0.14), transparent); }
.aurora i:nth-child(1) { left: -18vmax; top: -12vmax; }
.aurora i:nth-child(2) { right: -20vmax; top: 30%; background: radial-gradient(closest-side, rgba(150, 192, 140, 0.1), transparent); }
@media (prefers-reduced-motion: no-preference) {
  .aurora i:nth-child(1) { animation: fx-drift-a 28s ease-in-out infinite alternate; }
  .aurora i:nth-child(2) { animation: fx-drift-b 34s ease-in-out infinite alternate; }
  .fx-io .aurora:not(.is-live) i { animation-play-state: paused; }
}
@keyframes fx-drift-a { to { transform: translate(24vw, 16vh) scale(1.15); } }
@keyframes fx-drift-b { to { transform: translate(-26vw, -12vh) scale(0.9); } }

/* A band of light passes over the numbers. */
.stats { overflow: hidden; isolation: isolate; }
.stats::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; transform: translateX(-100%);
  background: linear-gradient(100deg, transparent 35%, rgba(125, 211, 252, 0.07) 50%, transparent 65%);
}
@media (prefers-reduced-motion: no-preference) { .stats::after { animation: fx-sweep 9s ease-in-out infinite; } }
@keyframes fx-sweep { 0%, 15% { transform: translateX(-100%); } 85%, 100% { transform: translateX(100%); } }

/* Stars drifting down toward the planet at the bottom of the last panel, two layers at two speeds; the near
   ones twinkle. Each layer repeats every 240px, so moving it 240px loops without a seam. */
.cta-sky {
  position: absolute; inset: 0; z-index: -2; overflow: hidden; pointer-events: none;
  -webkit-mask-image: linear-gradient(#000 25%, transparent 72%); mask-image: linear-gradient(#000 25%, transparent 72%);
}
.cta-sky::before, .cta-sky::after { content: ""; position: absolute; left: 0; right: 0; top: -240px; bottom: 0; }
.cta-sky::before {
  background-image:
    radial-gradient(1.5px 1.5px at 40px 60px, rgba(255, 255, 255, 0.8), transparent),
    radial-gradient(1px 1px at 190px 150px, rgba(186, 230, 253, 0.9), transparent),
    radial-gradient(1.2px 1.2px at 262px 28px, rgba(255, 255, 255, 0.6), transparent),
    radial-gradient(1px 1px at 96px 206px, rgba(255, 255, 255, 0.5), transparent);
  background-size: 300px 240px;
}
.cta-sky::after {
  background-image:
    radial-gradient(2px 2px at 120px 90px, rgba(224, 242, 254, 0.95), transparent),
    radial-gradient(1.5px 1.5px at 330px 200px, rgba(255, 255, 255, 0.75), transparent);
  background-size: 420px 240px;
}
@media (prefers-reduced-motion: no-preference) {
  .cta-sky::before { animation: fx-fall 64s linear infinite; }
  .cta-sky::after { animation: fx-fall 40s linear infinite, fx-twinkle 3.2s ease-in-out infinite alternate; }
}
@keyframes fx-fall { to { transform: translateY(240px); } }
@keyframes fx-twinkle { from { opacity: 0.25; } }

/* -------------------------------------------------------- /commands */
.chat-cmd-ico { transition: transform 0.25s var(--fx-ease), background-color 0.2s; }
@media (hover: hover) { .chat-cmd:hover .chat-cmd-ico { transform: scale(1.08); background: rgba(113, 172, 243, 0.2); } }

/* -------------------------------------------------------------- the 404 */
/* The void, turning behind the message (hero.js, data-at), and the message coming in. */
.not-found { position: relative; isolation: isolate; }
.not-found .emblem { opacity: 0.55; -webkit-mask-image: radial-gradient(farthest-side, #000 45%, transparent); mask-image: radial-gradient(farthest-side, #000 45%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .not-found .wrap > * { animation: fx-up 0.8s var(--fx-ease) both; }
  .not-found .wrap > :nth-child(2) { animation-delay: 0.08s; }
  .not-found .wrap > :nth-child(3) { animation-delay: 0.16s; }
  .not-found .wrap > :nth-child(4) { animation-delay: 0.24s; }
}

/* ---------------------------------------------------------- back to top */
/* Long pages: a round button, bottom right, once the page has scrolled; its ring fills as the page goes down. */
.fx-top {
  position: fixed; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 40;
  display: grid; place-items: center; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(8, 15, 21, 0.82); color: var(--kicker); cursor: pointer;
  box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.8);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  opacity: 0; visibility: hidden; transform: translateY(12px) scale(0.9);
  translate: var(--tx, 0) var(--ty, 0);
  transition: opacity 0.3s, visibility 0.3s, transform 0.35s var(--fx-ease), translate 0.35s var(--fx-ease), color 0.2s, box-shadow 0.3s;
}
.fx-top.is-on { opacity: 1; visibility: visible; transform: none; }
.fx-top:active { transform: scale(0.93); }
.fx-top svg { width: 48px; height: 48px; }
.fx-top circle { fill: none; stroke-width: 2; }
.fx-top-track { stroke: rgba(186, 230, 253, 0.14); }
.fx-top-ring { stroke: var(--sky); stroke-linecap: round; stroke-dasharray: 138.2; stroke-dashoffset: 138.2; }
.fx-top path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.3s var(--fx-ease); }
@media (hover: hover) {
  .fx-top:hover { color: var(--white); box-shadow: 0 14px 34px -12px rgba(56, 189, 248, 0.65); }
  .fx-top:hover path { transform: translateY(-2px); }
}
@media (min-width: 640px) { .fx-top { right: 24px; bottom: 24px; } }
/* Phones: above the home page's bottom bar while it shows. */
@media (max-width: 639px) { .mbar-on .fx-top { bottom: calc(80px + env(safe-area-inset-bottom, 0px)); } }

/* ------------------------------------------------------ the pointer's light */
/* A soft light that trails a mouse over the page (fx.js; not on touch screens). */
.fx-aura {
  position: fixed; left: -320px; top: -320px; z-index: 1; width: 640px; height: 640px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(56, 189, 248, 0.07), rgba(56, 189, 248, 0.025) 50%, transparent);
  opacity: 0; transition: opacity 0.6s; will-change: transform;
}
.fx-aura.is-on { opacity: 1; }
