diff --git a/src/app/globals.css b/src/app/globals.css index 2d3531a8..3795253a 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -372,3 +372,10 @@ border-color: rgba(226, 232, 240, 0.08); } } + +/* Arriving from kgu.one (src/app/kgu-arrival.ts), the hero is in place from the first frame, under kgu.one's + dots, instead of fading up after hydration. Important beats the inline styles and animations motion sets. */ +html[data-kgu-arrival] [data-kgu-intro] { + opacity: 1 !important; + transform: none !important; +} diff --git a/src/app/kgu-arrival.ts b/src/app/kgu-arrival.ts new file mode 100644 index 00000000..ed7f1e09 --- /dev/null +++ b/src/app/kgu-arrival.ts @@ -0,0 +1,6 @@ +// Carries kgu.one's departure dots over this page's first frame on an arrival +// from kgu.one. then keeps data-kgu-arrival, so globals.css holds the +// hero in place for the page's life. A minified copy of kgu.one's arrival +// script (sha256 f987b955c836). +export const KGU_ARRIVAL = + '(()=>{var N={to:3.4,fill:6},U=360,ie=180,Me=U+ie,R={from:80,perMs:.24,edge:60},he=60,be=180,ye=U+he+be,W=320,re=192;function D(e){if(!(e>0))return 0;if(e>=1)return 1;let n=(u,s,d)=>3*s*u*(1-u)**2+3*d*u*u*(1-u)+u**3,r=0,c=1;for(let u=0;u<30;u++){let s=(r+c)/2;n(s,.23,.32){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)},se=(e,n=U)=>n*e;function w(e,n,r,c=R.from){let u=(e-se(n))/ie;if(u<=0)return 0;let s=D(Math.min(1,Math.max(0,(c-r)/R.edge)));return D(u)*(N.to+(N.fill-N.to)*s)}function ae(e,n,r){let c=(e-se(n,re))/(W-re);return c<=0?r:c>=1?0:r*(1-D(c))}function z(e,n,r,c,u=n){let s=Math.ceil(e/16),d=Math.ceil(n/16),p=Math.max(d,Math.ceil(u/16)),b=new Float32Array(s*p);for(let a=0;af).sort((a,f)=>b[a]-b[f]||a-f),m=new Float32Array(s*p).fill(1);return y.forEach((a,f)=>m[a]=v>1?f/(v-1):0),{cols:s,rows:p,dist:b,rank:m}}var ce=e=>.2126*(e>>16)+.7152*(e>>8&255)+.0722*(e&255)>127.5?.5:.42,oe="([01](?:\\\\.\\\\d{1,3})?)",Ee=new RegExp(`^#kgu=${oe},${oe},([0-9a-f]{6}),(\\\\d{13})$`);function ue(e){let n=Ee.exec(e);if(!n)return null;let r=Number(n[1]),c=Number(n[2]);return r<=1&&c<=1?{x:r,y:c,ink:parseInt(n[3],16),at:Number(n[4])}:null}var ve=4e3,Le=1e3,fe=1500,ge=150,Se="data-kgu-arrival",de=["pointerdown","wheel","touchstart"];function me(e){let n=ue(e.location.hash);if(!n)return;let{document:r,history:c,location:u,performance:s}=e;c.replaceState(c.state,"",u.href.slice(0,u.href.indexOf("#")));let d=s.now(),p=e.Date.now()-n.at,b="(prefers-reduced-motion: reduce)",v=t=>e.matchMedia(t).matches;if(!(p>-Le&&p>16} ${n.ink>>8&255} ${n.ink&255} / ${ce(n.ink)})`,x=e.performance.getEntriesByType?.("navigation")[0],pe=x&&x.responseStart>0&&x.responseStartMath.max(0,p-(d-pe)+t-d),V=t=>R.from+Math.max(0,t-d)*R.perMs,E=0,k=0,L=0,g=z(0,0,0,0),S=()=>{let{clientWidth:t,clientHeight:o}=y,l=Math.max(o,e.innerHeight||0);if(t===E&&o===k&&l===L)return;E=t,k=o,L=l;let i=Math.min(2,e.devicePixelRatio||1);m.width=Math.ceil(E*i),m.height=Math.ceil(L*i),m.style.cssText=`position:fixed;left:0;top:0;width:${E}px;height:${L}px;z-index:2147483647;pointer-events:none`,a.scale(i,i),a.fillStyle=f,g=z(E,k,n.x*E,n.y*k,L)},q=t=>{let{cols:o,dist:l}=g;a.clearRect(0,0,E,L),a.beginPath();for(let i=0;i0&&a.rect((i%o+.5)*16-h/2,(Math.floor(i/o)+.5)*16-h/2,h,h)}a.fill()},G=t=>q((o,l)=>w(B(t),g.rank[l],o,V(t))),A=null,H=null,j="largest-contentful-paint";e.PerformanceObserver?.supportedEntryTypes?.includes(j)&&(H=new e.PerformanceObserver(t=>{A=t.getEntries().at(-1).startTime,K&&C()}),H.observe({type:j,buffered:!0}));let O=!1,K=!1,Q=0,T=-1,Y=new Float32Array(0),_=!1,$=()=>{O=!0},I=e.matchMedia(b),J=()=>{I.matches&&M()},X=()=>{r.visibilityState==="hidden"&&M()},M=()=>{if(!_){_=!0,H?.disconnect();for(let t of de)e.removeEventListener(t,$,!0);e.removeEventListener("keydown",M,!0),I.removeEventListener?.("change",J),e.removeEventListener("resize",S),r.removeEventListener("visibilitychange",X),m.width=m.height=0,m.remove()}},Z=t=>{if(!_){if(T<0&&t-d>fe+1e3)return M();if(O&&T<0&&Q>1&&(S(),T=t,Y=g.dist.map((o,l)=>w(B(t),g.rank[l],o,V(t))),e.removeEventListener("resize",S)),Q++,T<0)S(),G(t);else{let o=t-T;if(o>=W)return M();q((l,i)=>ae(o,g.rank[i],Y[i]))}e.requestAnimationFrame(Z)}};S(),G(d),y.append(m),e.requestAnimationFrame(Z),e.setTimeout($,fe),e.addEventListener("resize",S);for(let t of de)e.addEventListener(t,$,{capture:!0,passive:!0});e.addEventListener("keydown",M,{capture:!0,passive:!0}),I.addEventListener?.("change",J),r.addEventListener("visibilitychange",X);let ee=new WeakSet,P=!1,te=t=>{let o=t.getBoundingClientRect();return o.width>0&&o.top0},C=()=>{if(O||_||P)return;if(!H&&A===null){if(!r.body?.innerText.trim())return void e.setTimeout(C,50);A=s.now()}if(A===null)return;let t=A+ge-s.now();if(t>0)return void e.setTimeout(C,t);let o=[...r.images].filter(F=>!F.complete&&te(F)),l=r.fonts?.status==="loading"?r.fonts.ready:null,i=l&&!ee.has(l)?l:null;if(!o.length&&!i)return $();i&&ee.add(i),P=!0;let h=()=>{P=!1,e.setTimeout(C,50)};Promise.all([i,...o.map(F=>F.decode().catch(()=>{}))]).then(h,h)},ne=()=>{if(_)return;let t=[...r.images].filter(te),o=()=>{K=!0,C()};Promise.all([r.fonts?.ready,...t.map(l=>l.decode().catch(()=>{}))]).then(o,o)};r.readyState==="loading"?r.addEventListener("DOMContentLoaded",ne,{once:!0}):ne()}me(window);})();'; // kgu-arrive diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9fbb7734..1d3e43d7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,6 +4,7 @@ import { Analytics } from "@vercel/analytics/react"; import { Providers } from "./providers"; import type { Metadata } from "next"; import { cn } from "@/lib/shadcn"; +import { KGU_ARRIVAL } from "./kgu-arrival"; const title = "Connvo – Real Conversations, Better Connections"; const description = @@ -36,6 +37,9 @@ export default function RootLayout({ }) { return ( + +