A hall of amerc services that put your work on the open internet — each lives behind amerc's edge and is brought to life by your own broker. No servers to rent, no ports to forward.
+
Your estate on the open internet — a villa of amerc services, each room brought to life by your own broker. No servers to rent, no ports to forward.
{loggedIn
- ? {auth.user.handle}'s rooms are open
- : }
+ ? {auth.user.handle}'s estate — the gates are open
+ : }
+
⚜ Chambers of the estate
diff --git a/src/Scene2D.jsx b/src/Scene2D.jsx
index e37fe37..91eef0f 100644
--- a/src/Scene2D.jsx
+++ b/src/Scene2D.jsx
@@ -11,7 +11,7 @@ import { api } from './api.js';
const Menu = ({ size = 20 }) => ();
const X = ({ size = 20 }) => ();
-const RELEASE = '2.2.0-warcamp';
+const RELEASE = '2.3.0-villa';
const NAV = [
{ id: 'home', label: 'Tavern' },
@@ -476,6 +476,7 @@ function StatusPage() {
}
const CHANGELOG = [
+ { v: '2.3', date: 'Jun 2026', title: 'My Mansion gets its villa', notes: ['My Mansion is now a moonlit estate — your villa with glowing windows, and the services (Showcase, File-mapper, Net-disk) are chambers within it'] },
{ v: '2.2', date: 'Jun 2026', title: 'My Legion becomes a war camp', notes: ['Your classes are banners and each instance is a soldier — alive and bobbing when online, standing by when pending, fallen when down', 'Tap a soldier to command it: chat with your own running agent, watch its live terminal, or stand it down', 'Statuses refresh on their own so the camp stays current'] },
{ v: '2.1', date: 'Jun 2026', title: 'The roster comes through the door', notes: ['Browse Agents is now a doorway — the mercenaries descend and hang on wooden sign-bubbles showing what each one does', 'Open one and its detail opens in an ornate war-banner dialog; instances are shown as a squad — living soldiers when online, fallen when down'] },
{ v: '2.0', date: 'Jun 2026', title: 'The tavern becomes the interface', notes: ['The home page is now a full-screen game scene — every fixture is a door: the grand door is the roster, the bar signs you in, the banners are your Legion, the side passage leads to My Mansion', 'Speech bubbles everywhere: the dancer pitches the tour in a glowing holo-panel, the barkeep greets you by name', 'Details open in ornate in-game dialogs instead of plain pages'] },
diff --git a/src/styles.css b/src/styles.css
index a87353f..ec282fc 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -1807,3 +1807,27 @@ button {
.lg-tui-head { padding: 5px 11px; background: #0d1320; color: #5b6b7d; font-size: 10px; letter-spacing: 0.6px; text-transform: uppercase; border-bottom: 1px solid #1c2438; }
.lg-tui pre { margin: 0; padding: 11px; font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: #9fe6c0; max-height: 240px; overflow: auto; white-space: pre-wrap; word-break: break-word; }
.lg-rouse { margin-top: 2px; }
+
+/* ===== My Mansion = a villa estate (2.3) ===== */
+.mn-villa { display: flex; align-items: stretch; gap: 22px; margin-bottom: 18px; background: linear-gradient(180deg, #15102a, #0d0a18); border: 1px solid #2a2440; border-radius: 16px; padding: 16px; overflow: hidden; }
+.mn-villa-scene { position: relative; flex: 0 0 auto; width: 300px; height: 200px; border-radius: 12px; overflow: hidden; background: linear-gradient(180deg, #1a1840 0%, #3a2a5a 55%, #5a3a4a 78%, #2a1d2a 100%); box-shadow: inset 0 0 30px rgba(0,0,0,0.5); }
+.mn-villa-moon { position: absolute; right: 26px; top: 22px; width: 36px; height: 36px; border-radius: 50%; background: radial-gradient(circle at 38% 35%, #fff6e0, #ffd98a 60%, #e8b860); box-shadow: 0 0 24px rgba(255,220,150,0.6); }
+.mn-villa-star { position: absolute; width: 3px; height: 3px; border-radius: 50%; background: #fff; box-shadow: 0 0 5px #fff; animation: mnTwinkle 3s ease-in-out infinite; }
+@keyframes mnTwinkle { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
+.mn-villa-roof { position: absolute; left: 50px; bottom: 102px; width: 0; height: 0; border-left: 100px solid transparent; border-right: 100px solid transparent; border-bottom: 46px solid #5a2e22; filter: drop-shadow(0 -2px 0 #7a3e2e); }
+.mn-villa-house { position: absolute; left: 70px; bottom: 26px; width: 160px; height: 80px; background: linear-gradient(180deg, #d8c79a, #b89a6e); border-radius: 3px; box-shadow: inset 0 0 16px rgba(90,46,34,0.35); }
+.mn-villa-windows { position: absolute; inset: 12px 18px 30px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 16px; }
+.mn-win { border-radius: 2px; background: #ffcf6a; box-shadow: 0 0 10px rgba(255,207,106,0.85); animation: mnFlicker 4s ease-in-out infinite; }
+.mn-win.dark { background: #4a3a2a; box-shadow: none; }
+@keyframes mnFlicker { 0%, 100% { opacity: 0.92; } 45% { opacity: 0.7; } 70% { opacity: 1; } }
+.mn-villa-door { position: absolute; left: 50%; bottom: 0; width: 26px; height: 38px; transform: translateX(-50%); background: #5a3a1c; border-radius: 13px 13px 0 0; box-shadow: inset 0 0 6px rgba(0,0,0,0.5); }
+.mn-villa-flag { position: absolute; left: 50%; bottom: 144px; width: 2px; height: 30px; background: #3a2a1a; transform: translateX(-50%); z-index: 3; }
+.mn-villa-flag i { position: absolute; top: 0; left: 2px; width: 22px; height: 13px; background: #c44; clip-path: polygon(0 0, 100% 0, 80% 50%, 100% 100%, 0 100%); animation: mnWave 2.5s ease-in-out infinite; transform-origin: left; }
+@keyframes mnWave { 0%, 100% { transform: skewY(0deg); } 50% { transform: skewY(-6deg); } }
+.mn-villa-hedge { position: absolute; left: 0; right: 0; bottom: 0; height: 28px; background: repeating-radial-gradient(circle at 14px 18px, #2c4a2e 0 12px, #234023 12px 16px); background-color: #1e3620; }
+.mn-villa-body { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 7px; min-width: 0; }
+.mn-villa-tag { font-size: 10px; letter-spacing: 1.6px; color: #ffd75e; align-self: flex-start; background: rgba(255,215,94,0.08); border: 1px solid #5a4a1c; padding: 3px 10px; border-radius: 999px; }
+.mn-villa-body h2 { margin: 2px 0; font-family: Georgia, serif; font-size: 27px; color: #f3e9d2; }
+.mn-villa-body p { margin: 0 0 6px; color: #9b8fb8; font-size: 13.5px; line-height: 1.5; max-width: 540px; }
+.mn-wing-title { font-family: Georgia, serif; color: #cbb8e8; font-size: 16px; margin: 4px 2px 12px; letter-spacing: 0.5px; }
+@media (max-width: 680px) { .mn-villa { flex-direction: column; align-items: center; } .mn-villa-scene { width: 100%; max-width: 320px; } .mn-villa-body { align-items: center; text-align: center; } .mn-villa-tag { align-self: center; } }