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>
480 lines
19 KiB
HTML
480 lines
19 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Archive — stack-scene + words-scene (removed 2026-05-19)</title>
|
||
<style>
|
||
body { font-family: ui-monospace, Menlo, monospace; max-width: 1100px;
|
||
margin: 40px auto; padding: 0 24px; line-height: 1.45; color: #383831; }
|
||
h1 { font-size: 20px; }
|
||
h2 { font-size: 16px; margin-top: 32px; }
|
||
pre { background: #f4efe2; padding: 16px; border-radius: 6px;
|
||
overflow: auto; font-size: 12px; line-height: 1.5; }
|
||
code { font-family: inherit; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>Archive — 4-capabilities (#stack-scene) + "This is why we've invited you" (#words-scene)</h1>
|
||
|
||
<p>These two sections were removed from <code>protected/index.html</code> on 2026-05-19
|
||
when the experience was reframed from a Project Bifrost personal invitation into a
|
||
customer presentation. Kept here so they can be restored.</p>
|
||
|
||
<h2>To restore</h2>
|
||
<ol>
|
||
<li>Copy the <code><template id="stack-scene-html"></code> and
|
||
<code><template id="words-scene-html"></code> contents back into
|
||
<code>#overview-scroll</code> in <code>protected/index.html</code>, between
|
||
<code>#hero</code> and <code>#bifrost</code> (in that order).</li>
|
||
<li>Copy the JS in <code><script type="text/x-archived-js" id="stack-words-js"></code>
|
||
back into <code>protected/bifrost.js</code>, right after the HERO fade-in (the
|
||
<code>gsap.to('.hero-wrap', { opacity: 1, ... })</code> block).</li>
|
||
<li>In <code>bifrost.js</code>, add <code>'stack-scene'</code> and <code>'words-scene'</code>
|
||
back into <code>sceneOrder</code> (between <code>'hero'</code> and <code>'bifrost'</code>),
|
||
add their entries to <code>sceneToDot</code>, and add <code>'words-scene'</code> back to
|
||
the <code>sceneIds</code> array inside <code>collectStickyTargets()</code>.</li>
|
||
<li>Restore the "Capabilities" dot-nav button in <code>protected/index.html</code>:
|
||
<pre><button class="dot-btn" data-target="page-overview" data-scroll-to="stack-scene">
|
||
<span class="dot"></span>
|
||
<span class="label">Capabilities</span>
|
||
</button></pre></li>
|
||
</ol>
|
||
|
||
<h2>HTML — #stack-scene (Scene 2)</h2>
|
||
<template id="stack-scene-html">
|
||
<!-- ============================================================
|
||
SCENE 2 — ARCHITECTURE (pinned, scrubbed)
|
||
============================================================ -->
|
||
<section id="stack-scene" aria-label="The Fenja AI architecture">
|
||
<div class="stack-pin">
|
||
<!-- Title bar: rides along with the pin so it stays visible while
|
||
the reader scrolls through all 4 capability cards. The per-card
|
||
counter now lives inside each .layer-card (see .card-counter
|
||
below), so the title here is a standalone centered lockup. -->
|
||
<div class="stack-title-bar" aria-hidden="true">
|
||
<h2 class="stack-title">The Fenja AI platform in four steps</h2>
|
||
</div>
|
||
<div class="layer-theatre">
|
||
|
||
<!-- LEFT SIDE — explanatory copy, visible only during the grid phase. -->
|
||
<div class="copy-stage" aria-live="polite">
|
||
<div class="copy-layer" data-copy="0">
|
||
<span class="tag">One complete platform</span>
|
||
<h2>Everything you need <em>in one place.</em></h2>
|
||
<p>Fenja AI brings models, knowledge, tools, and agents together in one platform for using and scaling AI across your organisation.</p>
|
||
</div>
|
||
<div class="copy-layer" data-copy="1">
|
||
<span class="tag">Full control</span>
|
||
<h2>Your <strong>infrastructure.</strong><br/>Your <em>rules.</em></h2>
|
||
<p>Fenja AI is installed in your own client-managed environment, giving you full control over data, security, and governance.</p>
|
||
</div>
|
||
<div class="copy-layer" data-copy="2">
|
||
<span class="tag">Sovereignty</span>
|
||
<h2>Built in <strong>Denmark.</strong><br/>Ready for <em>Europe.</em></h2>
|
||
<p>Fenja AI is built in Denmark for European organisations that want trusted, sovereign AI on their own terms.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- LAYER CARDS — drop in, stack, then rearrange to grid -->
|
||
<article class="layer-card" data-layer="0" aria-label="Layer 1: the AI">
|
||
<span class="card-eyebrow">The AI</span>
|
||
<div class="card-box">
|
||
<span class="card-counter" aria-hidden="true">1 / 4</span>
|
||
<span class="card-grid-label" aria-hidden="true">The AI</span>
|
||
<div class="card-content">
|
||
<h3 class="card-title">An <b>open-source</b> model, running on your <em>own hardware.</em></h3>
|
||
<p class="card-body">A state-of-the-art open-source language model deployed directly in your environment. It gives you powerful AI capabilities with full control over data, performance, and security.</p>
|
||
</div>
|
||
<div class="card-brain" aria-hidden="true"></div>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="layer-card" data-layer="1" aria-label="Layer 2: Knowledge">
|
||
<span class="card-eyebrow">The Knowledge</span>
|
||
<div class="card-box">
|
||
<span class="card-counter" aria-hidden="true">2 / 4</span>
|
||
<span class="card-grid-label" aria-hidden="true">The Knowledge</span>
|
||
<div class="card-content">
|
||
<h3 class="card-title">The business context that makes <em>AI understand your world.</em></h3>
|
||
<p class="card-body">A built-in knowledge layer that helps the platform understand your terminology, processes, and data. It retains what matters, improves over time, and gives the AI the context needed to deliver relevant and accurate results.</p>
|
||
</div>
|
||
<div class="card-brain" aria-hidden="true"></div>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="layer-card" data-layer="2" aria-label="Layer 3: Tools">
|
||
<span class="card-eyebrow">The Tools</span>
|
||
<div class="card-box">
|
||
<span class="card-counter" aria-hidden="true">3 / 4</span>
|
||
<span class="card-grid-label" aria-hidden="true">The Tools</span>
|
||
<div class="card-content">
|
||
<h3 class="card-title">How AI <b>acts</b> — not just what it <em>knows.</em></h3>
|
||
<p class="card-body">The capabilities that let the platform do real work across your environment. From search and retrieval to data access, automation, and analysis, these are the tools the AI uses to solve tasks in practice.</p>
|
||
</div>
|
||
<div class="card-brain" aria-hidden="true"></div>
|
||
</div>
|
||
</article>
|
||
|
||
<article class="layer-card" data-layer="3" aria-label="Layer 4: Agents">
|
||
<span class="card-eyebrow">The Agents</span>
|
||
<div class="card-box">
|
||
<span class="card-counter" aria-hidden="true">4 / 4</span>
|
||
<span class="card-grid-label" aria-hidden="true">The Agents</span>
|
||
<div class="card-content">
|
||
<h3 class="card-title">Specialized AI agents <b>working together</b> around <em>real tasks.</em></h3>
|
||
<p class="card-body">Purpose-built agents designed to handle distinct roles and workflows. Fenja AI includes both ready-made agents and the framework to build new ones, so you can orchestrate AI the same way your organisation already works — through specialisation and coordination.</p>
|
||
</div>
|
||
<div class="card-brain" aria-hidden="true"></div>
|
||
</div>
|
||
</article>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<h2>HTML — #words-scene (Scene 3)</h2>
|
||
<template id="words-scene-html">
|
||
<!-- ============================================================
|
||
SCENE 3 — SLIDE 11 — WORDS FLY IN ONE AT A TIME
|
||
============================================================ -->
|
||
<section id="words-scene" aria-labelledby="words-head">
|
||
<h3 id="words-head" class="sr-only" style="position:absolute;left:-9999px;">
|
||
This is why we've invited you. To ensure Fenja AI is not just built for you, but with you.
|
||
</h3>
|
||
<div class="words-pin">
|
||
<p class="words" aria-hidden="true" id="words-sentence">
|
||
<span class="w">This</span>
|
||
<span class="w">is</span>
|
||
<span class="w">why</span>
|
||
<span class="w">we’ve</span>
|
||
<span class="w">invited</span>
|
||
<span class="w hi">you.</span>
|
||
<span class="w">To</span>
|
||
<span class="w">ensure</span>
|
||
<span class="w">Fenja</span>
|
||
<span class="w">AI</span>
|
||
<span class="w">is</span>
|
||
<span class="w">not</span>
|
||
<span class="w">just</span>
|
||
<span class="w">built</span>
|
||
<span class="w">for</span>
|
||
<span class="w">you</span>
|
||
<span class="w">—</span>
|
||
<span class="w">but</span>
|
||
<span class="w hi">with</span>
|
||
<span class="w hi">you.</span>
|
||
</p>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<h2>JS — bifrost.js timelines (stack-scene + words-scene)</h2>
|
||
<script type="text/x-archived-js" id="stack-words-js">
|
||
/* -------------------------------------------------------------
|
||
ARCHITECTURE — two-phase scrubbed sequence
|
||
Phase A (0.00 – 0.45): each of 4 layer-cards falls from above
|
||
and lands at a progressively higher Y offset so the previous
|
||
card's bottom strip peeks out below. Only the topmost card's
|
||
eyebrow is visible at any time.
|
||
Phase B (0.50 – 1.00): the stack rearranges into a 2x2 grid on
|
||
the right side. Body text in each card fades out; eyebrow
|
||
stays. Explanatory copy crossfades on the LEFT, three panels:
|
||
~0.55 "All the capabilities to solve business use cases"
|
||
~0.70 "Full client control / Complete sovereignty"
|
||
~0.85 "Built in Denmark / For Europe"
|
||
------------------------------------------------------------- */
|
||
const theatre = document.querySelector('.layer-theatre');
|
||
const cards = gsap.utils.toArray('.layer-card');
|
||
const copyLayers = gsap.utils.toArray('.copy-layer');
|
||
|
||
// Each card lands N pixels higher than the previous — previous's
|
||
// bottom strip is visible below.
|
||
const STACK_OFFSET_PER_CARD = 22; // px, upward
|
||
|
||
// Compute grid target positions. In .in-grid mode, each card-box is
|
||
// 20vw square and centered (via margin:auto) inside its full-width
|
||
// parent .layer-card. We translate the parent card so the box lands
|
||
// at the correct grid-cell position.
|
||
function computeGridPlan() {
|
||
const W = theatre.offsetWidth;
|
||
const H = theatre.offsetHeight;
|
||
const vw = window.innerWidth;
|
||
|
||
const cellSize = vw * 0.17; // matches .in-grid .card-box width (17vw)
|
||
const gap = Math.max(14, vw * 0.014);
|
||
|
||
const totalW = 2 * cellSize + gap;
|
||
const totalH = 2 * cellSize + gap;
|
||
|
||
// Right-anchor grid so it sits flush with the right side of the theatre
|
||
const gridRight = W * 0.99;
|
||
const gridStartX = gridRight - totalW;
|
||
const gridStartY = (H - totalH) / 2;
|
||
|
||
// Grid cell centers (in theatre coordinates), reading order: TL, TR, BL, BR
|
||
const centers = [
|
||
{ cx: gridStartX + cellSize / 2, cy: gridStartY + cellSize / 2 },
|
||
{ cx: gridStartX + cellSize / 2 + cellSize + gap, cy: gridStartY + cellSize / 2 },
|
||
{ cx: gridStartX + cellSize / 2, cy: gridStartY + cellSize / 2 + cellSize + gap },
|
||
{ cx: gridStartX + cellSize / 2 + cellSize + gap, cy: gridStartY + cellSize / 2 + cellSize + gap },
|
||
];
|
||
|
||
// In grid mode the card-box's horizontal center is the theatre horizontal
|
||
// center (via margin:auto). That's our anchor for dx computations.
|
||
const theatreCx = W / 2;
|
||
const theatreCy = H / 2;
|
||
|
||
return { cellSize, theatreCx, theatreCy, centers };
|
||
}
|
||
|
||
// Initial state — hide everything, set card translations.
|
||
cards.forEach((card, i) => {
|
||
gsap.set(card, { xPercent: 0, yPercent: -50, opacity: 0, x: 0, y: 0, rotation: 0, scale: 1 });
|
||
gsap.set(card.querySelector('.card-eyebrow'), { opacity: 0 });
|
||
});
|
||
copyLayers.forEach(el => gsap.set(el, { yPercent: -50, opacity: 0, y: 20 }));
|
||
|
||
const stackTl = gsap.timeline({
|
||
scrollTrigger: {
|
||
trigger: '#stack-scene',
|
||
start: 'top top',
|
||
end: '+=5000',
|
||
scrub: 0.6,
|
||
pin: '.stack-pin',
|
||
pinSpacing: true,
|
||
anticipatePin: 1,
|
||
invalidateOnRefresh: true,
|
||
}
|
||
});
|
||
|
||
// -------- Phase A: card landings --------
|
||
cards.forEach((card, i) => {
|
||
const landingY = -i * STACK_OFFSET_PER_CARD;
|
||
const t = i * 0.105;
|
||
|
||
stackTl
|
||
.fromTo(card,
|
||
{ y: -900, rotation: (i % 2 === 0 ? -4 : 4), scale: 0.97 },
|
||
{ y: landingY, rotation: 0, scale: 1, duration: 0.09, ease: 'power3.out' },
|
||
t);
|
||
|
||
stackTl.fromTo(card,
|
||
{ opacity: 0 },
|
||
{ opacity: 1, duration: 0.065, ease: 'power2.out' },
|
||
t + 0.015);
|
||
|
||
stackTl
|
||
.to(card, { y: landingY + 4, duration: 0.012, ease: 'power1.out' }, t + 0.092)
|
||
.to(card, { y: landingY, duration: 0.02, ease: 'power2.inOut' }, t + 0.105);
|
||
|
||
stackTl.to(card.querySelector('.card-eyebrow'),
|
||
{ opacity: 1, duration: 0.025, ease: 'power2.out' },
|
||
t + 0.06);
|
||
|
||
if (i > 0) {
|
||
stackTl.to(cards[i - 1].querySelector('.card-eyebrow'),
|
||
{ opacity: 0, duration: 0.02, ease: 'power2.in' },
|
||
t);
|
||
}
|
||
});
|
||
|
||
// -------- Phase B: rearrange to grid + fade copy --------
|
||
const PHASE_B_START = 0.58;
|
||
|
||
function scheduleGridTransition() {
|
||
const plan = computeGridPlan();
|
||
|
||
const vw = window.innerWidth;
|
||
const cardRect = cards[0].getBoundingClientRect();
|
||
const cardW = cardRect.width || vw;
|
||
const cardH = cardRect.height || 600;
|
||
const targetW = vw * 0.17;
|
||
const targetH = targetW;
|
||
const targetScaleX = targetW / cardW;
|
||
const targetScaleY = targetH / cardH;
|
||
|
||
cards.forEach((card, i) => {
|
||
const target = plan.centers[i];
|
||
const dx = target.cx - plan.theatreCx;
|
||
const dy = target.cy - plan.theatreCy;
|
||
const content = card.querySelector('.card-content');
|
||
const gridLabel = card.querySelector('.card-grid-label');
|
||
const brain = card.querySelector('.card-brain');
|
||
|
||
stackTl.to(card,
|
||
{ x: dx, y: dy,
|
||
scaleX: targetScaleX, scaleY: targetScaleY,
|
||
rotation: 0,
|
||
duration: 0.14, ease: 'power2.inOut',
|
||
transformOrigin: 'center center' },
|
||
PHASE_B_START);
|
||
|
||
const counterScaleX = targetScaleY / targetScaleX;
|
||
stackTl.to(brain,
|
||
{ scaleX: counterScaleX,
|
||
duration: 0.14, ease: 'power2.inOut',
|
||
transformOrigin: 'right center',
|
||
immediateRender: false },
|
||
PHASE_B_START);
|
||
|
||
const resetVars = {
|
||
scaleX: 1, scaleY: 1,
|
||
duration: 0.00001,
|
||
immediateRender: false,
|
||
};
|
||
if (i === 0) {
|
||
resetVars.onStart = function() {
|
||
theatre.classList.add('in-grid');
|
||
};
|
||
resetVars.onReverseComplete = function() {
|
||
theatre.classList.remove('in-grid');
|
||
};
|
||
}
|
||
stackTl.to(card, resetVars, PHASE_B_START + 0.14);
|
||
|
||
stackTl.to(brain,
|
||
{ scaleX: 1, duration: 0.00001, immediateRender: false },
|
||
PHASE_B_START + 0.14);
|
||
|
||
stackTl.to(content,
|
||
{ opacity: 0, duration: 0.08, ease: 'power2.in' },
|
||
PHASE_B_START);
|
||
stackTl.to(gridLabel,
|
||
{ opacity: 0.88, duration: 0.08, ease: 'power2.out' },
|
||
PHASE_B_START + 0.06);
|
||
|
||
stackTl.to(card.querySelector('.card-eyebrow'),
|
||
{ opacity: 0, duration: 0.06, ease: 'power2.in' },
|
||
PHASE_B_START);
|
||
});
|
||
}
|
||
scheduleGridTransition();
|
||
|
||
let resizeTimer;
|
||
window.addEventListener('resize', () => {
|
||
clearTimeout(resizeTimer);
|
||
resizeTimer = setTimeout(() => ScrollTrigger.refresh(), 250);
|
||
});
|
||
|
||
// -------- Copy layer crossfade on the LEFT (during grid phase) --------
|
||
const FADE = 0.025;
|
||
const swap = (fromIdx, toIdx, pos) => {
|
||
if (fromIdx !== null) {
|
||
stackTl.to(copyLayers[fromIdx], { opacity: 0, y: -14, duration: FADE, ease: 'power2.in' }, pos);
|
||
}
|
||
stackTl.fromTo(copyLayers[toIdx],
|
||
{ opacity: 0, y: 16 },
|
||
{ opacity: 1, y: 0, duration: FADE, ease: 'power2.out' },
|
||
pos + FADE + 0.002);
|
||
};
|
||
|
||
stackTl.fromTo(copyLayers[0],
|
||
{ opacity: 0, y: 16 },
|
||
{ opacity: 1, y: 0, duration: FADE * 1.5, ease: 'power2.out' },
|
||
PHASE_B_START + 0.08);
|
||
|
||
swap(0, 1, 0.77);
|
||
swap(1, 2, 0.90);
|
||
|
||
// Clean exit
|
||
stackTl.to('.layer-theatre', { opacity: 0, duration: 0.03, ease: 'power2.in' }, 0.97);
|
||
|
||
/* -------------------------------------------------------------
|
||
SCENE 3 — WORDS fly in one at a time, driven by scroll
|
||
------------------------------------------------------------- */
|
||
|
||
(function rebuildWordsSentence() {
|
||
const wordsP = document.getElementById('words-sentence');
|
||
if (!wordsP) return;
|
||
|
||
const firstName = (typeof window.__fenjaFirstName === 'string')
|
||
? window.__fenjaFirstName.trim()
|
||
: null;
|
||
|
||
let tokens;
|
||
if (firstName) {
|
||
tokens = [
|
||
{ text: 'This' }, { text: 'is' }, { text: 'why' },
|
||
{ text: 'we’ve' }, { text: 'invited' }, { text: 'you,' },
|
||
{ text: firstName + '.', hi: true },
|
||
{ text: 'To' }, { text: 'ensure' }, { text: 'Fenja' },
|
||
{ text: 'AI' }, { text: 'is' }, { text: 'not' },
|
||
{ text: 'just' }, { text: 'built' }, { text: 'for' },
|
||
{ text: 'you' }, { text: '—' }, { text: 'but' },
|
||
{ text: 'with', hi: true }, { text: 'you.', hi: true },
|
||
];
|
||
} else {
|
||
tokens = [
|
||
{ text: 'This' }, { text: 'is' }, { text: 'why' },
|
||
{ text: 'we’ve' }, { text: 'invited' },
|
||
{ text: 'you.', hi: true },
|
||
{ text: 'To' }, { text: 'ensure' }, { text: 'Fenja' },
|
||
{ text: 'AI' }, { text: 'is' }, { text: 'not' },
|
||
{ text: 'just' }, { text: 'built' }, { text: 'for' },
|
||
{ text: 'you' }, { text: '—' }, { text: 'but' },
|
||
{ text: 'with', hi: true }, { text: 'you.', hi: true },
|
||
];
|
||
}
|
||
|
||
wordsP.textContent = '';
|
||
tokens.forEach((t, i) => {
|
||
const span = document.createElement('span');
|
||
span.className = t.hi ? 'w hi' : 'w';
|
||
span.textContent = t.text;
|
||
wordsP.appendChild(span);
|
||
if (i < tokens.length - 1) wordsP.appendChild(document.createTextNode(' '));
|
||
});
|
||
})();
|
||
|
||
const wordEls = gsap.utils.toArray('.words .w');
|
||
|
||
const rnd = (i, seed) => {
|
||
const s = Math.sin((i + 1) * seed) * 10000;
|
||
return s - Math.floor(s);
|
||
};
|
||
|
||
wordEls.forEach((w, i) => {
|
||
const hi = w.classList.contains('hi');
|
||
const fromX = hi ? 0 : (rnd(i, 12.9898) - 0.5) * 220;
|
||
const fromY = hi ? 80 : (rnd(i, 78.233) - 0.5) * 160;
|
||
const rot = hi ? 0 : (rnd(i, 37.719) - 0.5) * 16;
|
||
gsap.set(w, {
|
||
opacity: 0,
|
||
x: fromX,
|
||
y: fromY,
|
||
rotate: rot,
|
||
scale: hi ? 1.05 : 0.9,
|
||
filter: 'blur(6px)',
|
||
});
|
||
});
|
||
|
||
const wordsTl = gsap.timeline({
|
||
scrollTrigger: {
|
||
trigger: '#words-scene',
|
||
start: 'top top',
|
||
end: 'bottom bottom',
|
||
scrub: 0.4,
|
||
}
|
||
});
|
||
|
||
wordEls.forEach((w, i) => {
|
||
const hi = w.classList.contains('hi');
|
||
const dur = hi ? 0.14 : 0.1;
|
||
wordsTl.to(w, {
|
||
opacity: 1,
|
||
x: 0, y: 0, rotate: 0,
|
||
scale: 1,
|
||
filter: 'blur(0px)',
|
||
duration: dur,
|
||
ease: 'power3.out',
|
||
}, i * 0.055);
|
||
if (hi) {
|
||
wordsTl.to(w, { scale: 1.0, duration: 0.05 }, '>-0.02');
|
||
}
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|