grapes-andrewdingus
Version:
GRAPES OS static site — CDN-ready via unpkg
123 lines (110 loc) • 4.93 kB
JavaScript
const templatetopnav = document.createElement("template");
templatetopnav.innerHTML = `
<nav class="topnav" id="topnav" aria-label="Main navigation">
<a class="nav-brand" href="./" onclick="home(); return false;">
<img src="./assets/img/grapes_mascot.png" onmouseover="spin(this)" onmouseout="unspin(this)" alt="GRAPES OS" width="30" height="30" />
<span class="nav-brand-name">GRAPES OS</span>
</a>
<div class="nav-links">
<a href="./">Games</a>
<a href="leaderboard.html">Leaderboard</a>
<div class="dropdown">
<a class="topnavbutton" href="more/index.html">More ↓</a>
<div class="dropdown-content">
<a href="more/apps.html" class="first">Apps</a>
<a href="more/discord.html">Discord</a>
<a href="more/game_help.html">Game Help</a>
<a href="more/takedown.html">DMCA</a>
<a href="more/blank.html" class="last">about:blank</a>
</div>
</div>
</div>
</nav>
<div id="hamburger-icon" onclick="toggleMobileMenu(this)">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
<ul class="mobile-menu">
<li><a href="./">Games</a></li>
<li><a href="leaderboard.html">Leaderboard</a></li>
<li><a href="more/apps.html">Apps</a></li>
<li><a href="more/discord.html">Discord</a></li>
<li><a href="more/game_help.html">Game Help</a></li>
<li><a href="more/takedown.html">DMCA</a></li>
</ul>
</div>
`;
function spin(element) {
element.style.transform = "rotate(360deg)";
element.style.transition = "transform 0.3s ease";
}
function unspin(element) {
element.style.transform = "";
}
function toggleMobileMenu(menu) {
menu.classList.toggle("open");
}
document.body.appendChild(templatetopnav.content);
// ── Footer ──────────────────────────────────────────────────────────────────
const templatefooter = document.createElement("template");
templatefooter.innerHTML = `
<footer id="site-footer" class="site-footer">
<div class="footer-inner">
<div class="footer-brand">
<img src="./assets/img/grapes_mascot.png" alt="GRAPES OS" width="38" height="38" />
<div>
<a href="./" class="footer-title">GRAPES OS</a>
<div class="footer-sub">1,000,000+ active users since 2022</div>
</div>
</div>
<div class="footer-cols">
<div class="footer-col">
<div class="footer-col-title">Quick Links</div>
<a href="./">Games</a>
<a href="leaderboard.html">Leaderboard</a>
<a href="blog/">Blog</a>
<a href="more/apps.html">Apps & Unblockers</a>
<a href="more/tab-cloak.html">Tab Cloak</a>
<a href="more/streak.html">Streak</a>
<a href="more/discord.html">Discord</a>
<a href="more/game_help.html">Game Help</a>
<a href="more/takedown.html">DMCA</a>
</div>
<div class="footer-col">
<div class="footer-col-title">Socials</div>
<a href="https://github.com/grapes-os/grapes-os.github.io" target="_blank" rel="noopener">GitHub</a>
<a href="https://discord.gg/aMUVSARrEy" target="_blank" rel="noopener">Discord</a>
<a href="https://www.tiktok.com/@rockyf2p" target="_blank" rel="noopener">TikTok</a>
<a href="https://www.youtube.com/@grapes-osgames" target="_blank" rel="noopener">YouTube</a>
<a href="https://www.instagram.com/grapes-os/reels/" target="_blank" rel="noopener">Instagram</a>
</div>
<div class="footer-col footer-manifesto">
<div class="footer-col-title">Manifesto</div>
<p>Gaming is a fundamental right. We build bridges, not walls — accessible gaming for everyone, everywhere.</p>
</div>
</div>
<div class="footer-bottom">
<span>© <span id="footer-year"></span> GRAPES OS</span>
<span>Built for fast, accessible, unblocked gaming.</span>
</div>
</div>
</footer>
`;
document.body.appendChild(templatefooter.content);
const footerYearSpan = document.getElementById("footer-year");
if (footerYearSpan) footerYearSpan.textContent = new Date().getFullYear();
(function ensureFooterLayout() {
if (!document.getElementById("global-footer-layout-style")) {
const s = document.createElement("style");
s.id = "global-footer-layout-style";
s.textContent = `html,body{min-height:100%;}body{display:flex;flex-direction:column;min-height:100vh;}#site-footer{margin-top:auto!important;}`;
document.head.appendChild(s);
}
})();
function placeFooterAtEnd() {
const f = document.getElementById("site-footer");
if (f && document.body.lastElementChild !== f) document.body.appendChild(f);
}
document.addEventListener("DOMContentLoaded", placeFooterAtEnd);
window.addEventListener("load", placeFooterAtEnd);
new MutationObserver(placeFooterAtEnd).observe(document.body, { childList: true });