Files
Greenlens/greenlens-promo/index.html
2026-04-27 22:23:33 +02:00

759 lines
23 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=1920, height=1080" />
<title>GreenLens Product Promo</title>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Playfair+Display:ital,wght@0,700;0,900;1,700;1,900&display=block"
rel="stylesheet"
/>
<style>
:root {
--forest: #131f16;
--forest-alt: #1c2e21;
--green: #2a5c3f;
--green-mid: #3d7a56;
--green-light: #56a074;
--coral: #e07a50;
--coral-dark: #c96840;
--cream: #f4f1e8;
--cream-alt: #eae6d8;
--muted-sage: #7a8c7d;
--display: "Playfair Display", Georgia, serif;
--body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
* {
box-sizing: border-box;
}
html,
body {
width: 1920px;
height: 1080px;
margin: 0;
overflow: hidden;
background: var(--forest);
color: var(--cream);
font-family: var(--body);
}
[data-composition-id="greenlens-promo"] {
position: relative;
width: 1920px;
height: 1080px;
overflow: hidden;
isolation: isolate;
background: var(--forest);
}
.scene {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
overflow: hidden;
opacity: 0;
}
.scene-content {
position: relative;
z-index: 3;
width: 100%;
height: 100%;
display: flex;
box-sizing: border-box;
}
.brand {
display: flex;
align-items: center;
gap: 16px;
font-family: var(--display);
font-weight: 900;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.brand img {
width: 48px;
height: 48px;
}
.brand-mark {
width: 48px;
height: 48px;
border-radius: 999px;
background:
radial-gradient(circle at 52% 38%, var(--green-light), transparent 34%),
var(--green);
box-shadow: inset 0 0 0 2px rgba(244, 241, 232, 0.24), 0 0 34px rgba(86, 160, 116, 0.36);
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 12px;
color: var(--coral);
font-size: 18px;
font-weight: 800;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.eyebrow::before {
content: "";
width: 10px;
height: 10px;
border-radius: 999px;
background: var(--green-light);
box-shadow: 0 0 28px rgba(86, 160, 116, 0.9);
}
h1,
h2 {
margin: 0;
font-family: var(--display);
font-weight: 900;
line-height: 0.96;
}
h1 {
font-size: 124px;
max-width: 880px;
}
h2 {
font-size: 92px;
}
em {
color: var(--green-light);
font-style: italic;
}
p {
margin: 0;
}
.caption {
font-size: 34px;
line-height: 1.35;
color: rgba(244, 241, 232, 0.76);
max-width: 680px;
}
.glass {
border: 1px solid rgba(244, 241, 232, 0.14);
background: rgba(19, 31, 22, 0.72);
box-shadow: 0 30px 110px rgba(0, 0, 0, 0.34);
backdrop-filter: blur(18px);
}
.image-fill {
width: 100%;
height: 100%;
object-fit: cover;
}
.scene-1 {
background: var(--forest);
}
.hero-bg {
position: absolute;
inset: 0;
z-index: 0;
}
.hero-bg img {
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0.9;
}
.hero-overlay {
position: absolute;
inset: 0;
z-index: 1;
background:
radial-gradient(circle at 72% 42%, rgba(86, 160, 116, 0.36), transparent 32%),
linear-gradient(90deg, rgba(19, 31, 22, 0.96), rgba(19, 31, 22, 0.72) 46%, rgba(19, 31, 22, 0.2));
}
.scan-line {
position: absolute;
z-index: 2;
left: 0;
right: 0;
top: 0;
height: 3px;
background: linear-gradient(90deg, transparent, var(--green-light), transparent);
box-shadow: 0 0 42px rgba(86, 160, 116, 0.88);
opacity: 0.8;
}
.particle {
position: absolute;
z-index: 2;
width: 10px;
height: 22px;
border-radius: 999px 0 999px 0;
background: rgba(244, 241, 232, 0.22);
}
.scene-1 .scene-content {
flex-direction: column;
justify-content: center;
gap: 34px;
padding: 96px 120px 110px;
}
.scene-1 .brand {
position: absolute;
top: 72px;
left: 120px;
}
.scene-2 .scene-content {
align-items: center;
justify-content: space-between;
gap: 80px;
padding: 86px 128px;
background:
radial-gradient(circle at 30% 20%, rgba(86, 160, 116, 0.22), transparent 26%),
var(--forest);
}
.copy-stack {
width: 680px;
display: flex;
flex-direction: column;
gap: 28px;
}
.phone-stage {
position: relative;
width: 780px;
height: 820px;
display: flex;
align-items: center;
justify-content: center;
}
.botanical-plate {
position: absolute;
width: 620px;
height: 720px;
border-radius: 42px;
overflow: hidden;
opacity: 0.45;
border: 1px solid rgba(244, 241, 232, 0.15);
}
.phone-frame {
position: relative;
z-index: 2;
width: 420px;
height: 744px;
border-radius: 48px;
padding: 18px;
background: #0d130f;
border: 2px solid rgba(244, 241, 232, 0.22);
box-shadow: 0 42px 110px rgba(0, 0, 0, 0.44);
overflow: hidden;
}
.phone-frame video {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 34px;
}
.scan-bracket {
position: absolute;
z-index: 3;
width: 108px;
height: 108px;
border-color: var(--green-light);
opacity: 0.9;
}
.scan-bracket.tl {
top: 112px;
left: 120px;
border-top: 5px solid;
border-left: 5px solid;
}
.scan-bracket.br {
right: 120px;
bottom: 112px;
border-right: 5px solid;
border-bottom: 5px solid;
}
.badge {
display: inline-flex;
align-items: center;
gap: 12px;
width: fit-content;
padding: 12px 18px;
border-radius: 999px;
color: var(--cream);
font-size: 18px;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
border: 1px solid rgba(86, 160, 116, 0.45);
background: rgba(42, 92, 63, 0.42);
}
.badge::before {
content: "";
width: 12px;
height: 12px;
border-radius: 999px;
background: var(--green-light);
}
.result-card {
position: absolute;
z-index: 4;
right: 26px;
bottom: 156px;
width: 318px;
padding: 24px;
border-radius: 24px;
}
.result-card strong {
display: block;
font-family: var(--display);
font-size: 34px;
line-height: 1;
}
.result-card span {
display: block;
margin-top: 8px;
color: rgba(244, 241, 232, 0.68);
font-size: 20px;
}
.scene-3 .scene-content {
align-items: center;
gap: 74px;
padding: 82px 120px;
background:
radial-gradient(circle at 74% 48%, rgba(224, 122, 80, 0.18), transparent 26%),
var(--forest-alt);
}
.analysis-frame {
width: 820px;
height: 760px;
border-radius: 38px;
overflow: hidden;
position: relative;
}
.analysis-frame img {
width: 100%;
height: 100%;
object-fit: cover;
}
.analysis-frame::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, transparent, rgba(19, 31, 22, 0.64));
}
.care-grid {
display: grid;
grid-template-columns: 1fr;
gap: 18px;
width: 540px;
}
.care-card {
display: flex;
align-items: center;
gap: 20px;
min-height: 122px;
padding: 26px;
border-radius: 24px;
}
.care-icon {
width: 58px;
height: 58px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 18px;
color: var(--forest);
background: var(--green-light);
font-size: 30px;
font-weight: 900;
}
.care-card strong {
display: block;
font-size: 28px;
}
.care-card span {
display: block;
margin-top: 6px;
color: rgba(244, 241, 232, 0.68);
font-size: 20px;
}
.route-line {
position: absolute;
left: 880px;
top: 562px;
z-index: 4;
width: 260px;
height: 5px;
border-radius: 999px;
background: var(--coral);
box-shadow: 0 0 36px rgba(224, 122, 80, 0.8);
}
.scene-4 .scene-content {
flex-direction: column;
justify-content: center;
gap: 34px;
padding: 82px 110px 96px;
background: var(--cream);
color: var(--forest);
}
.scene-4 .eyebrow {
color: var(--coral-dark);
}
.bento {
display: grid;
grid-template-columns: 1.2fr 1fr 1fr;
gap: 22px;
height: 560px;
}
.bento-card {
position: relative;
overflow: hidden;
border-radius: 30px;
border: 1px solid rgba(19, 31, 22, 0.14);
background: var(--forest);
}
.bento-card img {
width: 100%;
height: 100%;
object-fit: cover;
}
.bento-card.bg-track,
.bento-card.bg-collection,
.bento-card.bg-scan,
.final-image {
background-size: cover;
background-position: center;
}
.bento-card.bg-track {
background-image: url("assets/track-feature.png");
}
.bento-card.bg-collection,
.final-image {
background-image: url("assets/plant-collection.png");
}
.bento-card.bg-scan {
background-image: url("assets/scan-feature.png");
}
.bento-card::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, rgba(19, 31, 22, 0.05), rgba(19, 31, 22, 0.75));
}
.bento-label {
position: absolute;
z-index: 2;
left: 30px;
right: 30px;
bottom: 30px;
display: flex;
flex-direction: column;
gap: 8px;
color: var(--cream);
}
.bento-label strong {
font-family: var(--display);
font-size: 44px;
line-height: 1;
}
.bento-label span {
font-size: 20px;
color: rgba(244, 241, 232, 0.76);
}
.timeline {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
}
.timeline-pill {
min-height: 72px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 18px;
background: #ffffff;
border: 1px solid rgba(19, 31, 22, 0.1);
color: var(--green);
font-weight: 800;
font-size: 24px;
}
.scene-5 .scene-content {
align-items: center;
justify-content: center;
padding: 80px;
background:
radial-gradient(circle at 76% 38%, rgba(86, 160, 116, 0.2), transparent 28%),
var(--forest);
}
.final-card {
position: relative;
z-index: 3;
width: 980px;
min-height: 620px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 28px;
padding: 70px;
border-radius: 44px;
text-align: center;
}
.final-card .brand {
justify-content: center;
font-size: 34px;
}
.final-card h2 {
font-size: 110px;
}
.cta-button {
margin-top: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 300px;
height: 76px;
padding: 0 34px;
border-radius: 999px;
background: var(--coral);
color: white;
font-size: 24px;
font-weight: 800;
}
.final-image {
position: absolute;
z-index: 1;
right: 120px;
bottom: 92px;
width: 470px;
height: 580px;
border-radius: 36px;
overflow: hidden;
opacity: 0.34;
border: 1px solid rgba(244, 241, 232, 0.16);
}
.final-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div
id="root"
data-composition-id="greenlens-promo"
data-start="0"
data-duration="20"
data-width="1920"
data-height="1080"
>
<section id="scene-1" class="scene clip scene-1" data-start="0" data-duration="3.82" data-track-index="1">
<div class="hero-bg"><img src="assets/hero-plant.png" alt="" /></div>
<div class="hero-overlay"></div>
<div class="scan-line"></div>
<div class="particle" style="left: 1400px; top: 210px"></div>
<div class="particle" style="left: 1620px; top: 660px"></div>
<div class="particle" style="left: 1040px; top: 780px"></div>
<div class="scene-content">
<div class="brand"><img src="assets/favicon.svg" alt="" /><span>GreenLens</span></div>
<div class="eyebrow">Plant care, decoded</div>
<h1>What if every plant came with <em>instructions?</em></h1>
<p class="caption">Instant identification and care guidance for the plants you live with.</p>
</div>
</section>
<section id="scene-2" class="scene clip scene-2" data-start="3.82" data-duration="4.48" data-track-index="1">
<div class="scene-content">
<div class="copy-stack">
<div class="eyebrow">AI Scan</div>
<h2>Open. Scan. <em>Know.</em></h2>
<p class="caption">Scan a leaf and get the name, context, and next step in seconds.</p>
<div class="badge">Live plant match</div>
</div>
<div class="phone-stage">
<div class="botanical-plate"><img class="image-fill" src="assets/scan-feature.png" alt="" /></div>
<div class="scan-bracket tl"></div>
<div class="scan-bracket br"></div>
<div class="phone-frame">
<video src="assets/greenlens.mp4" muted playsinline></video>
</div>
<div class="result-card glass">
<strong>Monstera</strong>
<span>Identified with care tips ready.</span>
</div>
</div>
</div>
</section>
<section id="scene-3" class="scene clip scene-3" data-start="8.3" data-duration="4.54" data-track-index="1">
<div class="scene-content">
<div class="analysis-frame glass"><img src="assets/ai-analysis.png" alt="" /></div>
<div class="copy-stack">
<div class="eyebrow">Botanical Intelligence</div>
<h2>From photo to <em>care plan.</em></h2>
<p class="caption">GreenLens turns identification into practical care decisions.</p>
<div class="care-grid">
<div class="care-card glass"><div class="care-icon">1</div><div><strong>Watering</strong><span>Personalized rhythm</span></div></div>
<div class="care-card glass"><div class="care-icon">2</div><div><strong>Light</strong><span>Location-aware guidance</span></div></div>
<div class="care-card glass"><div class="care-icon">3</div><div><strong>Health</strong><span>Early diagnosis cues</span></div></div>
</div>
</div>
<div class="route-line"></div>
</div>
</section>
<section id="scene-4" class="scene clip scene-4" data-start="12.84" data-duration="3.98" data-track-index="1">
<div class="scene-content">
<div class="eyebrow">Your plant system</div>
<h2>Track watering, growth, notes, and <em>health.</em></h2>
<div class="bento">
<div class="bento-card bg-track"><div class="bento-label"><strong>Track it.</strong><span>Care reminders stay organized.</span></div></div>
<div class="bento-card bg-collection"><div class="bento-label"><strong>Collect.</strong><span>Your plants in one place.</span></div></div>
<div class="bento-card bg-scan"><div class="bento-label"><strong>Grow.</strong><span>Build a better routine.</span></div></div>
</div>
<div class="timeline">
<div class="timeline-pill">Watering</div>
<div class="timeline-pill">Growth</div>
<div class="timeline-pill">Notes</div>
<div class="timeline-pill">Health</div>
</div>
</div>
</section>
<section id="scene-5" class="scene clip scene-5" data-start="16.82" data-duration="3.18" data-track-index="1">
<div class="final-image"></div>
<div class="scene-content">
<div class="final-card glass">
<div class="brand"><span class="brand-mark"></span><span>GreenLens</span></div>
<h2>Scan it.<br />Track it.<br /><em>Grow it.</em></h2>
<div class="cta-button">Start with one plant</div>
</div>
</div>
</section>
</div>
<script>
window.__timelines = window.__timelines || {};
const tl = gsap.timeline({ paused: true });
gsap.set("#scene-1", { opacity: 1 });
gsap.set(".scene:not(#scene-1)", { opacity: 0 });
gsap.set(".phone-frame", { transformPerspective: 1200, rotationY: -8, rotationX: 3 });
gsap.set(".botanical-plate", { transformPerspective: 1200, rotationY: 8, rotationX: -2 });
gsap.set(".analysis-frame", { transformPerspective: 1200, rotationY: 7 });
gsap.set(".final-image", { transformPerspective: 1200, rotationY: -10 });
tl.from("#scene-1 .brand", { y: -28, opacity: 0, duration: 0.55, ease: "power3.out" }, 0);
tl.from("#scene-1 .eyebrow", { y: 34, opacity: 0, duration: 0.55, ease: "power3.out" }, 0.22);
tl.from("#scene-1 h1", { y: 58, opacity: 0, duration: 0.72, ease: "power3.out" }, 0.42);
tl.from("#scene-1 .caption", { y: 30, opacity: 0, duration: 0.48, ease: "power2.out" }, 1.02);
tl.fromTo(".hero-bg img", { scale: 1.04 }, { scale: 1.11, duration: 4.0, ease: "none" }, 0);
tl.fromTo(".scan-line", { y: -20 }, { y: 1120, duration: 2.8, ease: "power1.inOut" }, 0.45);
tl.to(".particle", { y: -38, x: 18, opacity: 0.55, duration: 2.2, stagger: 0.25, ease: "sine.inOut" }, 0.7);
tl.to("#scene-1", { y: -120, filter: "blur(18px)", opacity: 0, duration: 0.4, ease: "power2.in" }, 3.6);
tl.set("#scene-2", { y: 120, filter: "blur(18px)", opacity: 1 }, 3.82);
tl.to("#scene-2", { y: 0, filter: "blur(0px)", duration: 0.55, ease: "power3.out" }, 3.82);
tl.from("#scene-2 .copy-stack > *", { y: 42, opacity: 0, duration: 0.55, stagger: 0.12, ease: "power3.out" }, 4.08);
tl.from(".phone-stage", { x: 90, opacity: 0, duration: 0.75, ease: "power3.out" }, 4.2);
tl.from(".scan-bracket", { scale: 0.55, opacity: 0, duration: 0.48, stagger: 0.08, ease: "back.out(1.8)" }, 4.75);
tl.from(".result-card", { y: 46, opacity: 0, duration: 0.5, ease: "power3.out" }, 5.35);
tl.to(".phone-frame", { y: -12, duration: 1.7, repeat: 2, yoyo: true, ease: "sine.inOut" }, 5.0);
tl.to(".botanical-plate img", { scale: 1.07, duration: 4.2, ease: "none" }, 4.0);
tl.to("#scene-2", { x: -360, filter: "blur(22px)", opacity: 0, duration: 0.35, ease: "power3.in" }, 8.15);
tl.set("#scene-3", { x: 360, filter: "blur(22px)", opacity: 1 }, 8.3);
tl.to("#scene-3", { x: 0, filter: "blur(0px)", duration: 0.48, ease: "power3.out" }, 8.3);
tl.from(".analysis-frame", { scale: 0.9, opacity: 0, duration: 0.58, ease: "power3.out" }, 8.48);
tl.from("#scene-3 .copy-stack > *:not(.care-grid)", { y: 38, opacity: 0, duration: 0.5, stagger: 0.1, ease: "power3.out" }, 8.65);
tl.from(".care-card", { x: 70, opacity: 0, duration: 0.48, stagger: 0.15, ease: "power3.out" }, 9.25);
tl.from(".route-line", { scaleX: 0, opacity: 0, duration: 0.65, ease: "power3.out" }, 9.65);
tl.to(".analysis-frame img", { scale: 1.06, duration: 4.5, ease: "none" }, 8.5);
tl.to(".care-icon", { scale: 1.08, duration: 0.5, repeat: 5, yoyo: true, ease: "sine.inOut" }, 10.0);
tl.to("#scene-3", { scale: 1.08, filter: "blur(18px)", opacity: 0, duration: 0.38, ease: "power2.in" }, 12.62);
tl.set("#scene-4", { scale: 0.94, filter: "blur(18px)", opacity: 1 }, 12.84);
tl.to("#scene-4", { scale: 1, filter: "blur(0px)", duration: 0.48, ease: "power3.out" }, 12.84);
tl.from("#scene-4 .eyebrow, #scene-4 h2", { y: 34, opacity: 0, duration: 0.5, stagger: 0.1, ease: "power3.out" }, 13.0);
tl.from(".bento-card", { y: 80, opacity: 0, duration: 0.55, stagger: 0.12, ease: "power3.out" }, 13.45);
tl.from(".timeline-pill", { y: 24, opacity: 0, duration: 0.36, stagger: 0.07, ease: "power2.out" }, 14.32);
tl.to(".timeline-pill", { y: -8, duration: 0.55, repeat: 3, yoyo: true, stagger: 0.08, ease: "sine.inOut" }, 15.0);
tl.to("#scene-4", { scale: 0.88, filter: "blur(18px)", opacity: 0, duration: 0.38, ease: "power2.in" }, 16.62);
tl.set("#scene-5", { scale: 1.1, filter: "blur(16px)", opacity: 1 }, 16.82);
tl.to("#scene-5", { scale: 1, filter: "blur(0px)", duration: 0.52, ease: "power3.out" }, 16.82);
tl.from(".final-card", { y: 52, opacity: 0, duration: 0.68, ease: "power3.out" }, 17.0);
tl.from(".final-card h2", { y: 42, opacity: 0, duration: 0.62, ease: "power3.out" }, 17.22);
tl.from(".cta-button", { y: 30, opacity: 0, scale: 0.92, duration: 0.5, ease: "back.out(1.7)" }, 17.82);
tl.from(".final-image", { x: 100, opacity: 0, duration: 0.8, ease: "power3.out" }, 17.0);
tl.to(".cta-button", { boxShadow: "0 0 44px rgba(224, 122, 80, 0.55)", duration: 0.8, repeat: 2, yoyo: true, ease: "sine.inOut" }, 18.35);
window.__timelines["greenlens-promo"] = tl;
</script>
</body>
</html>