Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 303 additions & 21 deletions README.md

Large diffs are not rendered by default.

31 changes: 26 additions & 5 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,11 @@ body::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9999;o
.hero-cta:active{transform:translateY(1px)}
/* Stacked screens (portrait, or narrower than 720px): the kicker, title and subtitle fit inside the disc, the buttons
sit on the paper below it, the astronaut drifts off the disc's upper right and the storm planet tucks into the
bottom-left corner. The disc + buttons group is centred between the top HUD bar (72px) and a 24px bottom margin. */
bottom-left corner. The fest dates head the column, centred just above the disc: in the top-right corner they met
the astronaut whenever the screen was short for its width. The dates band (--dh) + disc + buttons group is centred
between the top HUD bar (72px) and a 24px bottom margin. */
@media (max-aspect-ratio:1/1),(max-width:719px) and (min-height:520px){
.hero{--cta-h:48px;--ctas:var(--cta-h);--d:min(80vw,100vh - 220px,640px);--cy:calc(50% + 12px - var(--ctas) / 2)}
.hero{--cta-h:48px;--ctas:var(--cta-h);--dh:102px;--d:min(80vw,100vh - 220px - var(--dh),640px);--cy:calc(50% + 12px - var(--ctas) / 2 + var(--dh) / 2)}
.hero-copy{top:calc(var(--cy) - var(--d) / 2);bottom:auto;justify-content:flex-start;padding:0 16px}
.hero-copy-disc{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:none;height:var(--d)}
/* .hero-copy starts at the disc's top edge here. */
Expand All @@ -198,19 +200,22 @@ body::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9999;o
.hero-cta-secondary.hv-gold:hover{color:#8a6a2a !important}
.hero-astro{top:calc(var(--cy) - var(--d) * .56);bottom:auto;right:max(4px,50% - var(--d) * .62);width:calc(var(--d) * .36);height:calc(var(--d) * .36)}
.hero-planet{--p:min(60vw,38vh);left:calc(var(--p) * -.32);bottom:calc(var(--p) * -.62);width:var(--p);height:var(--p)}
.hero-date{top:90px;right:clamp(18px,5vw,36px);min-width:0;padding:10px 0 8px 12px}
/* Bottom edge 12px above the disc's top, centred over it; --dh leaves room for it under the HUD. */
.hero-date{top:auto;bottom:calc(100% - var(--cy) + var(--d) / 2 + 12px);right:auto;left:50%;translate:-50% 0;align-items:center;min-width:0;padding:10px 14px 8px;text-align:center}
.hero-date-range{font-size:34px}
.hero-coords{display:none}
}
/* Phones: the buttons stack full width, so the disc gives up the extra height. */
@media (max-width:459px) and (min-height:520px){
.hero{--cta-h:46px;--ctas:calc(var(--cta-h) * 2 + 10px);--d:min(86vw,100vh - 270px)}
.hero{--cta-h:46px;--ctas:calc(var(--cta-h) * 2 + 10px);--dh:90px;--d:min(86vw,100vh - 270px - var(--dh))}
/* The centred dates reach over the astronaut's side of the disc here, so it starts just inside the disc's top edge:
even at the top of its 22px bob it stays clear of the dates (whose bottom is 12px above the disc). */
.hero-astro{top:calc(var(--cy) - var(--d) / 2 + 12px)}
.hero-ctas{flex-direction:column;align-items:stretch;width:min(100%,300px)}
.hero-cta{width:100%}
.hero-sub-rule{display:none}
}
@media (max-width:459px){
.hero-date{top:82px;right:18px}
.hero-date-label,.hero-date-foot{font-size:8px;letter-spacing:.16em}
.hero-date-range{font-size:29px;gap:7px}
.hero-date-dash{width:15px}
Expand Down Expand Up @@ -297,6 +302,22 @@ body::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9999;o
.td-tagline{top:44%}
}

/* ---------- Flagship Events (takeoff) scene (DetailView.tsx) ---------- */
/* Wide: the ringed planet centred behind the title, the rocket off to its right. */
.to-planet{--s:max(47vw,60vh);position:absolute;left:calc(50% - var(--s) / 2);top:calc(77% - var(--s) * 1.329);width:var(--s);pointer-events:none}
.to-rocket{position:absolute;right:max(9%,40px);top:17%;height:min(30vh,290px);pointer-events:none}
/* Portrait phones and tablets (the compact layout, with the tagline over the scene): one column has no room for the
wide layout, where the planet overflows the screen and the rocket sits on its rings over the title. The planet
shrinks to the upper left, the rocket gets the open sky on the right, and the tagline takes the open floor under the
lander instead of the middle of the screen, where the lander ends its climb (see Innovision#setupDetailScroll). */
@media (orientation:portrait) and (max-width:1099px){
/* --s: the planet's size. Its art (110% wide, 4% down) ends 1.14 --s below its top: just above the title at 43%. */
.to-planet,.to-rocket{--s:min(70vw,40vh)}
.to-planet{left:-8vw;top:calc(43% - var(--s) * 1.14)}
.to-rocket{right:5vw;top:calc(43% - var(--s) * .6 - min(9.5vh,85px));height:min(19vh,170px)}
.to-tagline{top:74%}
}

/* ---------- worlds slider decoration (WorldsView.tsx) ---------- */
@media (max-width:719px){.wv-deco-wide{display:none}}

Expand Down
6 changes: 3 additions & 3 deletions src/components/innovision/DetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ export default function DetailView({ v }: { v: V }) {
<div data-speed="-0.012" style={{ position: "absolute", inset: "0", pointerEvents: "none" }}>
<OrbitBackdrop top="30%" />
</div>
<div data-speed="-0.14" style={{ position: "absolute", left: "calc(50% - max(47vw, 60vh) / 2)", top: "calc(77% - max(47vw, 60vh) * 1.329)", width: "max(47vw, 60vh)", pointerEvents: "none" }}>
<div data-speed="-0.14" className="to-planet">
<div data-depth=".25" style={{ position: "relative", width: "110%", margin: "4% 0 0 -5%", aspectRatio: "1" }}>
<img decoding="async" src="/assets/planet-ringed.webp" alt="" style={{ width: "100%", height: "100%", transform: "rotate(6deg)", filter: MONO, animation: "iv-drift 9s ease-in-out infinite" }} />
</div>
</div>
<div data-speed="-0.22" aria-hidden="true" style={{ position: "absolute", right: "max(9%, 40px)", top: "17%", height: "min(30vh, 290px)", pointerEvents: "none" }}>
<div data-speed="-0.22" aria-hidden="true" className="to-rocket">
<div data-depth=".45" style={{ height: "100%" }}>
<div style={{ height: "100%", transform: "rotate(16deg)" }}>
<img decoding="async" src="/assets/rocket.svg" alt="" style={{ height: "100%", width: "auto", filter: MONO + " drop-shadow(0 18px 24px rgba(0,0,0,.2))", animation: "iv-drift 6s ease-in-out infinite" }} />
Expand Down Expand Up @@ -326,7 +326,7 @@ export default function DetailView({ v }: { v: V }) {

{/* ---- copy ---- */}
{v.compact && (
<h2 className={v.isHighpoint ? "hp-tagline" : v.isTouchdown ? "d-tagline td-tagline" : "d-tagline"} style={{ position: "absolute", left: "0", right: "0", width: v.taglineW, margin: "0 auto", fontFamily: "var(--font-display)", fontWeight: "400", fontSize: "clamp(26px,3.1vw,56px)", lineHeight: "1.04", textAlign: "center", color: "#fff", mixBlendMode: "difference", pointerEvents: "none" }}>
<h2 className={v.isHighpoint ? "hp-tagline" : v.isTouchdown ? "d-tagline td-tagline" : v.isTakeoff ? "d-tagline to-tagline" : "d-tagline"} style={{ position: "absolute", left: "0", right: "0", width: v.taglineW, margin: "0 auto", fontFamily: "var(--font-display)", fontWeight: "400", fontSize: "clamp(26px,3.1vw,56px)", lineHeight: "1.04", textAlign: "center", color: "#fff", mixBlendMode: "difference", pointerEvents: "none" }}>
{cw.words.map((wd, wdI) => (
<span key={wdI} data-d-word="" style={{ display: "inline-block", margin: "0 .14em" }}>{wd.t}</span>
))}
Expand Down
61 changes: 34 additions & 27 deletions src/components/innovision/HomeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export default function HomeView({ v }: { v: V }) {
<figure key={gI} data-t-frame="" style={{ position: "absolute", left: `calc(50% + ${g.x})`, top: `calc(50% + ${g.y})`, width: "clamp(220px,30vw,460px)", margin: "0", transform: "translate(-50%,-50%) translate3d(0,0,-6000px)", willChange: "transform,opacity" }}>
<div style={{ position: "relative", aspectRatio: g.ar, background: "#1b1a18", border: "1px solid rgba(236,232,223,.18)", overflow: "hidden" }}>
{g.imageUrl ? (
<img decoding="async" src={g.imageUrl} alt={g.capU} style={{ position: "absolute", inset: "0", width: "100%", height: "100%", objectFit: "cover" }} />
<img decoding="async" src={g.imageUrl} alt={g.ph} style={{ position: "absolute", inset: "0", width: "100%", height: "100%", objectFit: "cover" }} />
) : (
<ImageSlot id={g.id} shape="rect" placeholder={g.ph} style={{ position: "absolute", inset: "0", width: "100%", height: "100%" }} />
)}
Expand All @@ -203,9 +203,14 @@ export default function HomeView({ v }: { v: V }) {
<h2 style={{ margin: "0 0 14px", fontFamily: "var(--font-display)", fontWeight: "400", fontSize: "clamp(34px,4.4vw,68px)", lineHeight: "1" }}>Into the archive</h2>
<p style={{ margin: "0", fontSize: "16px", lineHeight: "1.6", color: "rgba(236,232,223,.82)", textWrap: "pretty" }}>Keep scrolling to fly through moments from Innovision past.</p>
</header>
<div style={{ position: "absolute", left: "clamp(20px,4vw,64px)", bottom: "calc(clamp(16px,2.6vw,44px) + 64px)", display: "flex", alignItems: "baseline", gap: "10px", fontFamily: "var(--font-display)", fontWeight: "400", pointerEvents: "none" }}>
<span data-t-count="" style={{ fontSize: "clamp(36px,4vw,60px)", lineHeight: "1" }}>01</span>
<span style={{ fontSize: "18px", color: "rgba(236,232,223,.7)" }}>/ {v.tunnelTotal}</span>
<div style={{ position: "absolute", left: "clamp(20px,4vw,64px)", right: "clamp(20px,4vw,64px)", bottom: "calc(clamp(16px,2.6vw,44px) + 64px)", display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: "16px", pointerEvents: "none" }}>
<div style={{ display: "flex", alignItems: "baseline", gap: "10px", fontFamily: "var(--font-display)", fontWeight: "400" }}>
<span data-t-count="" style={{ fontSize: "clamp(36px,4vw,60px)", lineHeight: "1" }}>01</span>
<span style={{ fontSize: "18px", color: "rgba(236,232,223,.7)" }}>/ {v.tunnelTotal}</span>
</div>
<a href="#/gallery" onMouseEnter={v.hover} style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: "0", padding: "15px 26px", textDecoration: "none", fontWeight: "700", fontSize: "14px", letterSpacing: ".06em", whiteSpace: "nowrap", clipPath: "polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)", transition: "background-color .4s cubic-bezier(.25,1,.1,1)", color: "#141312", background: "#ECE8DF", pointerEvents: "auto" }} className="hv-gold-fill">
<span data-scr="">VIEW FULL GALLERY</span>
</a>
</div>
</div>
</section>
Expand Down Expand Up @@ -250,32 +255,34 @@ export default function HomeView({ v }: { v: V }) {
</div>
</div>
</section>
<section data-launch-sec="" style={{ position: "relative", overflow: "hidden", padding: "clamp(110px,18vh,200px) clamp(20px,4vw,64px) clamp(260px,40vh,420px)", textAlign: "center", background: "#ECE8DF" }}>
<div aria-hidden="true" style={{ position: "absolute", left: "50%", top: "100%", width: "220vmax", height: "220vmax", margin: "-110vmax 0 0 -110vmax", borderRadius: "50%", background: "repeating-conic-gradient(from 0deg,rgba(20,19,18,.09) 0deg .5deg,transparent .5deg 5deg)", WebkitMaskImage: "radial-gradient(circle,transparent 22%,#000 28%,transparent 52%)", maskImage: "radial-gradient(circle,transparent 22%,#000 28%,transparent 52%)", pointerEvents: "none" }}></div>
<div aria-hidden="true" style={{ position: "absolute", left: "50%", bottom: "calc(min(130vw, 1700px) * -.8)", width: "min(130vw, 1700px)", aspectRatio: "1", marginLeft: "calc(min(130vw, 1700px) / -2)", pointerEvents: "none" }}>
<img decoding="async" data-spin="480" src="/assets/planet-mercury.webp" alt="" style={{ width: "100%", height: "100%", filter: "grayscale(1) contrast(1.35) brightness(1.05)" }} />
</div>
<div data-launch="" aria-hidden="true" style={{ position: "absolute", right: "clamp(20px,11vw,220px)", bottom: "16%", display: "flex", flexDirection: "column", alignItems: "center", pointerEvents: "none" }}>
<img decoding="async" src="/assets/rocket.svg" alt="" style={{ height: "min(34vh, 320px)", width: "auto", filter: "grayscale(1) contrast(1.35) brightness(1.05) drop-shadow(0 18px 24px rgba(0,0,0,.2))" }} />
<span style={{ width: "3.6vh", height: "8vh", marginTop: "-1.4vh", borderRadius: "45% 45% 50% 50% / 20% 20% 80% 80%", background: "radial-gradient(ellipse 50% 100% at 50% 0,#fff,rgba(255,244,230,.75) 45%,transparent 100%)", transformOrigin: "50% 0", animation: "iv-flame .16s ease-in-out infinite alternate" }}></span>
<span style={{ width: "2px", height: "70vh", background: "repeating-linear-gradient(180deg,rgba(20,19,18,.45) 0 8px,transparent 8px 18px)" }}></span>
</div>
<div data-reveal="" style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center" }}>
<h2 style={{ margin: "0 0 22px", fontFamily: "var(--font-display)", fontWeight: "400", fontSize: "clamp(48px,8.4vw,150px)", lineHeight: ".95", letterSpacing: "-.01em" }}>The odyssey<br />awaits.</h2>
<p style={{ margin: "0 auto 36px", maxWidth: "520px", fontSize: "18px", lineHeight: "1.6", color: "#3a3733", textWrap: "pretty" }}>Innovision 2026 is boarding soon at NIT Rourkela. Claim your seat on the voyage.</p>
<div className="cta-pair" style={{ display: "flex", gap: "14px", flexWrap: "wrap", justifyContent: "center" }}>
{/* The footer slides up over the closing section: the section is sticky (its top is set by Innovision#homeScroll so it
pins once its bottom reaches the bottom of the screen) across the 40vh spacer below it, and the wrapper's negative
margin lets the footer overlap that spacer. Sticky runs with the browser's own scrolling, so it stays smooth on
touch screens, unlike a scroll-scrubbed transform. */}
<div style={{ marginBottom: "-40vh" }}>
<section data-launch-sec="" style={{ position: "sticky", top: "0", overflow: "hidden", padding: "clamp(110px,18vh,200px) clamp(20px,4vw,64px) clamp(260px,40vh,420px)", textAlign: "center", background: "#ECE8DF" }}>
<div aria-hidden="true" style={{ position: "absolute", left: "50%", top: "100%", width: "220vmax", height: "220vmax", margin: "-110vmax 0 0 -110vmax", borderRadius: "50%", background: "repeating-conic-gradient(from 0deg,rgba(20,19,18,.09) 0deg .5deg,transparent .5deg 5deg)", WebkitMaskImage: "radial-gradient(circle,transparent 22%,#000 28%,transparent 52%)", maskImage: "radial-gradient(circle,transparent 22%,#000 28%,transparent 52%)", pointerEvents: "none" }}></div>
<div aria-hidden="true" style={{ position: "absolute", left: "50%", bottom: "calc(min(130vw, 1700px) * -.8)", width: "min(130vw, 1700px)", aspectRatio: "1", marginLeft: "calc(min(130vw, 1700px) / -2)", pointerEvents: "none" }}>
<img decoding="async" data-spin="480" src="/assets/planet-mercury.webp" alt="" style={{ width: "100%", height: "100%", filter: "grayscale(1) contrast(1.35) brightness(1.05)" }} />
</div>
<div data-reveal="" style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center" }}>
<h2 style={{ margin: "0 0 22px", fontFamily: "var(--font-display)", fontWeight: "400", fontSize: "clamp(48px,8.4vw,150px)", lineHeight: ".95", letterSpacing: "-.01em" }}>The odyssey<br />awaits.</h2>
<p style={{ margin: "0 auto 36px", maxWidth: "520px", fontSize: "18px", lineHeight: "1.6", color: "#3a3733", textWrap: "pretty" }}>Innovision 2026 is boarding soon at NIT Rourkela. Claim your seat on the voyage.</p>
<div className="cta-pair" style={{ display: "flex", gap: "14px", flexWrap: "wrap", justifyContent: "center" }}>

<a href={v.noUser || !v.hasRegistered ? "#register" : "#pass"} onClick={v.register} onMouseEnter={v.hover} style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: "168px", padding: "17px 30px", textDecoration: "none", fontWeight: "700", fontSize: "15px", letterSpacing: ".06em", color: "#ECE8DF", background: "#141312", clipPath: "polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)", transition: "background-color .4s cubic-bezier(.25,1,.1,1)" }} className="hv-bronze-fill">
<span data-scr="">{v.noUser || !v.hasRegistered ? "REGISTER" : "MY PASS"}</span>
<a href={v.noUser || !v.hasRegistered ? "#register" : "#pass"} onClick={v.register} onMouseEnter={v.hover} style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: "168px", padding: "17px 30px", textDecoration: "none", fontWeight: "700", fontSize: "15px", letterSpacing: ".06em", color: "#ECE8DF", background: "#141312", clipPath: "polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)", transition: "background-color .4s cubic-bezier(.25,1,.1,1)" }} className="hv-bronze-fill">
<span data-scr="">{v.noUser || !v.hasRegistered ? "REGISTER" : "MY PASS"}</span>

</a>
<a href="#/worlds/flagship-events" onMouseEnter={v.hover} style={{ position: "relative", isolation: "isolate", display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: "168px", padding: "17px 30px", textDecoration: "none", fontWeight: "700", fontSize: "15px", letterSpacing: ".06em", color: "#141312", background: "#141312", clipPath: "polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)" }} className="hv-bronze">
<span style={{ position: "absolute", inset: "1.5px", zIndex: "-1", background: "#ECE8DF", clipPath: "polygon(11px 0,100% 0,100% calc(100% - 11px),calc(100% - 11px) 100%,0 100%,0 11px)" }}></span>
<span data-scr="">EXPLORE THE WORLDS</span>
</a>
</a>
<a href="#/worlds/flagship-events" onMouseEnter={v.hover} style={{ position: "relative", isolation: "isolate", display: "inline-flex", alignItems: "center", justifyContent: "center", minWidth: "168px", padding: "17px 30px", textDecoration: "none", fontWeight: "700", fontSize: "15px", letterSpacing: ".06em", color: "#141312", background: "#141312", clipPath: "polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px)" }} className="hv-bronze">
<span style={{ position: "absolute", inset: "1.5px", zIndex: "-1", background: "#ECE8DF", clipPath: "polygon(11px 0,100% 0,100% calc(100% - 11px),calc(100% - 11px) 100%,0 100%,0 11px)" }}></span>
<span data-scr="">EXPLORE THE WORLDS</span>
</a>
</div>
</div>
</div>
</section>
</section>
<div aria-hidden="true" style={{ height: "40vh" }}></div>
</div>
<LiveFooter />
</main>
);
Expand Down
Loading
Loading