customer-presentation/public/entrance.html
Jonathan Hvid 9703d47407 credits: redesign supporter lockup + mobile parity pass
Rework the supporter credits ("Backed by" / "Part of") into a
three-tier lockup — a small uppercase label over an upright Newsreader
serif name, with the parent body / issuing authority in a quieter
serif beneath — so the credits read in the deck's editorial voice
instead of as a foreign sans-serif caption. Applied consistently
across all three views:

- Entrance welcome screen: replaced three separately position:fixed
  blocks (with hand-tuned top offsets) with one centred .welcome-credits
  lockup; drops the brittle magic-number stacking.
- Timeline hero ("Fenja introduction"): left-aligned .support-credit
  stack in place of the old .support / .support-bii lines.
- Mobile hero: matching .m-credit stack replacing .m-support / .m-backer.

Credits now read: Backed by Innofounder (Innovationsfonden); Part of
AI Lab (BioInnovation Institute); Part of The AI Regulatory Sandbox
(Datatilsynet & Digitaliseringsstyrelsen).

Also brings the mobile view to parity with the customer-facing desktop
deck: updated hero copy, platform-question framing, architecture layers,
Wiki deep-dive, deployment cards, and implementation roadmap; removes the
old "Join Project Bifrost" CTA + footer (mobile.js loses the join
handler, keeps the session check).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 14:08:19 +02:00

459 lines
14 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 brand lockup (centered in the right half) ─────
One fixed, centred container holding the Fenja wordmark and its
credits (funder + affiliations). Stacking them in a single
centred flex column — rather than three separately-pinned fixed
elements with hand-tuned top offsets — keeps the credits balanced
beneath the logo no matter how many lines they run to, and lets
the longest affiliation line wrap cleanly within a fixed width.
The whole group fades in together when the welcome step is
active. Hidden entirely on narrow screens (see the media query). */
.welcome-lockup {
position: fixed;
top: 50%;
left: 75%;
transform: translate(-50%, -50%);
width: clamp(280px, 32vw, 360px);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
opacity: 0;
pointer-events: none;
z-index: 5;
transition: opacity 640ms var(--ease) 120ms;
}
body:has(#step-welcome.is-active) .welcome-lockup {
opacity: 1;
}
.welcome-logo {
width: 250px;
max-width: 100%;
height: auto;
opacity: 0.92;
}
/* Hairline divider between the wordmark and the credits. */
.welcome-rule {
width: 56px;
height: 1px;
margin: 26px 0 24px;
background: var(--ink-soft);
opacity: 0.28;
}
/* Credits — funder + affiliations, rendered in the deck's editorial
voice: a small uppercase Manrope label over each entity name set
in Newsreader serif italic. This ties the credits to the Fenja
wordmark above (and to the serif headlines elsewhere) instead of
reading as a sans-serif caption stuck beneath the logo. */
.welcome-credits {
display: flex;
flex-direction: column;
gap: 20px;
}
.welcome-credit {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.welcome-credit-label {
font-family: "Manrope", system-ui, -apple-system, sans-serif;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.24em;
text-transform: uppercase;
color: var(--ink-dim);
}
.welcome-credit-name {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-style: normal;
font-weight: 500;
font-size: 21px;
line-height: 1.25;
letter-spacing: 0.005em;
color: var(--ink);
text-wrap: balance;
}
/* Parent body / issuing authority beneath an affiliation name —
quieter serif so the name above keeps the spotlight. */
.welcome-credit-auth {
font-family: "Newsreader", Georgia, "Times New Roman", serif;
font-style: normal;
font-size: 15px;
line-height: 1.3;
color: var(--ink-soft);
text-wrap: balance;
}
/* ───── 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-lockup { display: none; }
}
</style>
</head>
<body class="is-pending">
<div class="currents" id="currents" aria-hidden="true"></div>
<!-- Welcome-step brand lockup: the Fenja wordmark with its funder +
affiliation credits, centred in the right half of the screen.
Whole group is decorative (the real content is the entrance form),
so it's aria-hidden. -->
<div class="welcome-lockup" aria-hidden="true">
<img class="welcome-logo" src="/fenja/fenja-wordmark-black.svg" alt="" />
<span class="welcome-rule"></span>
<div class="welcome-credits">
<div class="welcome-credit">
<span class="welcome-credit-label">Backed by</span>
<span class="welcome-credit-name">Innofounder</span>
<span class="welcome-credit-auth">Innovationsfonden</span>
</div>
<div class="welcome-credit">
<span class="welcome-credit-label">Part of</span>
<span class="welcome-credit-name">AI Lab</span>
<span class="welcome-credit-auth">BioInnovation Institute</span>
</div>
<div class="welcome-credit">
<span class="welcome-credit-label">Part of</span>
<span class="welcome-credit-name">The AI Regulatory Sandbox</span>
<span class="welcome-credit-auth">Datatilsynet &amp; Digitaliseringsstyrelsen</span>
</div>
</div>
</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>