Replace the landing with the artifact design and rebuild the admin in Ant Design.

Adds consultation leads, section editors, and the one-time content reset for this release.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-01 20:36:06 +03:30
co-authored by Cursor
parent 5147c661f0
commit b0088c35d1
130 changed files with 8024 additions and 2801 deletions
+68 -10
View File
@@ -1,19 +1,77 @@
import Lenis from "lenis";
const REVEAL_SELECTOR = ".fade-item:not(.revealed)";
const REVEAL_SCROLL_RATIO = 0.88;
const REVEAL_INITIAL_RATIO = 0.92;
const INITIAL_REVEAL_DELAY_MS = 150;
/**
* Inertial scrolling plus the two scroll-driven effects that depend on it:
* the top progress bar and the `.fade-item` reveal.
*/
export default defineNuxtPlugin((nuxtApp) => {
if (!import.meta.client) return;
const lenis = new Lenis({ lerp: 0.09, smoothWheel: true });
let raf = 0;
const lenis = new Lenis({
duration: 1.2,
easing: (t: number) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
orientation: "vertical",
smoothWheel: true,
wheelMultiplier: 1.05,
touchMultiplier: 1.8,
});
let pending: HTMLElement[] = [];
let progressEl: HTMLElement | null = null;
const collect = () => {
pending = Array.from(document.querySelectorAll<HTMLElement>(REVEAL_SELECTOR));
progressEl = document.querySelector<HTMLElement>(".scroll-progress");
};
const reveal = (ratio: number) => {
if (!pending.length) return;
const limit = window.innerHeight * ratio;
const hits: HTMLElement[] = [];
pending = pending.filter((el) => {
if (!el.isConnected) return false;
if (el.getBoundingClientRect().top <= limit) {
hits.push(el);
return false;
}
return true;
});
for (const el of hits) el.classList.add("revealed");
};
lenis.on("scroll", (e: Lenis) => {
if (progressEl) {
const total = document.documentElement.scrollHeight - window.innerHeight;
const progress = total > 0 ? e.scroll / total : 0;
progressEl.style.transform = `scaleX(${progress})`;
}
reveal(REVEAL_SCROLL_RATIO);
});
let rafId = 0;
const loop = (time: number) => {
lenis.raf(time);
raf = requestAnimationFrame(loop);
rafId = requestAnimationFrame(loop);
};
raf = requestAnimationFrame(loop);
nuxtApp.hook("app:unmounted", () => {
cancelAnimationFrame(raf);
rafId = requestAnimationFrame(loop);
const initialReveal = () => {
collect();
window.setTimeout(() => {
collect();
reveal(REVEAL_INITIAL_RATIO);
}, INITIAL_REVEAL_DELAY_MS);
};
nuxtApp.hook("app:mounted", initialReveal);
nuxtApp.hook("page:finish", initialReveal);
nuxtApp.vueApp.onUnmount(() => {
cancelAnimationFrame(rafId);
lenis.destroy();
});
return {
provide: { lenis },
};
return { provide: { lenis } };
});