diff --git a/index.html b/index.html index ee09994..3d1e841 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - + diff --git a/package.json b/package.json index f0b53eb..dcbc941 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "amerc-site", - "version": "0.65.0-instanthome", + "version": "0.66.0-backtotop", "private": true, "type": "module", "scripts": { diff --git a/src/Scene2D.jsx b/src/Scene2D.jsx index 85e24ef..f13fca7 100644 --- a/src/Scene2D.jsx +++ b/src/Scene2D.jsx @@ -7,7 +7,7 @@ import Account from './Account.jsx'; import TavernGame from './TavernGame.jsx'; import { api } from './api.js'; -const RELEASE = '0.65.0-instanthome'; +const RELEASE = '0.66.0-backtotop'; const NAV = [ { id: 'home', label: 'Tavern' }, @@ -100,9 +100,17 @@ function Reveal({ children, className = '', delay = 0, tag: Tag = 'div' }) { function Home({ setRoute }) { const [stats, setStats] = useState(null); + const [scrolled, setScrolled] = useState(false); + const homeRef = useRef(null); useEffect(() => { api('/agents/stats').then(setStats).catch(() => {}); }, []); + useEffect(() => { + const el = homeRef.current; if (!el) return; + const onScroll = () => setScrolled(el.scrollTop > 500); + el.addEventListener('scroll', onScroll, { passive: true }); + return () => el.removeEventListener('scroll', onScroll); + }, []); return ( -
+
@@ -124,6 +132,7 @@ function Home({ setRoute }) {
); } diff --git a/src/styles.css b/src/styles.css index c3c2e03..cdead78 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1449,3 +1449,11 @@ button { /* persistent home host (0.65) — keeps the tavern mounted, hidden off-route */ .route-host { flex: 1; min-height: 0; flex-direction: column; } + +/* back-to-top button (0.66) */ +.gm-totop { position: fixed; right: 22px; bottom: 22px; width: 42px; height: 42px; border-radius: 50%; border: none; cursor: pointer; + background: linear-gradient(180deg, #2aa7d8, #1f86c4); color: #fff; font-size: 20px; line-height: 1; + box-shadow: 0 6px 18px rgba(0,0,0,0.45); opacity: 0; transform: translateY(10px); pointer-events: none; transition: opacity .2s, transform .2s, background .15s; z-index: 30; } +.gm-totop.show { opacity: 0.92; transform: none; pointer-events: auto; } +.gm-totop.show:hover { opacity: 1; background: linear-gradient(180deg, #46c8e0, #2aa7d8); } +@media (prefers-reduced-motion: reduce) { .gm-totop { transition: opacity .2s; transform: none; } }