text changes and text design
This commit is contained in:
parent
d5f578a581
commit
69a7f62ae6
4 changed files with 231 additions and 52 deletions
|
|
@ -62,7 +62,17 @@
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ───────── Site wordmark — top-left masthead ───────── */
|
/* ───────── Site wordmark — top-left masthead, clickable "home" link ───────── */
|
||||||
|
.site-mark,
|
||||||
|
.site-mark:link,
|
||||||
|
.site-mark:visited,
|
||||||
|
.site-mark:hover,
|
||||||
|
.site-mark:active,
|
||||||
|
.site-mark:focus,
|
||||||
|
.site-mark:focus-visible {
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
.site-mark {
|
.site-mark {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 28px;
|
top: 28px;
|
||||||
|
|
@ -70,17 +80,34 @@
|
||||||
width: 118px;
|
width: 118px;
|
||||||
height: auto;
|
height: auto;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity var(--dur, 200ms) var(--ease, ease);
|
||||||
|
}
|
||||||
|
.site-mark img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
pointer-events: none; /* keeps clicks on the anchor, not the image */
|
||||||
|
}
|
||||||
|
.site-mark:hover,
|
||||||
|
.site-mark:focus-visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.site-mark:focus-visible {
|
||||||
|
outline: 2px solid var(--walnut, #785f53);
|
||||||
|
outline-offset: 6px;
|
||||||
}
|
}
|
||||||
@media (max-width: 720px) {
|
@media (max-width: 720px) {
|
||||||
.site-mark { width: 90px; top: 20px; left: 22px; }
|
.site-mark { width: 90px; top: 20px; left: 22px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Page overline title — large, sits lower on the front matter so it reads */
|
/* Page overline title — large, sits in the upper third of the viewport
|
||||||
|
so the long page-sub body below it has room without clipping. */
|
||||||
.page-title {
|
.page-title {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 80px; top: 42vh;
|
left: 80px; top: 22vh;
|
||||||
font-family: "Newsreader", Georgia, serif;
|
font-family: "Newsreader", Georgia, serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 54px;
|
font-size: 54px;
|
||||||
|
|
@ -98,17 +125,21 @@
|
||||||
}
|
}
|
||||||
.page-title + .page-sub {
|
.page-title + .page-sub {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 80px; top: calc(42vh + 220px);
|
left: 80px; top: calc(22vh + 160px);
|
||||||
max-width: 560px;
|
max-width: 720px;
|
||||||
|
/* Upright serif editorial body, ink colour, 23px (about 15%
|
||||||
|
larger than the welcome-page body) so the long intro reads
|
||||||
|
at ease. Only the <em> spans carry italics for emphasis. */
|
||||||
font-family: "Newsreader", Georgia, serif;
|
font-family: "Newsreader", Georgia, serif;
|
||||||
font-style: italic;
|
font-weight: 400;
|
||||||
font-size: 19px;
|
font-size: 23px;
|
||||||
line-height: 1.5;
|
line-height: 1.52;
|
||||||
color: var(--ink-soft);
|
color: var(--ink);
|
||||||
z-index: 15;
|
z-index: 15;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 520ms var(--ease), transform 520ms var(--ease);
|
transition: opacity 520ms var(--ease), transform 520ms var(--ease);
|
||||||
}
|
}
|
||||||
|
.page-sub em { font-style: italic; font-weight: 700; color: var(--ink); }
|
||||||
/* Once the timeline has been advanced, the front matter steps aside */
|
/* Once the timeline has been advanced, the front matter steps aside */
|
||||||
.page-timeline.is-scrolled .page-title,
|
.page-timeline.is-scrolled .page-title,
|
||||||
.page-timeline.is-scrolled .page-sub {
|
.page-timeline.is-scrolled .page-sub {
|
||||||
|
|
@ -117,6 +148,71 @@
|
||||||
transform: translateY(-12px);
|
transform: translateY(-12px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ───────── First-load scroll hint ─────────
|
||||||
|
Right-edge prompt telling the reader to begin scrolling the
|
||||||
|
horizontal timeline. Vertically centered, horizontal layout
|
||||||
|
(label then arrow), editorial ink colour. Arrow pulses
|
||||||
|
rightward to hint at the scroll direction. Fades out as soon
|
||||||
|
as the reader advances — same `.is-scrolled` class the
|
||||||
|
front-matter uses. */
|
||||||
|
.timeline-scroll-hint {
|
||||||
|
position: absolute;
|
||||||
|
right: clamp(32px, 3.8vw, 72px);
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 22px;
|
||||||
|
color: var(--ink);
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
animation: ts-fade-in 700ms 500ms var(--ease) forwards;
|
||||||
|
transition: opacity 360ms var(--ease), transform 360ms var(--ease);
|
||||||
|
}
|
||||||
|
.ts-label {
|
||||||
|
font-family: "Newsreader", Georgia, serif;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: clamp(22px, 2.1vw, 30px);
|
||||||
|
letter-spacing: -0.005em;
|
||||||
|
line-height: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ts-arrow {
|
||||||
|
width: clamp(84px, 8vw, 120px);
|
||||||
|
height: auto;
|
||||||
|
color: var(--ink);
|
||||||
|
animation: ts-arrow-nudge 1800ms cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
||||||
|
}
|
||||||
|
@keyframes ts-fade-in {
|
||||||
|
from { opacity: 0; transform: translate(14px, -50%); }
|
||||||
|
to { opacity: 1; transform: translate(0, -50%); }
|
||||||
|
}
|
||||||
|
@keyframes ts-arrow-nudge {
|
||||||
|
0%, 100% { transform: translateX(0); opacity: 0.9; }
|
||||||
|
50% { transform: translateX(14px); opacity: 1; }
|
||||||
|
}
|
||||||
|
/* Fade out on the very first wheel tick (`.hint-dismissed` is set
|
||||||
|
in timeline.js's onWheel handler, independent of the 40px
|
||||||
|
`.is-scrolled` threshold so the hint leaves instantly).
|
||||||
|
`animation: none` is required to override the entry ts-fade-in
|
||||||
|
animation (which has forwards fill-mode and outranks this rule
|
||||||
|
otherwise); ts-arrow-nudge is also stopped so the pulse doesn't
|
||||||
|
keep ticking behind the fade. */
|
||||||
|
.page-timeline.hint-dismissed .timeline-scroll-hint {
|
||||||
|
animation: none;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(14px, -50%);
|
||||||
|
}
|
||||||
|
.page-timeline.hint-dismissed .ts-arrow {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.timeline-scroll-hint { animation: none; opacity: 1; }
|
||||||
|
.ts-arrow { animation: none; }
|
||||||
|
}
|
||||||
|
|
||||||
/* ───────── Dot-nav ─────────
|
/* ───────── Dot-nav ─────────
|
||||||
5px dots, filled when active, outlined ring otherwise. Labels hidden
|
5px dots, filled when active, outlined ring otherwise. Labels hidden
|
||||||
by default and appear as a floating tooltip above the dot on hover.
|
by default and appear as a floating tooltip above the dot on hover.
|
||||||
|
|
@ -438,17 +534,19 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 28px;
|
gap: 28px;
|
||||||
padding: 32px 44px;
|
padding: 32px 44px;
|
||||||
background: var(--paper-high);
|
/* Inverted palette — crimson field, paper ink — so the button
|
||||||
color: var(--ink);
|
pops out against the timeline's warm paper background. */
|
||||||
|
background: var(--crimson);
|
||||||
|
color: var(--paper);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 30;
|
z-index: 30;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translate(36px, -50%);
|
transform: translate(36px, -50%);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 0 0 0.5px rgba(56,56,49,0.08),
|
0 0 0 0.5px rgba(138,58,47,0.22),
|
||||||
0 26px 48px -22px rgba(56,56,49,0.28),
|
0 28px 52px -20px rgba(138,58,47,0.45),
|
||||||
0 3px 10px -4px rgba(56,56,49,0.10);
|
0 4px 12px -5px rgba(138,58,47,0.24);
|
||||||
transition:
|
transition:
|
||||||
opacity 520ms var(--ease),
|
opacity 520ms var(--ease),
|
||||||
transform 520ms var(--ease),
|
transform 520ms var(--ease),
|
||||||
|
|
@ -466,11 +564,12 @@
|
||||||
50% { transform: translate(6px, -50%); }
|
50% { transform: translate(6px, -50%); }
|
||||||
}
|
}
|
||||||
.continue-btn:hover {
|
.continue-btn:hover {
|
||||||
background: #fffbf2;
|
/* Slight darken on hover so the inverted card still signals it's interactive. */
|
||||||
|
background: #7a3229;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 0 0 0.5px rgba(56,56,49,0.12),
|
0 0 0 0.5px rgba(122,50,41,0.32),
|
||||||
0 32px 56px -22px rgba(56,56,49,0.34),
|
0 34px 60px -20px rgba(122,50,41,0.55),
|
||||||
0 4px 12px -5px rgba(56,56,49,0.12);
|
0 5px 14px -5px rgba(122,50,41,0.32);
|
||||||
}
|
}
|
||||||
.continue-btn .c-icon {
|
.continue-btn .c-icon {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
@ -478,7 +577,7 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 72px;
|
width: 72px;
|
||||||
height: 72px;
|
height: 72px;
|
||||||
color: var(--crimson);
|
color: var(--paper);
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
transition: transform var(--dur) var(--ease);
|
transition: transform var(--dur) var(--ease);
|
||||||
}
|
}
|
||||||
|
|
@ -495,14 +594,15 @@
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
letter-spacing: -0.015em;
|
letter-spacing: -0.015em;
|
||||||
color: var(--ink);
|
color: var(--paper);
|
||||||
line-height: 1.08;
|
line-height: 1.08;
|
||||||
max-width: 13ch;
|
max-width: 13ch;
|
||||||
}
|
}
|
||||||
.continue-btn .c-label em {
|
.continue-btn .c-label em {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--crimson);
|
/* Italic emphasis stays on paper colour so it reads against the crimson field. */
|
||||||
|
color: var(--paper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ───────── Overview page ───────── */
|
/* ───────── Overview page ───────── */
|
||||||
|
|
@ -676,8 +776,8 @@
|
||||||
|
|
||||||
/* Short-viewport safety: collapse the page-title block so cards never collide */
|
/* Short-viewport safety: collapse the page-title block so cards never collide */
|
||||||
@media (max-height: 620px) {
|
@media (max-height: 620px) {
|
||||||
.page-title { font-size: 36px; max-width: 640px; top: 38vh; }
|
.page-title { font-size: 36px; max-width: 640px; top: 18vh; }
|
||||||
.page-title + .page-sub { font-size: 16px; top: calc(38vh + 160px); }
|
.page-title + .page-sub { font-size: 21px; top: calc(18vh + 160px); }
|
||||||
}
|
}
|
||||||
@media (max-height: 500px) {
|
@media (max-height: 500px) {
|
||||||
.page-title { display: none; }
|
.page-title { display: none; }
|
||||||
|
|
@ -732,8 +832,11 @@
|
||||||
padding-bottom: clamp(6rem, 16vh, 11rem);
|
padding-bottom: clamp(6rem, 16vh, 11rem);
|
||||||
}
|
}
|
||||||
#page-overview #hero .hero-wrap {
|
#page-overview #hero .hero-wrap {
|
||||||
/* Constrain to the left column so Europe is visible to its right. */
|
/* Constrain to the left column so Europe is visible to its right.
|
||||||
max-width: 62ch;
|
Widened from 62ch to 74ch (~+20%) so the new longer hero lede
|
||||||
|
("Fenja AI is a sovereign AI platform…") sits comfortably on
|
||||||
|
fewer lines. */
|
||||||
|
max-width: 74ch;
|
||||||
/* Zeroed: wrap padding-top was adding down-drift inside the centered
|
/* Zeroed: wrap padding-top was adding down-drift inside the centered
|
||||||
container, pushing the hero-foot toward the dot-nav. Vertical
|
container, pushing the hero-foot toward the dot-nav. Vertical
|
||||||
position is now controlled entirely by #hero's asymmetric padding. */
|
position is now controlled entirely by #hero's asymmetric padding. */
|
||||||
|
|
@ -769,7 +872,7 @@
|
||||||
--type-body: "Manrope", ui-sans-serif, system-ui, sans-serif;
|
--type-body: "Manrope", ui-sans-serif, system-ui, sans-serif;
|
||||||
--type-display: "Newsreader", Georgia, serif;
|
--type-display: "Newsreader", Georgia, serif;
|
||||||
|
|
||||||
--step-hero: clamp(2.4rem, 6.2vw, 5.4rem);
|
--step-hero: clamp(2rem, 5.1vw, 4.4rem);
|
||||||
--step-xl: clamp(1.8rem, 4.8vw, 4rem);
|
--step-xl: clamp(1.8rem, 4.8vw, 4rem);
|
||||||
--step-lg: clamp(1.35rem, 3vw, 2.2rem);
|
--step-lg: clamp(1.35rem, 3vw, 2.2rem);
|
||||||
--step-md: clamp(1rem, 1.4vw, 1.15rem);
|
--step-md: clamp(1rem, 1.4vw, 1.15rem);
|
||||||
|
|
@ -850,11 +953,11 @@ html {
|
||||||
font-family: var(--type-display);
|
font-family: var(--type-display);
|
||||||
font-weight: 330;
|
font-weight: 330;
|
||||||
font-size: var(--step-hero);
|
font-size: var(--step-hero);
|
||||||
line-height: 1.02;
|
line-height: 1.06;
|
||||||
letter-spacing: -0.03em;
|
letter-spacing: -0.025em;
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
max-width: 22ch;
|
max-width: 30ch;
|
||||||
}
|
}
|
||||||
.hero-title em {
|
.hero-title em {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
|
@ -1879,15 +1982,21 @@ html {
|
||||||
}
|
}
|
||||||
.join-confirmation .confirm-headline {
|
.join-confirmation .confirm-headline {
|
||||||
font-family: var(--type-display);
|
font-family: var(--type-display);
|
||||||
font-weight: 330;
|
/* Matched to .join-cta .join-headline so pressing the CTA doesn't
|
||||||
font-size: clamp(2rem, 5vw, 3.6rem);
|
shrink the page's visual anchor — the confirmation keeps the
|
||||||
line-height: 1.06;
|
same stature, only the copy changes. */
|
||||||
letter-spacing: -0.03em;
|
font-weight: 320;
|
||||||
|
font-size: clamp(2.4rem, 6.2vw, 5.4rem);
|
||||||
|
line-height: 1.04;
|
||||||
|
letter-spacing: -0.035em;
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 22ch;
|
max-width: 20ch;
|
||||||
}
|
}
|
||||||
.join-confirmation .confirm-headline em {
|
.join-confirmation .confirm-headline em {
|
||||||
|
/* Italics preserved for emphasis; accent colour keeps the editorial
|
||||||
|
weight without the aurora gradient (which is reserved for S4
|
||||||
|
and the pre-click CTA). */
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
font-weight: 380;
|
font-weight: 380;
|
||||||
|
|
@ -2203,12 +2312,17 @@ html {
|
||||||
</head>
|
</head>
|
||||||
<body data-screen-label="01 Timeline">
|
<body data-screen-label="01 Timeline">
|
||||||
|
|
||||||
<img class="site-mark" src="/fenja/fenja-wordmark-black.svg" alt="Fenja" aria-hidden="true" />
|
<a class="site-mark" href="/" aria-label="Back to the front page">
|
||||||
|
<img src="/fenja/fenja-wordmark-black.svg" alt="Fenja" />
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- ───── Page 1 : TIMELINE ───── -->
|
<!-- ───── Page 1 : TIMELINE ───── -->
|
||||||
<section class="page page-timeline is-active" id="page-timeline" data-screen-label="01 Timeline">
|
<section class="page page-timeline is-active" id="page-timeline" data-screen-label="01 Timeline">
|
||||||
<div class="page-title">From the promise of AI to the loss of <em>sovereignty.</em></div>
|
<div class="page-title">When AI runs Europe, who runs the <em>AI?</em></div>
|
||||||
<div class="page-sub">Twenty-three headlines, quietly laid across a tinted map. Scroll the wheel — the map turns with you.</div>
|
<div class="page-sub">
|
||||||
|
We’ve spent years building data and AI across Denmark and Europe, watching one dependency harden after another. AI is different. The United States has made that clear. China has made that clear. You cannot stand strong in this century on AI you do not control — and for the first time in a generation, Europe has both the reason and the moment to build its own. The window is closing faster than most realise. It is open now. It will not be open long.<br/><br/>
|
||||||
|
As AI moves into our hospitals, our courts, our defence, our schools — can we afford for the switch to sit in <em>Washington?</em>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Globe ghost -->
|
<!-- Globe ghost -->
|
||||||
<div class="globe-wrap" id="globe-wrap"></div>
|
<div class="globe-wrap" id="globe-wrap"></div>
|
||||||
|
|
@ -2231,6 +2345,20 @@ html {
|
||||||
<!-- Year ticks and events injected by JS -->
|
<!-- Year ticks and events injected by JS -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- First-load scroll hint. Vertically centered on the right edge;
|
||||||
|
fades out the moment the reader starts scrolling the timeline
|
||||||
|
(piggybacks on `.is-scrolled`, set in timeline.js after ~40px
|
||||||
|
of scroll travel). -->
|
||||||
|
<div class="timeline-scroll-hint" aria-hidden="true">
|
||||||
|
<span class="ts-label">Scroll to begin</span>
|
||||||
|
<svg class="ts-arrow" viewBox="0 0 56 14" fill="none"
|
||||||
|
stroke="currentColor" stroke-width="1.6"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M2 7 H50"/>
|
||||||
|
<path d="M44 2 L50 7 L44 12"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- ───── Page 2 : OVERVIEW ───── -->
|
<!-- ───── Page 2 : OVERVIEW ───── -->
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,12 @@ function onWheel(e) {
|
||||||
state.target = clamp(state.target + dy * 1.1, 0, state.max);
|
state.target = clamp(state.target + dy * 1.1, 0, state.max);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
kick();
|
kick();
|
||||||
|
|
||||||
|
// Dismiss the scroll hint on the very first wheel tick — instant fade.
|
||||||
|
// A separate class from `.is-scrolled` (which keys off 40px of travel
|
||||||
|
// and controls the front-matter) so the hint goes the moment the
|
||||||
|
// reader commits, not after inertia catches up.
|
||||||
|
document.getElementById('page-timeline')?.classList.add('hint-dismissed');
|
||||||
}
|
}
|
||||||
|
|
||||||
function kick() {
|
function kick() {
|
||||||
|
|
@ -444,6 +450,7 @@ document.querySelectorAll('.dot-btn').forEach(btn => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/* ─────────────────────────────────────────────────────────────
|
/* ─────────────────────────────────────────────────────────────
|
||||||
First name propagation — fetched from /auth/me on load.
|
First name propagation — fetched from /auth/me on load.
|
||||||
Used by Scene 3 ("This is why we've invited you, [Name].").
|
Used by Scene 3 ("This is why we've invited you, [Name].").
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,18 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
padding: 0 112px;
|
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 {
|
.entrance-inner {
|
||||||
max-width: 560px;
|
max-width: 620px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ───── Steps ───── */
|
/* ───── Steps ───── */
|
||||||
|
|
@ -162,15 +170,47 @@
|
||||||
.welcome-body {
|
.welcome-body {
|
||||||
font-family: "Newsreader", Georgia, "Times New Roman", serif;
|
font-family: "Newsreader", Georgia, "Times New Roman", serif;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
max-width: 540px;
|
max-width: 620px;
|
||||||
margin: 0 0 20px 0;
|
margin: 0 0 20px 0;
|
||||||
text-wrap: pretty;
|
text-wrap: pretty;
|
||||||
}
|
}
|
||||||
.welcome-body em { font-style: italic; font-weight: 700; }
|
.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 {
|
.welcome-cta {
|
||||||
all: unset;
|
all: unset;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
@ -246,7 +286,7 @@
|
||||||
.tagline { font-size: 26px; margin-bottom: 32px; }
|
.tagline { font-size: 26px; margin-bottom: 32px; }
|
||||||
.currents { opacity: 0.5; }
|
.currents { opacity: 0.5; }
|
||||||
.welcome-title { font-size: 38px; }
|
.welcome-title { font-size: 38px; }
|
||||||
.welcome-body { font-size: 16.5px; }
|
.welcome-body { font-size: 18px; }
|
||||||
.welcome-logo { display: none; }
|
.welcome-logo { display: none; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -291,16 +331,20 @@
|
||||||
Thank you for your <em>interest.</em>
|
Thank you for your <em>interest.</em>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="welcome-body">
|
<p class="welcome-body">
|
||||||
Thank you for joining and for your interest in enabling sovereign AI
|
This is a personal invitation because we believe your perspective
|
||||||
in Denmark and Europe. Project Bifrost is a deliberate effort to
|
can make a meaningful contribution to an important mission: building
|
||||||
advance it — the conviction that how we build these systems,
|
trusted, sovereign AI for Denmark and Europe. In this short web
|
||||||
and where, will shape the next decades.
|
experience, we will explain why this matters, what Fenja AI is, and
|
||||||
</p>
|
how you, through Project Bifrost, can help shape its future.
|
||||||
<p class="welcome-body">
|
|
||||||
What follows is a timeline: twelve moments that explain why
|
|
||||||
this matters now, and — at the end — a note on how
|
|
||||||
Fenja AI addresses it.
|
|
||||||
</p>
|
</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 created to ensure that Fenja AI is built not just for organisations like yours, but <em>with</em> you.</p>
|
||||||
|
</div>
|
||||||
<button type="button" class="welcome-cta" id="welcome-continue">
|
<button type="button" class="welcome-cta" id="welcome-continue">
|
||||||
<svg class="c-icon" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
<svg class="c-icon" width="20" height="20" viewBox="0 0 24 24" fill="none"
|
||||||
stroke="currentColor" stroke-width="1.3"
|
stroke="currentColor" stroke-width="1.3"
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ function setWelcomeTitle(firstName) {
|
||||||
// Keep DOM construction to textContent + appended <em> — no innerHTML
|
// Keep DOM construction to textContent + appended <em> — no innerHTML
|
||||||
// of unsanitised input. firstName came from the server but we still
|
// of unsanitised input. firstName came from the server but we still
|
||||||
// construct the node tree explicitly for clarity.
|
// construct the node tree explicitly for clarity.
|
||||||
el.textContent = 'Thanks for your interest, ';
|
el.textContent = 'Thank you for your interest, ';
|
||||||
const em = document.createElement('em');
|
const em = document.createElement('em');
|
||||||
em.textContent = firstName + '.';
|
em.textContent = firstName + '.';
|
||||||
el.appendChild(em);
|
el.appendChild(em);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue