Compare commits

..

2 Commits

Author SHA1 Message Date
Roberto Musso
ec5284457f update commit
Some checks failed
Deploy Website / deploy (push) Failing after 6s
2026-04-11 17:45:15 +02:00
Roberto Musso
121e229784 Replace dark problem section with sticky scroll app walkthrough
- Remove old Problem + Reveal sections (dark bg, SVG waves, static screenshot)
- Add interactive walkthrough: sticky scroll with progressive app UI reveal
- Recreate app UI in HTML/CSS (sidebar, greeting, daily brief, chat, suggestions)
- 4 scroll steps with text descriptions + progress dots on the left
- GSAP ScrollTrigger pins the section and animates elements in sequence
- Pillar badges (AI Secretary, Private by Design, EU AI Act) appear at final step
- Clean up all orphaned CSS/JS from old sections
- Responsive breakpoints for mobile walkthrough layout
2026-04-11 16:22:28 +02:00
2 changed files with 483 additions and 151 deletions

View File

@@ -1,4 +1,4 @@
name: Deploy HTML to Docker LXC name: Deploy Website
run-name: Deploying static site by ${{ github.actor }} run-name: Deploying static site by ${{ github.actor }}
on: on:
@@ -8,17 +8,31 @@ on:
jobs: jobs:
deploy: deploy:
runs-on: ubuntu-latest # Adjust if your runner uses a different label runs-on: ubuntu-latest
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Copy site files to Docker LXC - name: Deploy static files via SCP
uses: appleboy/scp-action@v0.1.7 uses: appleboy/scp-action@v0.1.7
with: with:
host: ${{ secrets.SSH_HOST }} host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }} username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }} key: ${{ secrets.SSH_KEY }}
source: "index.html,privacy.html,terms.html,assets/*" source: "index.html,privacy.html,terms.html,assets/*"
target: "/opt/adiuvai-website/html/" target: "/opt/adiuvai-waitlist/website/"
rm: true rm: true
- name: Verify deployment
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
if [ -f /opt/adiuvai-waitlist/website/index.html ]; then
echo "✅ Website deployed"
else
echo "❌ index.html not found"
exit 1
fi

View File

@@ -69,9 +69,9 @@
position: fixed; position: fixed;
inset: 0; inset: 0;
background: background:
radial-gradient(ellipse 80% 60% at 25% 20%, rgba(251,200,129,0.07) 0%, transparent 60%), radial-gradient(ellipse 80% 60% at 25% 20%, rgba(251,200,129,0.10) 0%, transparent 60%),
radial-gradient(ellipse 70% 50% at 75% 70%, rgba(138,142,169,0.06) 0%, transparent 50%), radial-gradient(ellipse 70% 50% at 75% 70%, rgba(138,142,169,0.08) 0%, transparent 50%),
radial-gradient(ellipse 90% 60% at 50% 110%, rgba(200,195,205,0.08) 0%, transparent 50%); radial-gradient(ellipse 90% 60% at 50% 110%, rgba(200,195,205,0.10) 0%, transparent 50%);
pointer-events: none; pointer-events: none;
z-index: 0; z-index: 0;
} }
@@ -81,13 +81,15 @@
content: ''; content: '';
position: fixed; position: fixed;
inset: 0; inset: 0;
opacity: 0.025; opacity: 0.03;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
background-size: 200px; background-size: 200px;
pointer-events: none; pointer-events: none;
z-index: 1; z-index: 1;
} }
/* Section wave dividers — removed, using gradient fades instead */
.container { .container {
max-width: 1100px; max-width: 1100px;
margin: 0 auto; margin: 0 auto;
@@ -163,7 +165,7 @@
.nav-logo { .nav-logo {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 8px;
font-size: 1.1rem; font-size: 1.1rem;
font-weight: 400; font-weight: 400;
letter-spacing: -0.02em; letter-spacing: -0.02em;
@@ -402,7 +404,7 @@
SECTIONS (shared) SECTIONS (shared)
═══════════════════════════════════════ */ ═══════════════════════════════════════ */
.section { .section {
padding: 120px 24px; padding: 64px 24px;
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
@@ -416,106 +418,308 @@
} }
/* ═══════════════════════════════════════ /* ═══════════════════════════════════════
PROBLEM — Scrollytelling APP WALKTHROUGH — Sticky Scroll
═══════════════════════════════════════ */ ═══════════════════════════════════════ */
.problem { .walkthrough {
min-height: 100vh; position: relative;
z-index: 2;
height: 100vh;
display: flex; display: flex;
flex-direction: column; align-items: center;
justify-content: center; justify-content: center;
overflow: hidden;
} }
.problem-lines { .walkthrough-inner {
max-width: 700px; display: flex;
align-items: center;
justify-content: center;
gap: 64px;
padding: 0 48px;
max-width: 1200px;
margin: 0 auto; margin: 0 auto;
text-align: center; width: 100%;
} }
.problem-line {
font-size: clamp(1.4rem, 3vw, 2rem); /* Text column (left) */
font-weight: 400; .wt-text {
flex: 0 0 320px;
position: relative;
min-height: 200px;
}
.wt-step {
position: absolute;
top: 0;
left: 0;
right: 0;
opacity: 0;
transform: translateY(20px);
}
.wt-step.active {
opacity: 1;
transform: none;
}
.wt-step-num {
font-size: 0.68rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--primary-deep);
margin-bottom: 10px;
}
.wt-step h3 {
font-size: clamp(1.5rem, 2.5vw, 2rem);
font-weight: 600;
letter-spacing: -0.02em; letter-spacing: -0.02em;
line-height: 1.5; line-height: 1.3;
margin-bottom: 28px; margin-bottom: 12px;
color: var(--text-muted);
} }
.problem-conclusion { .wt-step p {
font-size: 0.95rem;
color: var(--text-muted);
line-height: 1.7;
}
.wt-step .emphasis {
font-weight: 700; font-weight: 700;
color: var(--text); color: var(--text);
margin-top: 36px;
font-size: clamp(1.5rem, 3.5vw, 2.2rem);
line-height: 1.4;
letter-spacing: -0.02em;
} }
.problem-conclusion em { .wt-step .emphasis em {
font-style: normal; font-style: normal;
color: var(--primary-deep); color: var(--primary-deep);
} }
/* ═══════════════════════════════════════ /* Progress dots */
THE REVEAL .wt-dots {
═══════════════════════════════════════ */ display: flex;
.reveal { text-align: center; } gap: 8px;
.reveal h2 { margin-bottom: 56px; } margin-top: 28px;
}
.wt-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--muted);
transition: all 0.4s ease;
}
.wt-dot.active {
background: var(--primary);
transform: scale(1.25);
}
.device-frame { /* Device column (right) */
max-width: 840px; .wt-device {
margin: 0 auto 56px; flex: 1;
border-radius: 16px; max-width: 640px;
position: relative;
}
.wt-device-frame {
border-radius: 14px;
overflow: hidden; overflow: hidden;
background: #fff; background: #fafafa;
box-shadow: box-shadow:
0 2px 4px rgba(0,0,0,0.02), 0 2px 4px rgba(0,0,0,0.03),
0 8px 16px rgba(0,0,0,0.04), 0 8px 20px rgba(0,0,0,0.06),
0 32px 64px rgba(0,0,0,0.06); 0 24px 48px rgba(0,0,0,0.08),
transform: perspective(1200px) rotateX(2deg); 0 48px 80px rgba(0,0,0,0.05);
transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.6s ease;
} }
.device-frame:hover { .wt-device-frame::before {
transform: perspective(1200px) rotateX(0deg) translateY(-4px); content: '';
box-shadow: position: absolute;
0 2px 4px rgba(0,0,0,0.02), inset: -40px;
0 12px 24px rgba(0,0,0,0.06), background: radial-gradient(ellipse 70% 60% at 50% 55%, rgba(251,200,129,0.10) 0%, rgba(251,200,129,0.02) 40%, transparent 70%);
0 48px 80px rgba(0,0,0,0.08); filter: blur(40px);
z-index: -1;
border-radius: 40px;
} }
.device-topbar { .wt-topbar {
height: 32px; height: 28px;
background: #f8f8f8; background: #f0f0f0;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 14px; padding: 0 12px;
gap: 6px; gap: 5px;
border-bottom: 1px solid #eee; border-bottom: 1px solid #e8e8e8;
} }
.device-dot { width: 9px; height: 9px; border-radius: 50%; } .wt-topbar span { width: 8px; height: 8px; border-radius: 50%; }
.device-dot:nth-child(1) { background: #ff5f57; } .wt-topbar span:nth-child(1) { background: #ff5f57; }
.device-dot:nth-child(2) { background: #febc2e; } .wt-topbar span:nth-child(2) { background: #febc2e; }
.device-dot:nth-child(3) { background: #28c840; } .wt-topbar span:nth-child(3) { background: #28c840; }
.device-frame img { width: 100%; height: auto; display: block; object-fit: contain; }
.pillars { /* App recreation */
.wt-app {
display: flex;
min-height: 380px;
font-size: 13px;
color: #1a1a1a;
}
/* Sidebar */
.wt-sidebar {
width: 44px;
background: #f4f0f4;
border-right: 1px solid #e8e4e8;
display: flex;
flex-direction: column;
align-items: center;
padding: 10px 0;
gap: 4px;
opacity: 0;
}
.wt-sidebar-logo {
width: 24px;
height: 24px;
margin-bottom: 8px;
}
.wt-sidebar-icon {
width: 32px;
height: 32px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: #8a8ea9;
transition: all 0.2s;
}
.wt-sidebar-icon.active {
background: rgba(251,200,129,0.15);
color: #e5a94e;
}
.wt-sidebar-icon i { width: 16px; height: 16px; }
.wt-sidebar-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: #d4d0d8;
margin-top: auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 9px;
font-weight: 700;
color: #666;
}
/* Main content area */
.wt-main {
flex: 1;
padding: 32px 40px;
display: flex;
flex-direction: column;
background: #fafafa;
}
.wt-greeting {
opacity: 0;
margin-bottom: 4px;
}
.wt-greeting-label {
font-size: 14px;
color: #8a8ea9;
font-weight: 400;
}
.wt-greeting-name {
font-size: 36px;
font-weight: 700;
letter-spacing: -0.03em;
color: #1a1a1a;
display: flex;
align-items: baseline;
gap: 8px;
}
.wt-greeting-name .wt-sparkle {
color: #e5a94e;
font-size: 28px;
line-height: 1;
}
.wt-brief {
opacity: 0;
margin: 16px 0 20px;
font-size: 13px;
line-height: 1.6;
color: #555;
max-width: 480px;
}
.wt-chat {
opacity: 0;
margin-top: auto;
}
.wt-chat-input {
display: flex;
align-items: center;
background: #fff;
border: 1px solid #e0dce0;
border-radius: 24px;
padding: 10px 14px 10px 18px;
gap: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.03);
}
.wt-chat-input span {
flex: 1;
color: #b0aab4;
font-size: 13px;
}
.wt-chat-send {
width: 28px;
height: 28px;
border-radius: 50%;
background: rgba(251,200,129,0.15);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.wt-chat-send i { width: 14px; height: 14px; color: #e5a94e; }
.wt-suggestions {
opacity: 0;
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 12px;
}
.wt-suggestion {
display: flex;
align-items: center;
gap: 8px;
font-size: 12.5px;
color: #8a8ea9;
padding: 2px 0;
}
.wt-suggestion i { width: 14px; height: 14px; flex-shrink: 0; }
/* Pillar pills (below device) */
.wt-pillars {
display: flex; display: flex;
gap: 16px; gap: 16px;
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: 32px;
opacity: 0;
} }
.pillar {
display: flex; @media (max-width: 900px) {
align-items: center; .walkthrough-inner {
gap: 10px; flex-direction: column;
padding: 12px 22px; gap: 32px;
border-radius: 50px; padding: 80px 20px 24px;
background: var(--card-bg); }
backdrop-filter: blur(16px); .wt-text { flex: none; width: 100%; min-height: 120px; }
border: 1px solid var(--card-border); .wt-device { max-width: 100%; }
font-size: 0.88rem; .wt-app { min-height: 280px; }
font-weight: 500; .wt-main { padding: 20px 24px; }
transition: all var(--transition); .wt-greeting-name { font-size: 24px; }
} }
.pillar:hover { @media (max-width: 640px) {
background: rgba(255,255,255,0.7); .walkthrough-inner { padding: 72px 16px 16px; gap: 20px; }
transform: translateY(-2px); .wt-text { flex: none; }
box-shadow: 0 8px 20px rgba(0,0,0,0.04); .wt-app { min-height: 240px; font-size: 11px; }
.wt-main { padding: 16px 18px; }
.wt-greeting-name { font-size: 20px; }
.wt-greeting-name .wt-sparkle { font-size: 18px; }
.wt-sidebar { width: 36px; }
.wt-sidebar-icon { width: 26px; height: 26px; }
.wt-sidebar-icon i { width: 13px; height: 13px; }
.wt-brief { font-size: 11px; }
.wt-chat-input { padding: 8px 10px 8px 14px; }
.wt-suggestion { font-size: 11px; }
} }
.pillar i { width: 18px; height: 18px; color: var(--primary-deep); }
/* ═══════════════════════════════════════ /* ═══════════════════════════════════════
HOW IT WORKS HOW IT WORKS
@@ -543,15 +747,16 @@
text-align: center; text-align: center;
padding: 40px 24px; padding: 40px 24px;
border-radius: var(--radius); border-radius: var(--radius);
background: var(--card-bg); background: rgba(255, 255, 255, 0.55);
backdrop-filter: blur(16px); backdrop-filter: blur(20px);
border: 1px solid var(--card-border); border: 1px solid rgba(255, 255, 255, 0.65);
box-shadow: 0 4px 16px rgba(0,0,0,0.03), 0 1px 2px rgba(0,0,0,0.02);
transition: all var(--transition); transition: all var(--transition);
} }
.step-card:hover { .step-card:hover {
background: rgba(255,255,255,0.65); background: rgba(255,255,255,0.75);
transform: translateY(-4px); transform: translateY(-6px);
box-shadow: 0 12px 32px rgba(0,0,0,0.05); box-shadow: 0 16px 40px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.03);
} }
.step-num { .step-num {
width: 48px; height: 48px; border-radius: 50%; width: 48px; height: 48px; border-radius: 50%;
@@ -578,16 +783,17 @@
.feature-card { .feature-card {
padding: 28px; padding: 28px;
border-radius: var(--radius); border-radius: var(--radius);
background: var(--card-bg); background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(16px); backdrop-filter: blur(20px);
border: 1px solid var(--card-border); border: 1px solid rgba(255, 255, 255, 0.6);
transition: all var(--transition); box-shadow: 0 4px 16px rgba(0,0,0,0.03), 0 1px 2px rgba(0,0,0,0.02);
transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
position: relative; position: relative;
transform-style: preserve-3d;
} }
.feature-card:hover { .feature-card:hover {
background: rgba(255,255,255,0.65); background: rgba(255,255,255,0.75);
transform: translateY(-3px); box-shadow: 0 20px 48px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.03);
box-shadow: 0 12px 32px rgba(0,0,0,0.04);
} }
.feature-icon { .feature-icon {
width: 42px; height: 42px; border-radius: 12px; width: 42px; height: 42px; border-radius: 12px;
@@ -623,9 +829,10 @@
position: relative; position: relative;
padding: 40px; padding: 40px;
border-radius: var(--radius); border-radius: var(--radius);
background: var(--card-bg); background: rgba(255, 255, 255, 0.55);
backdrop-filter: blur(16px); backdrop-filter: blur(20px);
border: 1px solid var(--card-border); border: 1px solid rgba(255, 255, 255, 0.65);
box-shadow: 0 8px 32px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.02);
} }
.founder-quote::before { .founder-quote::before {
content: '\201C'; content: '\201C';
@@ -656,12 +863,9 @@
═══════════════════════════════════════ */ ═══════════════════════════════════════ */
.final-cta { .final-cta {
text-align: center; text-align: center;
padding: 120px 24px; padding: 64px 24px;
position: relative; position: relative;
z-index: 2; z-index: 2;
background:
radial-gradient(ellipse 80% 50% at 50% 100%, rgba(251,200,129,0.06) 0%, transparent 60%),
linear-gradient(180deg, var(--bg) 0%, var(--bg-shifted) 100%);
} }
.final-cta h2 { margin-bottom: 12px; } .final-cta h2 { margin-bottom: 12px; }
.final-cta .subtitle { .final-cta .subtitle {
@@ -716,9 +920,8 @@
.features-grid { grid-template-columns: 1fr; } .features-grid { grid-template-columns: 1fr; }
.pillars { flex-direction: column; align-items: center; } .pillars { flex-direction: column; align-items: center; }
nav { padding: 0 16px; } nav { padding: 0 16px; }
.device-frame { transform: none; } .section { padding: 48px 20px; }
.device-frame:hover { transform: none; } .final-cta { padding: 48px 20px; }
.section { padding: 80px 20px; }
.founder-quote { padding: 28px; } .founder-quote { padding: 28px; }
} }
@@ -732,7 +935,8 @@
transition-duration: 0.01ms !important; transition-duration: 0.01ms !important;
} }
.gs-reveal { opacity: 1; transform: none; } .gs-reveal { opacity: 1; transform: none; }
.problem-line, .problem-conclusion { opacity: 1 !important; transform: none !important; } .wt-step { opacity: 1 !important; transform: none !important; }
.wt-sidebar, .wt-greeting, .wt-brief, .wt-chat, .wt-suggestions, .wt-pillars { opacity: 1 !important; transform: none !important; }
.particle { display: none; } .particle { display: none; }
} }
</style> </style>
@@ -746,8 +950,7 @@
<path d="M32,4 L48,32 L16,32 Z" fill="#fbc881"/> <path d="M32,4 L48,32 L16,32 Z" fill="#fbc881"/>
<path d="M16,32 L48,32 L32,60 Z" fill="#040404"/> <path d="M16,32 L48,32 L32,60 Z" fill="#040404"/>
<circle cx="32" cy="32" r="2.5" fill="#040404" opacity="0.18"/> <circle cx="32" cy="32" r="2.5" fill="#040404" opacity="0.18"/>
</svg> </svg><span>adiuv<span class="ai">AI</span></span>
adiuv<span class="ai">AI</span>
</a> </a>
<a href="#final-cta" class="btn btn-primary">Join the waitlist</a> <a href="#final-cta" class="btn btn-primary">Join the waitlist</a>
</nav> </nav>
@@ -807,40 +1010,88 @@
100% on your device 100% on your device
</div> </div>
<!-- ═══════ THE PROBLEM — Scrollytelling ═══════ --> <!-- ═══════ APP WALKTHROUGH — Sticky Scroll ═══════ -->
<section class="section problem" id="problem"> <section class="walkthrough" id="walkthrough">
<div class="problem-lines"> <div class="walkthrough-inner">
<p class="problem-line">Your important emails hide between newsletters.</p>
<p class="problem-line">Your tasks live in three different apps.</p>
<p class="problem-line">Meeting notes sit in a doc you'll never open again.</p>
<p class="problem-conclusion">You don't need another tool.<br>You need <em>a secretary</em>.</p>
</div>
</section>
<!-- ═══════ THE REVEAL ═══════ --> <!-- Text column -->
<section class="section reveal" id="reveal"> <div class="wt-text">
<div class="container"> <div class="wt-step" data-step="0">
<p class="section-label gs-reveal">The product</p> <p class="wt-step-num">The problem</p>
<h2 class="gs-reveal">Your daily brief, every morning.</h2> <h3>Your important emails hide between newsletters.</h3>
<p>You miss deadlines buried in threads. Tasks get lost across three different apps. Sound familiar?</p>
<div class="device-frame gs-reveal"> <div class="wt-dots"><span class="wt-dot active"></span><span class="wt-dot"></span><span class="wt-dot"></span><span class="wt-dot"></span></div>
<div class="device-topbar" aria-hidden="true"> </div>
<div class="device-dot"></div> <div class="wt-step" data-step="1">
<div class="device-dot"></div> <p class="wt-step-num">The greeting</p>
<div class="device-dot"></div> <h3>Every morning, your AI secretary is ready.</h3>
<p>Open the app and it already knows what happened overnight — emails scanned, tasks prioritized, deadlines flagged.</p>
<div class="wt-dots"><span class="wt-dot"></span><span class="wt-dot active"></span><span class="wt-dot"></span><span class="wt-dot"></span></div>
</div>
<div class="wt-step" data-step="2">
<p class="wt-step-num">The brief</p>
<h3>Meeting notes sit in a doc you'll never open again.</h3>
<p>Not here. Your daily brief is a clear, AI-generated summary of what matters today — tasks, follow-ups, and deadlines in one place.</p>
<div class="wt-dots"><span class="wt-dot"></span><span class="wt-dot"></span><span class="wt-dot active"></span><span class="wt-dot"></span></div>
</div>
<div class="wt-step" data-step="3">
<p class="wt-step-num">The result</p>
<h3 class="emphasis">You don't need another tool.<br>You need <em>a secretary</em>.</h3>
<p>Ask it anything. It understands your projects, your emails, your schedule — and it never leaves your device.</p>
<div class="wt-dots"><span class="wt-dot"></span><span class="wt-dot"></span><span class="wt-dot"></span><span class="wt-dot active"></span></div>
</div>
</div>
<!-- Device column -->
<div class="wt-device">
<div class="wt-device-frame">
<div class="wt-topbar"><span></span><span></span><span></span></div>
<div class="wt-app">
<!-- Sidebar -->
<div class="wt-sidebar" id="wt-sidebar">
<svg class="wt-sidebar-logo" viewBox="0 0 64 64" fill="none">
<path d="M32,4 L48,32 L16,32 Z" fill="#fbc881"/>
<path d="M16,32 L48,32 L32,60 Z" fill="#040404"/>
</svg>
<div class="wt-sidebar-icon active"><i data-lucide="house"></i></div>
<div class="wt-sidebar-icon"><i data-lucide="chart-gantt"></i></div>
<div class="wt-sidebar-icon"><i data-lucide="clipboard-check"></i></div>
<div class="wt-sidebar-icon"><i data-lucide="folder-kanban"></i></div>
<div class="wt-sidebar-avatar">JD</div>
</div>
<!-- Main -->
<div class="wt-main">
<div class="wt-greeting" id="wt-greeting">
<div class="wt-greeting-label">Good morning,</div>
<div class="wt-greeting-name">James <span class="wt-sparkle"></span></div>
</div>
<div class="wt-brief" id="wt-brief">
Good morning! Just a quick reminder to wrap up task X today and reply to that project email. Also, please don't forget that the documentation and the estimate are due tomorrow.
</div>
<div class="wt-chat" id="wt-chat">
<div class="wt-chat-input">
<span>Ask me anything...</span>
<div class="wt-chat-send"><i data-lucide="arrow-up"></i></div>
</div>
</div>
<div class="wt-suggestions" id="wt-suggestions">
<div class="wt-suggestion"><i data-lucide="list-todo"></i> What's on my plate today?</div>
<div class="wt-suggestion"><i data-lucide="trending-up"></i> Summarize this week</div>
<div class="wt-suggestion"><i data-lucide="circle-alert"></i> Any overdue tasks?</div>
<div class="wt-suggestion"><i data-lucide="lightbulb"></i> Suggest next actions</div>
</div>
</div>
</div>
</div>
<div class="pillars wt-pillars" id="wt-pillars">
<div class="pillar"><i data-lucide="sparkles"></i> AI Secretary</div>
<div class="pillar"><i data-lucide="lock"></i> Private by Design</div>
<div class="pillar"><i data-lucide="scale"></i> EU AI Act Compliant</div>
</div>
</div> </div>
<!-- Screenshot of the adiuvAI desktop app -->
<img src="./assets/home.png"
alt="adiuvAI dashboard showing a personalized morning brief with tasks, priorities, and AI chat assistant"
loading="lazy" width="1920" height="1079">
</div>
<div class="pillars">
<div class="pillar gs-reveal"><i data-lucide="sparkles"></i> AI Secretary</div>
<div class="pillar gs-reveal"><i data-lucide="lock"></i> Private by Design</div>
<div class="pillar gs-reveal"><i data-lucide="scale"></i> EU AI Act Compliant</div>
</div> </div>
</div>
</section> </section>
<!-- ═══════ HOW IT WORKS ═══════ --> <!-- ═══════ HOW IT WORKS ═══════ -->
@@ -989,8 +1240,7 @@
<svg viewBox="0 0 64 64" fill="none" aria-hidden="true"> <svg viewBox="0 0 64 64" fill="none" aria-hidden="true">
<path d="M32,4 L48,32 L16,32 Z" fill="#fbc881"/> <path d="M32,4 L48,32 L16,32 Z" fill="#fbc881"/>
<path d="M16,32 L48,32 L32,60 Z" fill="currentColor"/> <path d="M16,32 L48,32 L32,60 Z" fill="currentColor"/>
</svg> </svg><span>adiuv<span class="ai">AI</span></span>
adiuv<span class="ai">AI</span>
</div> </div>
<p class="legal"> <p class="legal">
&copy; 2026 adiuvAI. All rights reserved. &copy; 2026 adiuvAI. All rights reserved.
@@ -1080,22 +1330,64 @@
}); });
}); });
// ─── Problem: scroll-driven line reveals ─── // ─── Walkthrough: sticky scroll with progressive app reveal ───
const lines = gsap.utils.toArray('.problem-line, .problem-conclusion'); const wtSection = document.getElementById('walkthrough');
lines.forEach((el) => { const wtSteps = gsap.utils.toArray('.wt-step');
gsap.set(el, { opacity: 0, y: 28 }); const wtSidebar = document.getElementById('wt-sidebar');
gsap.to(el, { const wtGreeting = document.getElementById('wt-greeting');
opacity: 1, const wtBrief = document.getElementById('wt-brief');
y: 0, const wtChat = document.getElementById('wt-chat');
ease: 'power2.out', const wtSuggestions = document.getElementById('wt-suggestions');
const wtPillars = document.getElementById('wt-pillars');
if (wtSection) {
// Set initial states
gsap.set(wtSteps, { opacity: 0, y: 40 });
gsap.set(wtSteps[0], { opacity: 1, y: 0 });
gsap.set([wtSidebar], { opacity: 0, x: -30 });
gsap.set([wtGreeting], { opacity: 0, y: -20 });
gsap.set([wtBrief], { opacity: 0, y: 20 });
gsap.set([wtChat], { opacity: 0, y: 30 });
gsap.set([wtSuggestions], { opacity: 0, y: 30 });
gsap.set([wtPillars], { opacity: 0, y: 20 });
const wtTl = gsap.timeline({
scrollTrigger: { scrollTrigger: {
trigger: el, trigger: wtSection,
start: 'top 82%', start: 'top top',
end: 'top 58%', end: () => '+=' + (window.innerHeight * 3),
scrub: 0.5, scrub: 0.6,
pin: true,
anticipatePin: 1,
invalidateOnRefresh: true,
}, },
}); });
});
// Use normalized 0-1 positions so timing scales with any scroll distance
wtTl
// Step 0 visible at start → sidebar flies in
.to(wtSidebar, { opacity: 1, x: 0, duration: 0.15, ease: 'power2.out' }, 0)
.to(wtSteps[0], { opacity: 0, y: -30, duration: 0.08 }, 0.13)
// Step 1: greeting
.to(wtSteps[1], { opacity: 1, y: 0, duration: 0.1, ease: 'power2.out' }, 0.18)
.to(wtGreeting, { opacity: 1, y: 0, duration: 0.1, ease: 'power2.out' }, 0.18)
// Hold step 1
.to({}, { duration: 0.08 }, 0.28)
// Step 2: brief
.to(wtSteps[1], { opacity: 0, y: -30, duration: 0.08 }, 0.36)
.to(wtSteps[2], { opacity: 1, y: 0, duration: 0.1, ease: 'power2.out' }, 0.42)
.to(wtBrief, { opacity: 1, y: 0, duration: 0.1, ease: 'power2.out' }, 0.42)
// Hold step 2
.to({}, { duration: 0.08 }, 0.52)
// Step 3: chat + suggestions + pillars
.to(wtSteps[2], { opacity: 0, y: -30, duration: 0.08 }, 0.60)
.to(wtSteps[3], { opacity: 1, y: 0, duration: 0.1, ease: 'power2.out' }, 0.66)
.to(wtChat, { opacity: 1, y: 0, duration: 0.08, ease: 'power2.out' }, 0.66)
.to(wtSuggestions, { opacity: 1, y: 0, duration: 0.08, ease: 'power2.out' }, 0.72)
.to(wtPillars, { opacity: 1, y: 0, duration: 0.08, ease: 'power2.out' }, 0.78)
// Hold step 3 visible
.to({}, { duration: 0.14 }, 0.86);
}
// ─── Generic scroll reveals for gs-reveal ─── // ─── Generic scroll reveals for gs-reveal ───
gsap.utils.toArray('.gs-reveal').forEach((el, i) => { gsap.utils.toArray('.gs-reveal').forEach((el, i) => {
@@ -1125,6 +1417,32 @@
scrub: true, scrub: true,
}, },
}); });
// ─── 3D tilt on feature cards ───
document.querySelectorAll('.feature-card').forEach((card) => {
card.addEventListener('mousemove', (e) => {
const r = card.getBoundingClientRect();
const x = (e.clientX - r.left) / r.width - 0.5;
const y = (e.clientY - r.top) / r.height - 0.5;
gsap.to(card, {
rotateY: x * 10,
rotateX: y * -10,
transformPerspective: 600,
duration: 0.4,
ease: 'power2.out',
});
});
card.addEventListener('mouseleave', () => {
gsap.to(card, {
rotateY: 0,
rotateX: 0,
duration: 0.6,
ease: 'elastic.out(1, 0.5)',
});
});
});
}); });
// ─── Waitlist Form Handler ─── // ─── Waitlist Form Handler ───