customer-presentation/public/entrance.html
Jonathan Hvid fb815768e2 customer-presentation: convert deck from Bifrost invitation to customer-facing
Why: pivot the experience from a personal invitation for Project Bifrost
participants to a customer-facing presentation that can be shown to
prospects like Novo Nordisk while still mentioning Bifrost in context.

Major changes:
- Entrance: re-worded title/body away from "invitation" into "introduction"; kept Fenja AI / Project Bifrost definition blocks.
- Timeline: page-sub reworked to also speak to highly-regulated private orgs (data, IP, regulated workflows, US-vendor dependency) alongside public sector.
- "Backed by Innovationsfonden" pairs with new "Part of BioInnovation Institute AI Lab" line on entrance and Scene 1 hero.
- Removed: stack-scene (4 capabilities) and words-scene ("This is why we've invited you") — archived at protected/_archive/stack-scene.html for restore.
- Removed: bifrost-join CTA + Innovationsfonden footer section.
- Inlined the standalone /deepdive architecture explainer into #overview-scroll after #bifrost-meaning; platform.js detects scroller and skips its own Lenis setup when integrated.
- New: Wiki deep-dive section (#wiki-deepdive) — scattered knowledge cluster → Fenja AI Compiler → layered page stack with citations, plus pinned scrubbed beat-by-beat reveal.
- New: Implementation roadmap section (#platform-roadmap) — four stage cards + GOVERN & SCALE band + footer, with click-to-expand card-morph (FLIP-based; same DOM element grows into the featured panel).
- Dot-nav: 4 → 8 entries — Welcome / Timeline / Fenja introduction / Project Bifrost / Architecture / Wiki / Deployment / Roadmap.
- Deployment options: scroll-tied fade-in for the whole section + sticky-damping at centre for a subtle dwell stop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:56:30 +02:00

440 lines
13 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Fenja AI</title>
<style>
@view-transition { navigation: auto; }
:root {
--paper: #faf6ee;
--paper-sink: #e7e1d0;
--paper-sink-deep: #ddd6c3;
--ink: #383831;
--ink-soft: #5f5e5e;
--ink-dim: #8a887f;
--walnut: #785f53;
--walnut-dim: #6b5348;
--crimson: #8a3a2f;
--ease: cubic-bezier(0.2, 0, 0, 1);
--dur: 240ms;
}
*, *::before, *::after { box-sizing: border-box; }
html, body {
margin: 0; padding: 0;
min-height: 100%;
background: var(--paper);
color: var(--ink);
font-family: "Manrope", system-ui, -apple-system, sans-serif;
-webkit-font-smoothing: antialiased;
}
body {
min-height: 100vh;
background: radial-gradient(1100px 760px at 22% 42%, #fffcf7 0%, var(--paper) 58%, #f2ecdd 100%);
display: flex;
align-items: center;
view-transition-name: paper;
}
/* ───── Topographic currents ───── */
.currents {
position: fixed;
top: -22vh; right: -18vw;
width: 90vw; height: 130vh;
max-width: 1600px;
pointer-events: none;
z-index: 1;
-webkit-mask-image: radial-gradient(60% 60% at 50% 50%, #000 40%, transparent 82%);
mask-image: radial-gradient(60% 60% at 50% 50%, #000 40%, transparent 82%);
opacity: 0;
transition: opacity 900ms var(--ease);
}
.currents.is-ready { opacity: 1; }
.currents svg { width: 100%; height: 100%; display: block; }
.entrance {
position: relative;
z-index: 10;
width: 100%;
min-height: 100vh;
padding: 0 112px;
/* Vertically center the active step (email or welcome). Body-level
flex also centers, but an extra flex layer here ensures the
welcome step — which is taller than the email step — stays
anchored to the viewport centre rather than drifting down. */
display: flex;
align-items: center;
}
.entrance-inner {
max-width: 620px;
width: 100%;
}
/* ───── Steps ───── */
.step { display: none; }
.step.is-active {
display: block;
animation: enter 640ms var(--ease) forwards;
}
/* Suppress every step until entrance.js has checked /auth/me and picked
the right starting step. Prevents a flash of the email form when an
authed user lands on /. */
body.is-pending .step { display: none !important; }
@keyframes enter {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
/* ───── Tagline ───── */
.tagline {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-style: italic;
font-weight: 400;
font-size: 34px;
line-height: 1.28;
letter-spacing: -0.012em;
color: var(--ink);
margin: 0 0 40px 0;
text-wrap: pretty;
}
/* ───── Field ───── */
.field { display: block; width: 100%; }
.field-input {
display: block; width: 100%;
height: 56px; padding: 0 18px;
background: var(--paper-sink);
color: var(--ink);
font-family: "Manrope", system-ui, sans-serif;
font-size: 17px; font-weight: 400;
border: 0;
border-radius: 12px 12px 0 0;
outline: 0;
box-shadow: inset 0 -1px 0 0 rgba(56, 56, 49, 0.25);
transition: box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
.field-input::placeholder {
color: var(--ink-dim);
font-family: "Newsreader", Georgia, serif;
font-style: italic;
font-size: 17px;
}
.field-input:focus {
background: #eae3d0;
box-shadow: inset 0 -2px 0 0 var(--walnut);
}
.field-input.is-error {
box-shadow: inset 0 -2px 0 0 var(--crimson);
}
.field-input:disabled { opacity: 0.55; cursor: default; }
/* ───── Welcome-step wordmark (centered in the right half) ───── */
.welcome-logo {
position: fixed;
top: 50%;
left: 75%;
transform: translate(-50%, -50%);
width: 280px;
height: auto;
opacity: 0;
pointer-events: none;
z-index: 5;
transition: opacity 640ms var(--ease) 120ms;
}
body:has(#step-welcome.is-active) .welcome-logo {
opacity: 0.92;
}
/* "Backed by Innovationsfonden" — sits directly beneath the fixed
welcome-logo at the same horizontal centre (left:75%). Fades in
with the welcome step (same trigger as the logo above it). */
.welcome-backer {
position: fixed;
/* Sits below the fixed welcome-logo. The logo renders ~70px tall
at width:280px, so its bottom edge is ~50% + 35px; this sits
clear of that with enough breathing room not to crowd the
wordmark. Horizontal nudge via the transform pushes the block
slightly right of the logo's centreline so it reads as a
support line rather than a baseline caption. */
top: calc(50% + 80px);
left: 75%;
transform: translate(calc(-38% - 5px), 0);
display: inline-flex;
align-items: center;
gap: 10px;
font-family: "Manrope", system-ui, -apple-system, sans-serif;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-soft);
opacity: 0;
pointer-events: none;
z-index: 5;
transition: opacity 640ms var(--ease) 160ms;
}
.welcome-backer svg { height: 24px; width: auto; display: block; }
body:has(#step-welcome.is-active) .welcome-backer {
opacity: 0.85;
}
/* "Part of BioInnovation Institute AI Lab" — sits directly below
the welcome-backer line. Same horizontal anchor (left:75%) and
transform offset, just nudged down so the two lines stack with
consistent breathing room. Fades in with the welcome step. */
.welcome-bii {
position: fixed;
top: calc(50% + 112px);
left: 75%;
transform: translate(calc(-38% - 5px), 0);
font-family: "Manrope", system-ui, -apple-system, sans-serif;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--ink-soft);
opacity: 0;
pointer-events: none;
z-index: 5;
transition: opacity 640ms var(--ease) 200ms;
}
body:has(#step-welcome.is-active) .welcome-bii {
opacity: 0.85;
}
/* ───── Welcome ───── */
.welcome-title {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-weight: 400;
font-size: 54px;
line-height: 1.05;
letter-spacing: -0.022em;
color: var(--ink);
margin: 0 0 28px 0;
text-wrap: pretty;
}
/* The terminal keyword — per the Definitive Emphasis rule:
Newsreader Bold Italic on the last word, followed by the
absolute period. Applies to both "Thanks for your interest,
Erik." (name) and "Thank you for your interest." (no name). */
.welcome-title em {
font-style: italic;
font-weight: 700;
}
.welcome-body {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-weight: 400;
font-size: 20px;
line-height: 1.55;
color: var(--ink);
max-width: 620px;
margin: 0 0 20px 0;
text-wrap: pretty;
}
.welcome-body em { font-style: italic; font-weight: 700; }
/* Two-line definition block: bold-italic term + short definition. */
.welcome-define {
max-width: 620px;
margin: 0 0 18px 0;
}
.welcome-term {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-weight: 500;
font-size: 22px;
line-height: 1.2;
color: var(--ink);
margin: 0 0 2px 0;
}
.welcome-term em {
font-style: italic;
font-weight: 700;
}
.welcome-def {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-weight: 400;
font-size: 19px;
line-height: 1.5;
color: var(--ink-soft);
margin: 0;
text-wrap: pretty;
}
.welcome-def em {
font-style: italic;
font-weight: 700;
color: var(--ink);
}
.welcome-cta {
all: unset;
display: inline-flex;
align-items: center;
gap: 14px;
margin-top: 20px;
padding: 16px 24px;
background: #fffcf7;
color: var(--ink);
cursor: pointer;
box-shadow:
0 0 0 0.5px rgba(56,56,49,0.06),
0 18px 32px -18px rgba(56,56,49,0.22),
0 2px 6px -3px rgba(56,56,49,0.08);
transition:
background var(--dur) var(--ease),
box-shadow var(--dur) var(--ease);
animation: welcome-breath 2800ms var(--ease) infinite;
}
.welcome-cta:hover {
background: #fffbf2;
box-shadow:
0 0 0 0.5px rgba(56,56,49,0.10),
0 24px 40px -20px rgba(56,56,49,0.28),
0 3px 8px -4px rgba(56,56,49,0.10);
}
.welcome-cta .c-label {
font-family: "Newsreader", Georgia, serif;
font-size: 19px;
font-weight: 400;
letter-spacing: -0.01em;
color: var(--ink);
line-height: 1;
}
.welcome-cta .c-icon {
flex-shrink: 0;
color: var(--ink-soft);
display: block;
}
.welcome-cta .c-arrow {
font-family: "Newsreader", Georgia, serif;
font-style: italic;
font-size: 21px;
color: var(--crimson);
line-height: 1;
transition: transform var(--dur) var(--ease);
}
.welcome-cta:hover .c-arrow {
transform: translateX(4px);
}
@keyframes welcome-breath {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(5px); }
}
/* ───── Post-submit acknowledgement ───── */
.ack {
margin-top: 16px;
font-family: "Newsreader", Georgia, serif;
font-style: italic;
font-size: 15px;
color: var(--ink-soft);
min-height: 22px;
opacity: 0;
transform: translateY(-4px);
transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.ack.is-visible { opacity: 1; transform: translateY(0); }
.ack.is-error { color: var(--crimson); }
@media (max-width: 720px) {
.entrance { padding: 0 28px; }
.tagline { font-size: 26px; margin-bottom: 32px; }
.currents { opacity: 0.5; }
.welcome-title { font-size: 38px; }
.welcome-body { font-size: 18px; }
.welcome-logo { display: none; }
.welcome-backer { display: none; }
.welcome-bii { display: none; }
}
</style>
</head>
<body class="is-pending">
<div class="currents" id="currents" aria-hidden="true"></div>
<img class="welcome-logo" src="/fenja/fenja-wordmark-black.svg" alt="Fenja" aria-hidden="true" />
<div class="welcome-backer" aria-label="Backed by Innovationsfonden" aria-hidden="true">
<span>Backed by</span>
<!-- Simplified Innovationsfonden wordmark — same redrawn lockup
as the hero's .support block. Not their official logo, a
respectful representation. -->
<svg viewBox="0 0 190 20" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<g fill="#3c6b6b">
<path d="M4 2 L12 18 L10 2 Z" />
<text x="18" y="15" font-family="Manrope, sans-serif" font-weight="600" font-size="13" letter-spacing="0.2" fill="#3c6b6b">nnovationsfonden</text>
</g>
</svg>
</div>
<div class="welcome-bii" aria-hidden="true">
Part of BioInnovation Institute AI Lab
</div>
<main class="entrance">
<div class="entrance-inner">
<!-- STEP 1 — EMAIL -->
<section class="step is-active" id="step-email">
<p class="tagline">
An introduction to Fenja AI.
</p>
<form class="field" id="email-form" novalidate>
<input
type="email"
class="field-input"
id="email-input"
name="email"
autocomplete="email"
spellcheck="false"
placeholder="your email"
aria-label="Email address"
required
/>
<div class="ack" id="email-ack" aria-live="polite"></div>
</form>
</section>
<!-- STEP 2 — WELCOME -->
<!-- The title is set dynamically by entrance.js:
with first name: "Welcome, <em>Erik.</em>"
without first name: "<em>Welcome.</em>"
Static fallback text (for no-JS) renders the anonymous variant. -->
<section class="step" id="step-welcome">
<h1 class="welcome-title" id="welcome-title">
<em>Welcome.</em>
</h1>
<p class="welcome-body">
In this short walkthrough, we want to introduce Fenja AI &mdash; the
company and the platform &mdash; and the initiative around it,
Project Bifrost. The aim is straightforward: to show why trusted,
sovereign AI matters now, what Fenja is, and how it is being built
in Denmark and Europe.
</p>
<div class="welcome-define">
<h3 class="welcome-term"><em>Fenja AI</em></h3>
<p class="welcome-def">The company and platform for sovereign and safe AI.</p>
</div>
<div class="welcome-define">
<h3 class="welcome-term"><em>Project Bifrost</em></h3>
<p class="welcome-def">The initiative shaping Fenja AI together with a select group of Danish and European organisations.</p>
</div>
<button type="button" class="welcome-cta" id="welcome-continue">
<svg class="c-icon" width="20" height="20" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.3"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 4.5c2.5-.7 5-.7 8 .5C15 4 17.5 3.8 20 4.5v14c-2.5-.7-5-.5-8 .5-3-1-5.5-1.2-8-.5v-14Z"/>
<path d="M12 5v14"/>
</svg>
<span class="c-label">Start the introduction</span>
<span class="c-arrow" aria-hidden="true">&rarr;</span>
</button>
</section>
</div>
</main>
<script src="/entrance.js" defer></script>
</body>
</html>