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
19 changes: 19 additions & 0 deletions public/images/keynotes/flag-gb.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
153 changes: 56 additions & 97 deletions public/images/sponsors/eafit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 22 additions & 18 deletions src/components/SponsorsSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,30 @@ export default function SponsorsSection({ copy }) {

return (
<section className="sponsors-page__sections" aria-label="Sponsors">
<div className="sponsors-page__diamond-block">
<h2 className="sponsors-page__tier-heading sponsors-page__tier-heading--diamond">
<span className="sponsors-page__tier-rule-grey" aria-hidden={true} />
<span className="sponsors-page__tier-label">{s.venueLevel}</span>
</h2>
<div className="sponsors-page__diamond-panel">
<div className="sponsors-page__diamond-grid">
{VENUE_SPONSORS.map((item) => (
<SponsorCard
key={item.key}
name={item.name}
logoSrc={item.logoSrc}
href={item.href}
variant="venue"
/>
))}
{VENUE_SPONSORS.length > 0 && (
<div className="sponsors-page__diamond-block">
<h2 className="sponsors-page__tier-heading sponsors-page__tier-heading--diamond">
<span
className="sponsors-page__tier-rule-grey"
aria-hidden={true}
/>
<span className="sponsors-page__tier-label">{s.venueLevel}</span>
</h2>
<div className="sponsors-page__diamond-panel">
<div className="sponsors-page__diamond-grid">
{VENUE_SPONSORS.map((item) => (
<SponsorCard
key={item.key}
name={item.name}
logoSrc={item.logoSrc}
href={item.href}
variant="venue"
/>
))}
</div>
</div>
</div>
</div>

)}
<div className="sponsors-page__platino">
<h2 className="sponsors-page__tier-heading sponsors-page__tier-heading--gold">
<span className="sponsors-page__tier-rule-grey" aria-hidden={true} />
Expand Down
92 changes: 90 additions & 2 deletions src/pages/LandingPage/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const KEYNOTE_FLAGS_BY_NAME = {
"Malvika Sharan": { code: "in", label: "India" },
"Dr. Kari L. Jordan": { code: "us", label: "United States" },
"Dra. Kari L. Jordan": { code: "us", label: "Estados Unidos" },
"Irit Katriel": { code: "il", label: "Israel" },
"Irit Katriel": { code: "gb", label: "United Kingdom" },
};

function keynoteFlagAssetPath(code) {
Expand Down Expand Up @@ -214,6 +214,91 @@ KeynotesRevealRow.propTypes = {
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
};

function LandingAfterMovieSection({ copy }) {
const videoId = copy?.youtubeVideoId;
const [playing, setPlaying] = useState(false);

if (!videoId) return null;

const embedSrc = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(videoId)}?autoplay=1&rel=0&modestbranding=1`;
const thumbMax = `https://i.ytimg.com/vi/${videoId}/maxresdefault.jpg`;
const thumbHq = `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;

return (
<section
className="landing-after-movie"
aria-label={copy.sectionAriaLabel ?? copy.title}
>
<Container fluid="xxl" className="landing-after-movie__container">
<header className="landing-after-movie__header">
<h2 className="landing-after-movie__title">{copy.title}</h2>
<p className="landing-after-movie__subtitle">{copy.subtitle}</p>
</header>
<div className="landing-after-movie__frame-wrap">
<div className="landing-after-movie__frame">
{playing ? (
<iframe
className="landing-after-movie__iframe"
src={embedSrc}
title={copy.title}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
) : (
<button
type="button"
className="landing-after-movie__poster"
onClick={() => setPlaying(true)}
aria-label={copy.playLabel ?? copy.title}
>
<span className="landing-after-movie__poster-bg" aria-hidden>
<img
src={thumbMax}
alt=""
className="landing-after-movie__poster-img"
onError={(e) => {
if (e.currentTarget.src !== thumbHq) {
e.currentTarget.src = thumbHq;
}
}}
/>
</span>
<span
className="landing-after-movie__poster-scrim"
aria-hidden
/>
<span className="landing-after-movie__play" aria-hidden>
<svg
className="landing-after-movie__play-icon"
viewBox="0 0 24 24"
width="28"
height="28"
fill="currentColor"
aria-hidden
>
<title>{copy.playLabel ?? copy.title}</title>
<path d="M8 5v14l11-7z" />
</svg>
</span>
</button>
)}
</div>
</div>
</Container>
</section>
);
}

LandingAfterMovieSection.propTypes = {
copy: PropTypes.shape({
sectionAriaLabel: PropTypes.string,
title: PropTypes.string,
subtitle: PropTypes.string,
playLabel: PropTypes.string,
youtubeVideoId: PropTypes.string,
}),
};

const LandingPage = ({ dataTranslate }) => {
const h = dataTranslate?.landing?.hero ?? {};
const topicRows = dataTranslate?.landing?.topics?.rows ?? DEFAULT_TOPIC_ROWS;
Expand All @@ -224,6 +309,7 @@ const LandingPage = ({ dataTranslate }) => {
cfpPage.submitProposalHref ?? DEFAULT_CFP_HERO.submitProposalHref,
...cfpPage.hero,
};
const afterMovie = dataTranslate?.landing?.afterMovie;
const keynotes = dataTranslate?.landing?.keynotes;
const keynoteColumnsRaw = keynotes?.columns ?? keynotes?.rows ?? [];
const keynoteColumns = [...keynoteColumnsRaw].sort((a, b) =>
Expand Down Expand Up @@ -337,13 +423,15 @@ const LandingPage = ({ dataTranslate }) => {
</Container>
</section>

{afterMovie ? <LandingAfterMovieSection copy={afterMovie} /> : null}

<section aria-label={`${cfpHero.titleBefore} ${cfpHero.titleAccent}`}>
<Container fluid="xxl">
<header className="cfp-hero coc-page__hero--tracked">
<div className="cfp-hero__glow" aria-hidden>
<span className="cfp-hero__glow-blob" />
</div>
<Row className="cfp-hero__row align-items-center g-5 g-lg-0">
<Row className="cfp-hero__row align-items-center gx-0 gy-5 g-lg-0">
<Col lg={7}>
<div className="cfp-hero__badge">
<span className="cfp-hero__pulse" aria-hidden />
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Sponsors/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const Sponsors = ({ dataTranslate }) => {
<p className="sponsors-page__lead">{s.heroLead}</p>
</div>
<div className="sponsors-page__hero-cta-wrap">
<a className="sponsors-page__cta" href={sponsorMailto}>
<a className="cfp-btn cfp-btn--primary" href={sponsorMailto}>
{s.becomeSponsorCta}
<ArrowOutwardIcon />
</a>
Expand Down
147 changes: 141 additions & 6 deletions src/styles/landing.scss
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,141 @@
}
}

/* After movie — YouTube embed with poster + play control */
.landing-after-movie {
padding: clamp(2.5rem, 6vw, 4rem) clamp(1rem, 3vw, 1.5rem);
background: #f7f8fc;
}

.landing-after-movie__container {
max-width: 1320px;
margin: 0 auto;
}

.landing-after-movie__header {
text-align: center;
max-width: 40rem;
margin: 0 auto clamp(1.75rem, 4vw, 2.75rem);
}

.landing-after-movie__title {
margin: 0;
font-family: 'Maven Pro', 'Nunito', sans-serif;
font-size: clamp(1.75rem, 4vw, 2.5rem);
font-weight: 600;
line-height: 1.15;
letter-spacing: 0.04em;
color: #0a0a0a;
}

.landing-after-movie__subtitle {
margin: 0.85rem 0 0;
font-family: 'Geist', system-ui, sans-serif;
font-size: clamp(0.95rem, 1.35vw, 1.08rem);
font-weight: 500;
line-height: 1.5;
color: #5c5f78;
}

.landing-after-movie__frame-wrap {
max-width: min(960px, 100%);
margin: 0 auto;
}

.landing-after-movie__frame {
position: relative;
width: 100%;
aspect-ratio: 16 / 9;
border-radius: clamp(18px, 3vw, 28px);
overflow: hidden;
background: #e8e9f4;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08);
}

.landing-after-movie__iframe {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
border: 0;
}

.landing-after-movie__poster {
position: absolute;
inset: 0;
display: block;
width: 100%;
height: 100%;
padding: 0;
border: none;
cursor: pointer;
background: #1a1a24;
}

.landing-after-movie__poster:focus-visible {
outline: 3px solid #6155f5;
outline-offset: 4px;
}

.landing-after-movie__poster-bg {
position: absolute;
inset: -12px;
overflow: hidden;
}

.landing-after-movie__poster-img {
width: 100%;
height: 100%;
object-fit: cover;
filter: grayscale(1) blur(10px);
transform: scale(1.04);
opacity: 0.92;
}

.landing-after-movie__poster-scrim {
position: absolute;
inset: 0;
background: rgba(255, 255, 255, 0.12);
}

.landing-after-movie__play {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
width: clamp(4rem, 12vw, 5.25rem);
height: clamp(4rem, 12vw, 5.25rem);
border-radius: 50%;
background: #f4f4fd;
color: #4b41c4;
box-shadow:
0 4px 24px rgba(0, 0, 0, 0.18),
0 1px 3px rgba(0, 0, 0, 0.08);
transition:
transform 0.2s ease,
box-shadow 0.2s ease;
}

.landing-after-movie__poster:hover .landing-after-movie__play {
transform: translate(-50%, -50%) scale(1.04);
box-shadow:
0 8px 32px rgba(75, 65, 196, 0.25),
0 2px 8px rgba(0, 0, 0, 0.1);
}

.landing-after-movie__play-icon {
margin-left: 4px;
}

@media (prefers-reduced-motion: reduce) {
.landing-after-movie__poster:hover .landing-after-movie__play {
transform: translate(-50%, -50%);
}
}

/* Keynotes — frame 2059:353 */
.landing-keynotes {
position: relative;
Expand Down Expand Up @@ -645,7 +780,8 @@

.landing-gallery__viewport {
overflow: hidden;
padding: 0.5rem 0;
/* Vertical room so slide hover (translateY + shadow) is not clipped */
padding: 1rem 0;
}

.landing-gallery__track {
Expand Down Expand Up @@ -1370,15 +1506,14 @@
position: relative;
margin-bottom: clamp(2rem, 5vw, 3.5rem);
padding-bottom: clamp(1rem, 3vw, 2rem);
overflow: hidden;
/* Allow hover scale / shadows on .cfp-btn to paint outside the box */
overflow: visible;
}

.cfp-hero__glow {
position: absolute;
top: 0;
right: 0;
width: 66%;
height: 100%;
inset: 0;
overflow: hidden;
pointer-events: none;
z-index: 0;
opacity: 0.35;
Expand Down
Loading
Loading