diff --git a/src/app/events/[world]/page.tsx b/src/app/events/[world]/page.tsx index ba62e12..d73f78c 100644 --- a/src/app/events/[world]/page.tsx +++ b/src/app/events/[world]/page.tsx @@ -95,7 +95,7 @@ export default async function WorldPage({ params }: PageProps<'/events/[world]'>

{w.intro}

ENTER THE WORLD - ALL EVENTS + ALL EVENTS
@@ -123,7 +123,7 @@ export default async function WorldPage({ params }: PageProps<'/events/[world]'>

NEXT WORLD · {next.statL.toUpperCase()}

-

{next.name} →

+

{next.name} →

diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index 0134f8b..c082c9e 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -47,7 +47,7 @@ export default async function EventsPage() {

EXPLORE THE WORLDS - BACK TO INNOVISION + BACK TO INNOVISION
@@ -59,7 +59,7 @@ export default async function EventsPage() { {worlds.map(({ w, list }) => (

{w.statL.toUpperCase()} · {w.category.toUpperCase()}

-

{w.name}

+

{w.name}

{w.tagline}

{w.intro}

{list.length > 0 ? ( @@ -73,7 +73,7 @@ export default async function EventsPage() {

LINE-UP ANNOUNCED SOON

)}
- {w.name.toUpperCase()} → + {w.name.toUpperCase()} → ENTER THE WORLD
diff --git a/src/components/events/EventsChrome.tsx b/src/components/events/EventsChrome.tsx index e4bcc89..fa21aa3 100644 --- a/src/components/events/EventsChrome.tsx +++ b/src/components/events/EventsChrome.tsx @@ -10,6 +10,8 @@ import styles from './EventsPage.module.css'; * BreadcrumbList JSON-LD describes, and a footer linking every world page. Server-rendered, no client JS. * Links into the animated explorer (/#/...) are plain , not : the explorer reads its hash route once its * loader finishes, and a full page load is what keeps that hash (as for a visitor arriving from search). + * Every here (and on the /events pages) has prefetch={false}: by default each one in the viewport costs uncached + * RSC requests on Vercel (3 to 5 per page view were measured). A click still navigates client-side, fetching then. * * @param trail [name, path] from the home page down to this page; the last entry is the current page. */ @@ -19,7 +21,7 @@ export default function EventsChrome({ trail, children }: { trail: [string, stri
- + INNOVISION @@ -27,7 +29,7 @@ export default function EventsChrome({ trail, children }: { trail: [string, stri
    {trail.map(([name, path], i) => (
  1. - {i === trail.length - 1 ? {name} : {name}} + {i === trail.length - 1 ? {name} : {name}}
  2. ))}
@@ -38,19 +40,19 @@ export default function EventsChrome({ trail, children }: { trail: [string, stri

© 2026 Innovision · NIT Rourkela, Odisha

diff --git a/src/components/innovision/Innovision.tsx b/src/components/innovision/Innovision.tsx index a1a7c6c..f7bc65e 100644 --- a/src/components/innovision/Innovision.tsx +++ b/src/components/innovision/Innovision.tsx @@ -728,8 +728,10 @@ export class Innovision extends Component { this._warmed = true; if (slowNet()) return; // The overlay and view a visitor is most likely to open next are fetched ahead too (their own hover/tap also does). - // The pages of their own too, so MERCH (and REGISTER while closed) open at once (a no-op on the dev server). - this.cleanups.push(this.idle(() => { this.prefetch('auth'); this.prefetch('detail'); OWN_PAGES.forEach((p) => this.props.router?.prefetch(p)); })); + // The pages of their own (OWN_PAGES: MERCH, REGISTER while closed) are NOT prefetched: each router.prefetch cost 3 + // uncached RSC requests on every home page view, for a page few visitors open. A click on one still switches + // client-side (the document click listener in componentDidMount), fetching the route then. + this.cleanups.push(this.idle(() => { this.prefetch('auth'); this.prefetch('detail'); })); // The menu (where the top bar has a MENU button) and the register / log-in overlay are mounted, closed, ahead of // time: mounting one on its first tap blocked a phone for ~100 ms just as its reveal began. One per idle period. this.cleanups.push(this.idle(() => { @@ -2947,8 +2949,10 @@ export class Innovision extends Component { authSub: reg ? 'Three short stops to register for Innovision 2026 at NIT Rourkela.' : am === 'login' ? 'Sign in or create your account with Google.' : P.status === 'CONFIRMED' ? 'Your payment is verified. Your INNO pass is always available here.' : P.status === 'REJECTED' ? (this.canRegisterAgain() ? 'See why below, then register again with the right details.' : 'Please contact the registration helpdesk for assistance.') : 'Your payment is under review by the registration team. Your pass appears here after approval.', - // The seat counter (GET /api/seats) beside the registration form. - showSeats: reg, + // The seat counter (GET /api/seats) beside the registration form. Only while the overlay is open: it is mounted, + // closed, at idle (warmDeferred), and a mounted counter polls every 30 s. `auth` turns true before the overlay + // animates in and false after it has animated out, so the counter is never cut off mid-animation. + showSeats: reg && s.auth, // REGISTER AGAIN on a rejected pass; the pass itself decides whether to show it (attempts left). registerAgain: REGISTRATIONS_OPEN ? this.registerAgain : undefined, idCardUploaded: this.idCardUploaded,