first commit
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
{{/*
|
||||
The opening of every page: an optional note (the eyebrow), the statement,
|
||||
the dek, the actions — then either the layer panel (when `fit:` is set)
|
||||
or the field, a blue plate with the platform's four layers drawn as bars.
|
||||
`bars: false` drops the field.
|
||||
*/}}
|
||||
{{ $s := . }}
|
||||
<header class="hero{{ if $s.compact }} hero-compact{{ end }}">
|
||||
{{ with $s.eyebrow }}<p class="note" data-reveal><span class="note-live" aria-hidden="true"></span><span class="note-text">{{ . }}</span></p>{{ end }}
|
||||
<h1 class="statement" data-reveal style="--d:80ms">{{ $s.title | markdownify }}</h1>
|
||||
{{ with $s.subhead }}<p class="dek" data-reveal style="--d:140ms">{{ . | markdownify }}</p>{{ end }}
|
||||
{{ if $s.ctas }}<div class="actions" data-reveal style="--d:200ms">{{ partial "sections/ctas.html" $s.ctas }}</div>{{ end }}
|
||||
|
||||
{{ with $s.log }}
|
||||
{{/*
|
||||
An agent's activity log, typed out line by line (see the script below).
|
||||
Lines take `tag` + `text`; `think: true` marks a reasoning step (greyed,
|
||||
with a pause); `done: true` closes the run. The window keeps a fixed
|
||||
height and scrolls as lines arrive. `logImage` swaps the blue field for
|
||||
a photo; `logCaption` credits it.
|
||||
*/}}
|
||||
<figure class="hero-field hero-log{{ if $s.logImage }} has-image{{ end }}" data-reveal style="--d:260ms">
|
||||
{{ with $s.logImage }}<img class="log-bg" src="{{ . | relURL }}" alt="" fetchpriority="high">{{ end }}
|
||||
<div class="log-window">
|
||||
<div class="log-bar">
|
||||
<span class="log-title">{{ $s.logTitle | default "agent · your-company.federated.computer" }}</span>
|
||||
<span class="log-live"><span class="note-live" aria-hidden="true"></span>Live</span>
|
||||
</div>
|
||||
<div class="log-view">
|
||||
<ol class="log-lines" aria-label="An AI agent at work on a Federated Core">
|
||||
{{ range . }}
|
||||
<li class="log-line{{ if .done }} is-done{{ end }}{{ if .think }} is-think{{ end }}">
|
||||
<span class="log-tag">{{ .tag | default (cond .done "Done" (cond (.think | default false) "Thinking" "")) }}</span>
|
||||
<span class="log-text">{{ .text }}</span>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{ with $s.logCaption }}<figcaption class="log-caption">{{ . }}</figcaption>{{ end }}
|
||||
</figure>
|
||||
<script>
|
||||
(function () {
|
||||
var fig = document.currentScript.previousElementSibling;
|
||||
if (!fig || matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
var view = fig.querySelector('.log-view'), list = fig.querySelector('.log-lines');
|
||||
var lines = [].slice.call(fig.querySelectorAll('.log-line'));
|
||||
var onScreen = true, i = 0;
|
||||
function visible() { return onScreen && !document.hidden; }
|
||||
fig.classList.add('is-animated');
|
||||
lines.forEach(function (li) {
|
||||
li.style.setProperty('--n', li.querySelector('.log-text').textContent.trim().length);
|
||||
});
|
||||
// Pause while the log is off screen or the tab is hidden.
|
||||
function schedule(fn, ms) { setTimeout(function () { if (visible()) fn(); else schedule(fn, 400); }, ms); }
|
||||
function next() {
|
||||
if (i === lines.length) { schedule(reset, 4200); return; }
|
||||
var li = lines[i++], n = +li.style.getPropertyValue('--n');
|
||||
// Finished lines drop their typing animation, so a repaint can't replay it.
|
||||
lines.forEach(function (l) { if (l.classList.contains('is-current')) l.classList.add('is-typed'); l.classList.remove('is-current'); });
|
||||
li.classList.add('is-on', 'is-current');
|
||||
// Keep the newest line in view, like a terminal: slide the list up.
|
||||
var shift = Math.max(0, li.offsetTop + li.offsetHeight + 18 - view.clientHeight);
|
||||
list.style.transform = 'translateY(' + -shift + 'px)';
|
||||
var pause = li.classList.contains('is-think') ? 1300 : li.classList.contains('is-done') ? 300 : 450;
|
||||
schedule(next, n * 16 + pause);
|
||||
}
|
||||
function reset() {
|
||||
fig.classList.add('is-clearing');
|
||||
schedule(function () {
|
||||
lines.forEach(function (l) { l.classList.remove('is-on', 'is-current', 'is-typed'); });
|
||||
list.style.transition = 'none';
|
||||
list.style.transform = '';
|
||||
void list.offsetHeight;
|
||||
list.style.transition = '';
|
||||
fig.classList.remove('is-clearing');
|
||||
i = 0;
|
||||
schedule(next, 500);
|
||||
}, 450);
|
||||
}
|
||||
if ('IntersectionObserver' in window) {
|
||||
new IntersectionObserver(function (e) { onScreen = e[0].isIntersecting; }).observe(fig);
|
||||
}
|
||||
schedule(next, 700);
|
||||
})();
|
||||
</script>
|
||||
{{ else }}
|
||||
{{ with $s.fit }}
|
||||
<aside class="hero-fit" aria-label="Platform layers this path uses" data-reveal style="--d:260ms">
|
||||
<div class="hero-fit-head">
|
||||
<p class="hero-fit-title">What this path uses</p>
|
||||
<a class="more" href="{{ "/solutions/#compare" | relURL }}">Compare all four<span class="arrow" aria-hidden="true">→</span></a>
|
||||
</div>
|
||||
{{ partial "fit.html" (dict "fit" .) }}
|
||||
</aside>
|
||||
{{ else }}
|
||||
{{ if ne $s.bars false }}
|
||||
<figure class="hero-field" aria-hidden="true" data-reveal style="--d:260ms">
|
||||
{{/* Listed in stack order; drawn bottom-up so Core is the foundation. */}}
|
||||
<div class="field-stack">
|
||||
{{ range $i, $l := hugo.Data.layers }}
|
||||
<span class="field-layer" style="--i:{{ $i }}"><i></i><em>{{ printf "%02d" (add $i 1) }} · {{ $l.name }}</em></span>
|
||||
{{ end }}
|
||||
</div>
|
||||
</figure>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</header>
|
||||
Reference in New Issue
Block a user