From b3bd5e4af621391c831322fad342f48c76a5ca7d Mon Sep 17 00:00:00 2001 From: Jonathan Hvid Date: Wed, 10 Jun 2026 15:43:14 +0200 Subject: [PATCH] credits: hide AI Lab affiliation only for alz@bii.dk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore the "Part of AI Lab" credit block in all three views and hide it client-side once /auth/me (or fresh login) identifies the viewer as alz@bii.dk. Everyone else sees it as before. Marked with data-ailab; hidden via inline display:none since the flex containers override the [hidden] attribute. No inline scripts — logic lives in the existing page JS, CSP stays script-src 'self'. Co-Authored-By: Claude Opus 4.8 (1M context) --- protected/index.html | 5 +++++ protected/mobile/index.html | 5 +++++ protected/mobile/mobile.js | 18 ++++++++++++++++++ protected/timeline.js | 17 +++++++++++++++++ public/entrance.html | 5 +++++ public/entrance.js | 19 +++++++++++++++++++ 6 files changed, 69 insertions(+) diff --git a/protected/index.html b/protected/index.html index bcb5ad2..e115a1a 100644 --- a/protected/index.html +++ b/protected/index.html @@ -2681,6 +2681,11 @@ html { Innofounder Innovationsfonden +
+ Part of + AI Lab + BioInnovation Institute +
Part of The Regulatory AI-Sandbox diff --git a/protected/mobile/index.html b/protected/mobile/index.html index ea32f57..db0c44b 100644 --- a/protected/mobile/index.html +++ b/protected/mobile/index.html @@ -166,6 +166,11 @@ Innofounder Innovationsfonden
+
+ Part of + AI Lab + BioInnovation Institute +
Part of The Regulatory AI-Sandbox diff --git a/protected/mobile/mobile.js b/protected/mobile/mobile.js index 20e02d2..429a99f 100644 --- a/protected/mobile/mobile.js +++ b/protected/mobile/mobile.js @@ -21,12 +21,30 @@ // protected/mobile/index.html and never by the desktop view. // ───────────────────────────────────────────────────────────── +/* ───── AI Lab credit visibility ───── + The "Part of AI Lab" affiliation credit is shown to everyone except + one viewer, who has asked that it never appear while they present. + Hidden client-side once /auth/me returns the email. Compared + lower-cased so casing doesn't matter; the container is display:flex, + so an inline display:none is used (it beats the stylesheet rule, + where the [hidden] attribute would not). ───── */ +const AILAB_HIDE_EMAIL = 'alz@bii.dk'; +function applyAilabVisibility(email) { + if (!email || email.trim().toLowerCase() !== AILAB_HIDE_EMAIL) return; + document.querySelectorAll('[data-ailab]').forEach((el) => { + el.style.display = 'none'; + }); +} + (async function checkSession() { try { const res = await fetch('/auth/me', { credentials: 'same-origin' }); if (!res.ok) { window.location.href = '/'; + return; } + const data = await res.json().catch(() => ({})); + applyAilabVisibility(data.email); } catch { // Network error — do not boot the user out; desktop behaviour is // the same. If the next action actually needs the server, we'll diff --git a/protected/timeline.js b/protected/timeline.js index 3b885f6..a05ed7f 100644 --- a/protected/timeline.js +++ b/protected/timeline.js @@ -465,6 +465,22 @@ document.querySelectorAll('.dot-btn').forEach(btn => { }); +/* ───────────────────────────────────────────────────────────── + AI Lab credit visibility — the "Part of AI Lab" affiliation in the + hero foot is shown to everyone except one viewer, who has asked that + it never appear while they present. Hidden client-side once /auth/me + returns the email. Compared lower-cased so casing doesn't matter; + the container is display:flex, so an inline display:none is used (it + beats the stylesheet rule, where the [hidden] attribute would not). + ───────────────────────────────────────────────────────────── */ +const AILAB_HIDE_EMAIL = 'alz@bii.dk'; +function applyAilabVisibility(email) { + if (!email || email.trim().toLowerCase() !== AILAB_HIDE_EMAIL) return; + document.querySelectorAll('[data-ailab]').forEach((el) => { + el.style.display = 'none'; + }); +} + /* ───────────────────────────────────────────────────────────── First name propagation — fetched from /auth/me on load. Used by Scene 3 ("This is why we've invited you, [Name]."). @@ -477,6 +493,7 @@ document.querySelectorAll('.dot-btn').forEach(btn => { if (res.ok) { const data = await res.json().catch(() => ({})); window.__fenjaFirstName = data.firstName || null; + applyAilabVisibility(data.email); } } catch { // Offline — leave undefined; bifrost.js falls back to the diff --git a/public/entrance.html b/public/entrance.html index 4ab2542..bcdb8ee 100644 --- a/public/entrance.html +++ b/public/entrance.html @@ -377,6 +377,11 @@ Innofounder Innovationsfonden
+
+ Part of + AI Lab + BioInnovation Institute +
Part of The Regulatory AI-Sandbox diff --git a/public/entrance.js b/public/entrance.js index d0cf192..85f3d41 100644 --- a/public/entrance.js +++ b/public/entrance.js @@ -53,6 +53,21 @@ requestAnimationFrame(() => setTimeout(() => wrap.classList.add('is-ready'), 120)); })(); +/* ───── AI Lab credit visibility ───── + The "Part of AI Lab" affiliation credit is shown to everyone except + one viewer, who has asked that it never appear while they present. + Hidden client-side once we know the email — compared lower-cased so + casing in the invite list or the typed address doesn't matter. The + container is display:flex, so an inline display:none is used (it beats + the stylesheet rule; the [hidden] attribute would not). ───── */ +const AILAB_HIDE_EMAIL = 'alz@bii.dk'; +function applyAilabVisibility(email) { + if (!email || email.trim().toLowerCase() !== AILAB_HIDE_EMAIL) return; + document.querySelectorAll('[data-ailab]').forEach((el) => { + el.style.display = 'none'; + }); +} + /* ───── Step transitions ───── */ const steps = { email: document.getElementById('step-email'), @@ -146,6 +161,9 @@ emailForm.addEventListener('submit', async (e) => { // welcome step and advance. const data = await res.json().catch(() => ({})); setWelcomeTitle(data.firstName || null); + // /auth/login returns {ok, firstName} — no email — so use the + // address the visitor just authenticated with. + applyAilabVisibility(email); setAck(emailAck, '', false); showStep('welcome'); } catch (err) { @@ -173,6 +191,7 @@ document.getElementById('welcome-continue').addEventListener('click', () => { authed = true; const data = await res.json().catch(() => ({})); firstName = data.firstName || null; + applyAilabVisibility(data.email); } } catch { /* offline — fall through to email */ }