talkable tavern NPCs (0.38.0): Pokémon-style speech bubbles
- hover a character (barkeep / two patrons) -> parchment speech bubble with flavor - clicking routes to Browse / My Booth / Mansion — adds life + feature discovery - verified bubble renders on hover
This commit is contained in:
parent
a138ff1ebb
commit
e711a7c904
@ -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.37.0-embed" />
|
||||
<meta name="version" content="0.38.0-npc" />
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<!-- Open Graph / social share -->
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "amerc-site",
|
||||
"version": "0.37.0-embed",
|
||||
"version": "0.38.0-npc",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@ -7,7 +7,7 @@ import Account from './Account.jsx';
|
||||
import TavernGame from './TavernGame.jsx';
|
||||
import { api } from './api.js';
|
||||
|
||||
const RELEASE = '0.37.0-embed';
|
||||
const RELEASE = '0.38.0-npc';
|
||||
|
||||
const NAV = [
|
||||
{ id: 'home', label: 'Tavern' },
|
||||
|
||||
@ -108,8 +108,20 @@ export default function TavernGame({ onHotspot }) {
|
||||
<button className="gm-label gm-label-screen" style={{ left: '50%', top: '18%' }} onClick={() => onHotspot?.('agents')}>▸ Browse Agents</button>
|
||||
<button className="gm-hot" style={{ left: '44%', top: '50%', width: '14%', height: '24%' }} onClick={() => onHotspot?.('booth')} title="My Booth" />
|
||||
<button className="gm-label gm-label-booth" style={{ left: '50%', top: '90%' }} onClick={() => onHotspot?.('booth')}>⌂ Enter My Booth</button>
|
||||
<button className="gm-label gm-label-bar" style={{ left: '20%', top: '24%' }} onClick={() => onHotspot?.('agents')}>🍺 The Bar</button>
|
||||
<Npc x="11%" y="4%" w="13%" h="20%" who="Barkeep" say="What'll it be? The staff roster is up on the board." onClick={() => onHotspot?.('agents')} />
|
||||
<Npc x="11%" y="52%" w="13%" h="22%" who="Patron" say="I run three mercenaries straight from my booth." onClick={() => onHotspot?.('booth')} />
|
||||
<Npc x="72%" y="52%" w="13%" h="22%" who="Patron" say="Showcase put my little app on the open internet!" onClick={() => onHotspot?.('mansion')} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Npc({ x, y, w, h, who, say, onClick }) {
|
||||
const [hover, setHover] = useState(false);
|
||||
return (
|
||||
<button className="gm-npc" style={{ left: x, top: y, width: w, height: h }}
|
||||
onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} onClick={onClick} aria-label={who}>
|
||||
{hover && <span className="gm-say"><strong>{who}</strong>{say}</span>}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1181,3 +1181,10 @@ button {
|
||||
.ap-embed > code { display: block; color: #7fe9ff; font-family: ui-monospace, monospace; font-size: 12px; background: #07060c; padding: 10px 12px; border-radius: 8px; word-break: break-all; border: 1px solid #1d2a3a; }
|
||||
.ap-embed .ap-hint { margin: 8px 0 0; } .ap-embed .ap-hint code { display: inline; padding: 1px 5px; background: #162032; color: #9d8fc0; }
|
||||
.ap-pty-note { padding: 12px 14px; }
|
||||
|
||||
/* tavern NPC speech bubbles (0.38) */
|
||||
.gm-npc { position: absolute; background: transparent; border: 0; cursor: pointer; border-radius: 8px; transition: box-shadow .14s; }
|
||||
.gm-npc:hover { box-shadow: 0 0 0 2px rgba(255,220,140,0.5), 0 0 18px rgba(255,200,100,0.35); background: rgba(255,220,140,0.08); }
|
||||
.gm-say { position: absolute; bottom: 102%; left: 50%; transform: translateX(-50%); width: max-content; max-width: 200px; padding: 8px 11px; font-family: Georgia, serif; font-size: 12px; line-height: 1.5; color: #1c1206; background: #fff0d7; border: 2px solid #3a2410; border-radius: 8px; box-shadow: 0 6px 16px rgba(0,0,0,0.5); z-index: 8; text-align: left; }
|
||||
.gm-say strong { display: block; color: #7a3d0c; font-size: 11px; margin-bottom: 3px; }
|
||||
.gm-say::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 7px solid transparent; border-top-color: #3a2410; }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user