homepage flow diagram (0.47.0)

- animated 'You -> amerc edge -> Your users' architecture diagram on the
  home features section: three nodes (broker+agent / relay+proxy+auth /
  chatbox+terminal+url) connected by flowing-dot links
- makes the non-obvious 'agent mercenary layer' model legible at a glance
- horizontal on desktop, stacks vertical on mobile, animation respects
  prefers-reduced-motion; wrapped in the scroll-reveal
- verified live: 3 nodes, 2 links render, visible
This commit is contained in:
artheru 2026-06-10 07:06:07 +08:00
parent 84a37bb7ed
commit 56c85e0c1d
4 changed files with 45 additions and 3 deletions

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#0e0a14" />
<meta name="description" content="amerc is the agent mercenary tavern — hire, run, publish, and remotely deliver AI agents across software boundaries. No infrastructure, just skills." />
<meta name="version" content="0.46.0-status" />
<meta name="version" content="0.47.0-flow" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/app-192.png" type="image/png" sizes="192x192" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />

View File

@ -1,6 +1,6 @@
{
"name": "amerc-site",
"version": "0.46.0-status",
"version": "0.47.0-flow",
"private": true,
"type": "module",
"scripts": {

View File

@ -7,7 +7,7 @@ import Account from './Account.jsx';
import TavernGame from './TavernGame.jsx';
import { api } from './api.js';
const RELEASE = '0.46.0-status';
const RELEASE = '0.47.0-flow';
const NAV = [
{ id: 'home', label: 'Tavern' },
@ -150,11 +150,34 @@ function ActivityFeed() {
</div>
);
}
const FLOW = [
{ ico: '💻', title: 'You', sub: 'broker + agent', body: 'Your broker runs the agent on your own machine — codex, claude, any CLI. It dials out over WebSocket, so there are no inbound ports to open.' },
{ ico: '💎', title: 'amerc edge', sub: 'relay · proxy · auth', body: 'amerc authenticates each session, relays the agent, and proxies traffic — all on the public edge at amerc.ai.' },
{ ico: '👥', title: 'Your users', sub: 'chatbox · terminal · url', body: 'They reach your agent as an embedded chatbox, a live web terminal, or a public Showcase subdomain.' },
];
function FlowDiagram() {
return (
<div className="fd">
{FLOW.map((n, i) => (
<React.Fragment key={i}>
<div className="fd-node">
<span className="fd-ico" aria-hidden="true">{n.ico}</span>
<strong>{n.title}</strong>
<span className="fd-sub">{n.sub}</span>
<p>{n.body}</p>
</div>
{i < FLOW.length - 1 && <div className="fd-link" aria-hidden="true"><i /></div>}
</React.Fragment>
))}
</div>
);
}
function HomeFeatures({ setRoute }) {
return (
<section className="hf">
<h2 className="hf-title">How <span>amerc</span> works</h2>
<p className="hf-lead">An agent mercenary layer for embedding, bringing, and hosting AI agents across vertical software boundaries.</p>
<Reveal><FlowDiagram /></Reveal>
<div className="hf-grid">
{HF_STEPS.map((s, i) => (
<Reveal key={i} className="hf-card" delay={i * 90}>

View File

@ -1301,3 +1301,22 @@ button {
.st-state.up { color: #36f0b0; } .st-state.down { color: #ff7a8c; } .st-state.checking { color: #b6a7d4; }
.st-foot { color: #7a6a98; font-size: 12px; line-height: 1.6; margin: 14px 2px 0; }
@media (max-width: 560px) { .st-host { display: none; } .st-name { min-width: 0; flex: 1; } }
/* homepage flow diagram (0.47) */
.fd { display: flex; align-items: stretch; gap: 0; margin: 6px 0 34px; flex-wrap: wrap; justify-content: center; }
.fd-node { flex: 1 1 220px; min-width: 200px; max-width: 320px; background: linear-gradient(180deg, #15102a, #0e0a18); border: 1px solid #271c3a; border-radius: 16px; padding: 18px 16px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.fd-ico { font-size: 30px; line-height: 1.1; filter: drop-shadow(0 3px 8px rgba(0,0,0,0.45)); }
.fd-node strong { color: #fff; font-size: 15px; margin-top: 4px; }
.fd-sub { color: var(--cyan); font-size: 10.5px; letter-spacing: 0.5px; text-transform: uppercase; }
.fd-node p { color: #a99cc8; font-size: 12.5px; line-height: 1.55; margin: 7px 0 0; }
.fd-link { flex: 0 0 56px; align-self: center; height: 3px; position: relative; border-radius: 3px; background: linear-gradient(90deg, #2a2040, #46c8e0, #2a2040); overflow: hidden; }
.fd-link i { position: absolute; top: 50%; left: 0; width: 7px; height: 7px; margin-top: -3.5px; border-radius: 50%; background: #aef2ff; box-shadow: 0 0 9px #46c8e0; animation: fdflow 1.7s linear infinite; }
@keyframes fdflow { from { left: -8px; } to { left: calc(100% + 8px); } }
@media (max-width: 760px) {
.fd { flex-direction: column; align-items: stretch; }
.fd-node { max-width: none; }
.fd-link { flex: 0 0 34px; width: 3px; height: 34px; align-self: center; background: linear-gradient(180deg, #2a2040, #46c8e0, #2a2040); }
.fd-link i { left: 50%; top: 0; margin-left: -3.5px; margin-top: 0; animation: fdflowv 1.7s linear infinite; }
}
@keyframes fdflowv { from { top: -8px; } to { top: calc(100% + 8px); } }
@media (prefers-reduced-motion: reduce) { .fd-link i { animation: none; opacity: 0; } }