diff --git a/index.html b/index.html index 083fc38..d3bfb97 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ name="description" content="amerc is an agent mercenary layer for embedding, bringing, and hosting agents across vertical software boundaries." /> - + diff --git a/package.json b/package.json index 39244bf..31a7796 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "amerc-site", - "version": "0.28.0-keys", + "version": "0.29.0-footer", "private": true, "type": "module", "scripts": { diff --git a/src/Scene2D.jsx b/src/Scene2D.jsx index b150ca8..3c4b503 100644 --- a/src/Scene2D.jsx +++ b/src/Scene2D.jsx @@ -6,7 +6,7 @@ import Mansion from './Mansion.jsx'; import TavernGame from './TavernGame.jsx'; import { api } from './api.js'; -const RELEASE = '0.28.0-keys'; +const RELEASE = '0.29.0-footer'; const NAV = [ { id: 'home', label: 'Tavern' }, @@ -89,18 +89,54 @@ function Home({ setRoute }) { ); } -function Page({ children }) { return
{children}
; } +function Footer({ setRoute }) { + const [ok, setOk] = useState(null); + const [stats, setStats] = useState(null); + useEffect(() => { + api('/health').then(() => setOk(true)).catch(() => setOk(false)); + api('/agents/stats').then(setStats).catch(() => {}); + }, []); + return ( + + ); +} + +function Page({ children, setRoute }) { return
{children}
; } function Scene({ route, setRoute, auth }) { if (route === 'home') return ; - if (route === 'agents') return ; - if (route === 'mansion') return ; - if (route === 'booth') return ; - if (route === 'signin') return
+ if (route === 'agents') return ; + if (route === 'mansion') return ; + if (route === 'booth') return ; + if (route === 'signin') return
GATEHOUSE

Open Booth

One amerc account across tavern, docs, PM and git.

setRoute('booth')} />
; - if (route === 'admin') return
+ if (route === 'admin') return
BACKDOOR

Quartermaster

Tenant, key, session and risk controls.

; diff --git a/src/styles.css b/src/styles.css index 1af70b2..2a1efeb 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1092,3 +1092,21 @@ button { .ap-keys { margin-top: 22px; padding: 18px; border-radius: 14px; background: #130d20; border: 1px solid #271c3a; } .ap-keys-mint { display: flex; gap: 8px; margin: 10px 0; flex-wrap: wrap; } .ap-keys-mint input { flex: 1 1 200px; padding: 9px 11px; border-radius: 8px; background: #0a0f1a; border: 1px solid #2e2440; color: #eaf2ff; font-family: inherit; } + +/* footer + live status (0.29) */ +.td-page { display: flex; flex-direction: column; } +.td-page-inner { flex: 1; } +.ft { border-top: 1px solid #1c1430; background: linear-gradient(180deg, #0c0814, #07060c); padding: 30px 24px 18px; font-family: Inter, sans-serif; color: #b9a6cf; } +.ft-cols { max-width: 1080px; margin: 0 auto; display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 28px; } +.ft-brand { max-width: 340px; } +.ft-logo { display: flex; align-items: center; gap: 8px; } +.ft-logo strong { font-family: Georgia, serif; font-size: 20px; color: #f3d27a; } +.ft-brand p { font-size: 12px; line-height: 1.7; color: #9a86b8; margin: 8px 0 12px; } +.ft-status { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: #8fe9c0; background: rgba(54,240,176,0.08); border: 1px solid rgba(54,240,176,0.3); border-radius: 16px; padding: 5px 12px; } +.ft-status i { width: 8px; height: 8px; border-radius: 50%; background: #36f0b0; box-shadow: 0 0 0 0 rgba(54,240,176,0.7); animation: ap-pulse 1.8s infinite; } +.ft-status.down { color: #ff9f9f; background: rgba(255,122,140,0.08); border-color: rgba(255,122,140,0.3); } .ft-status.down i { background: #ff7a8c; animation: none; } +.ft-col h5 { font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #6f5b8c; margin: 0 0 10px; } +.ft-col a, .ft-col button { display: block; color: #c3d0e6; font-size: 13px; text-decoration: none; background: none; cursor: pointer; padding: 4px 0; text-align: left; font-family: inherit; } +.ft-col a:hover, .ft-col button:hover { color: #27d8ff; } +.ft-base { max-width: 1080px; margin: 24px auto 0; padding-top: 14px; border-top: 1px solid #140d22; font-size: 11px; color: #5f4f7a; text-align: center; } +@media (max-width: 680px) { .ft-cols { grid-template-columns: 1fr 1fr; } .ft-brand { grid-column: 1 / -1; } }