aaac24b05c
gates / gates (push) Successful in 4m12s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
509 lines
29 KiB
HTML
509 lines
29 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Technology — Docker, the Dashboard and Proxmox for a home server | Felhom.eu</title>
|
||
<meta name="description" content="Industry-grade technology at home, in Hungary: Docker containers, a Dashboard in English or Hungarian, Proxmox virtualisation. HTTPS and an encrypted tunnel — with no open port.">
|
||
|
||
<meta name="keywords" content="Docker, dashboard, Proxmox, container, virtualisation, reverse proxy, HTTPS, encrypted tunnel, home server technology">
|
||
<meta name="robots" content="index, follow">
|
||
<link rel="canonical" href="https://felhom.eu/en/technology">
|
||
<link rel="alternate" hreflang="hu" href="https://felhom.eu/technologiak">
|
||
<link rel="alternate" hreflang="en" href="https://felhom.eu/en/technology">
|
||
<link rel="alternate" hreflang="x-default" href="https://felhom.eu/technologiak">
|
||
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:url" content="https://felhom.eu/en/technology">
|
||
<meta property="og:title" content="Professional technology for a home server">
|
||
<meta property="og:description" content="Docker, a Dashboard in English or Hungarian, Proxmox — industry-grade tools at home.">
|
||
<meta property="og:image" content="https://felhom.eu/assets/og-image-en.png">
|
||
<meta property="og:locale" content="en_GB">
|
||
<meta property="og:site_name" content="Felhom.eu">
|
||
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:title" content="Professional technology for a home server">
|
||
<meta name="twitter:description" content="Docker, a Dashboard in English or Hungarian, Proxmox — industry tools, at home.">
|
||
<meta name="twitter:image" content="https://felhom.eu/assets/og-image-en.png">
|
||
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "Article",
|
||
"headline": "The technology behind a Felhom home server",
|
||
"description": "Docker containers, a Dashboard in English or Hungarian and Proxmox virtualisation for a home server.",
|
||
"author": {"@type": "Organization", "name": "Felhom.eu"},
|
||
"publisher": {"@type": "Organization", "name": "Felhom.eu", "logo": {"@type": "ImageObject", "url": "https://felhom.eu/assets/logo.png"}},
|
||
"mainEntityOfPage": "https://felhom.eu/en/technology"
|
||
}
|
||
</script>
|
||
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
|
||
<link rel="stylesheet" href="/assets/site.css?v=4">
|
||
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
|
||
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
|
||
</head>
|
||
<body class="page-technologiak">
|
||
<nav>
|
||
<div class="container">
|
||
<a href="/en/" class="logo">
|
||
<img src="/assets/logo.png" alt="Felhom.eu logo">
|
||
<span class="logo-text">felhom.eu</span>
|
||
</a>
|
||
<ul class="nav-links">
|
||
<li><a href="/en/#services">Services</a></li>
|
||
<li><a href="/en/apps">Apps</a></li>
|
||
<li><a href="/en/technology" class="active">Technology</a></li>
|
||
<li><a href="/en/backups">Backups</a></li>
|
||
<li><a href="/en/faq">FAQ</a></li>
|
||
<li><a href="/en/contact">Contact</a></li>
|
||
<li class="lang-globe-li"><details class="lang-globe"><summary class="lang-globe-btn" aria-label="Language" title="Language"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-globe"/></svg></summary><ul class="lang-globe-menu"><li><a href="/technologiak" lang="hu" hreflang="hu" class="lang-globe-item">Magyar</a></li><li><a href="/en/technology" lang="en" hreflang="en" class="lang-globe-item current" aria-current="true">English</a></li></ul></details></li>
|
||
</ul>
|
||
<button class="hamburger" id="hamburger" aria-label="Open menu" aria-expanded="false">
|
||
<span class="hamburger-box">
|
||
<span class="hamburger-line"></span>
|
||
<span class="hamburger-line"></span>
|
||
<span class="hamburger-line"></span>
|
||
</span>
|
||
</button>
|
||
</div>
|
||
</nav>
|
||
<div class="mobile-overlay" id="mobileOverlay"></div>
|
||
|
||
<main>
|
||
<section class="page-header">
|
||
<div class="container">
|
||
<h1>The <span>technology</span></h1>
|
||
<p>Modern, proven tools for running a home server. This is how we build the system.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Table of Contents -->
|
||
<section class="content-section" style="padding-top: 0;">
|
||
<div class="container">
|
||
<div class="toc-nav">
|
||
<h3>Contents</h3>
|
||
<ul class="toc-links">
|
||
<li><a href="#containers">Why containers?</a></li>
|
||
<li><a href="#dashboard">The control layer (Dashboard)</a></li>
|
||
<li><a href="#proxmox">Virtualisation (Proxmox)</a></li>
|
||
<li><a href="#network">Network and security</a></li>
|
||
<li><a href="#storage">Storage</a></li>
|
||
<li><a href="#hardware">Hardware set-ups</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Miért konténerek? -->
|
||
<section class="content-section alt-bg" id="containers">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>Why <span>containers?</span></h2>
|
||
<p>The cornerstone of running a modern server</p>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-package"/></svg></span> What is a container?</h3>
|
||
<p>Imagine that every app runs in its own sealed "box". The box holds the app and everything it depends on – so it works the same way anywhere, on any server.</p>
|
||
<p>Containers (Docker) changed how servers are run: simpler installs, easier updates, and more reliable operation.</p>
|
||
|
||
<div class="highlight-box">
|
||
<p><strong>An analogy:</strong> as if every app lived in its own flat in a block of flats. It has its own front door and its own meters, and it does not bother the neighbours – but they still share one building.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="comparison-grid">
|
||
<div class="comparison-card">
|
||
<div class="card-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-monitor"/></svg></div>
|
||
<h3>Traditional install</h3>
|
||
<div class="subtitle">"Straight onto the system"</div>
|
||
<p>The apps are installed straight onto the operating system. They can clash with each other, and they are hard to remove.</p>
|
||
<ul class="feature-list cons">
|
||
<li>Dependencies can get tangled</li>
|
||
<li>Hard to reproduce on another server</li>
|
||
<li>Update = risk</li>
|
||
<li>Removing an app leaves "rubbish" behind</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="comparison-card recommended">
|
||
<div class="card-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-container"/></svg></div>
|
||
<h3>Container install</h3>
|
||
<div class="subtitle">Docker</div>
|
||
<p>Every app runs on its own. A clean, tidy system that is easy to manage.</p>
|
||
<ul class="feature-list">
|
||
<li>Fully isolated apps</li>
|
||
<li>One command = installed</li>
|
||
<li>Simple updates, and a simple way back</li>
|
||
<li>Reproducible anywhere</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Single Node - vezérlőpult -->
|
||
<section class="content-section" id="dashboard">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>The control layer: <span>the Dashboard</span></h2>
|
||
<p>The interface of every Felhom box, in English or Hungarian</p>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-target"/></svg></span> What does the Dashboard do?</h3>
|
||
<p>The Dashboard is on every Felhom box: it is the interface, in English or Hungarian, that runs your system on its Proxmox base. It was designed for home servers: you install apps in a few clicks and never touch a command line — Docker and Proxmox do the work in the background.</p>
|
||
|
||
<ul class="feature-list">
|
||
<li>A web interface in English or Hungarian – the household chooses, and no command-line knowledge is needed</li>
|
||
<li>App catalog – 56 apps to install in a few clicks</li>
|
||
<li>Resource view – memory and storage use as it happens</li>
|
||
<li>Automatic backups – databases and files, with their status watched</li>
|
||
<li>App updates – only versions we have tried, a fresh backup first, and if the new version does not start, the box goes back to the previous one by itself</li>
|
||
<li>System monitoring – health watched all the time, with alerts</li>
|
||
</ul>
|
||
|
||
<div class="dash-grid">
|
||
<figure class="dash-shot">
|
||
<a href="/assets/dashboard-apps-en.webp"><img src="/assets/dashboard-apps-en.webp" alt="The Apps page: cards of installed and installable apps, with their status" width="1440" height="900" loading="lazy"></a>
|
||
<figcaption><strong>Apps</strong> — install in a few clicks, and see what runs and what is up to date.</figcaption>
|
||
</figure>
|
||
<figure class="dash-shot">
|
||
<a href="/assets/dashboard-backups-en.webp"><img src="/assets/dashboard-backups-en.webp" alt="The backups page: each app's database backed up overnight, and checked" width="1440" height="900" loading="lazy"></a>
|
||
<figcaption><strong>Backups</strong> — every night each app's database is backed up and checked.</figcaption>
|
||
</figure>
|
||
</div>
|
||
|
||
<div class="highlight-box">
|
||
<p><strong>Good for:</strong> a home media server, a family cloud, personal projects, a small office.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stack-diagram">
|
||
<h3>How a Felhom box is built</h3>
|
||
<div class="stack-layers">
|
||
<div class="stack-layer">
|
||
<div class="layer-label">Control + apps</div>
|
||
<div class="layer-content highlight">
|
||
<div class="layer-name">Dashboard + Apps</div>
|
||
<div class="layer-tech">An interface in English or Hungarian · Nextcloud, Jellyfin, Immich…</div>
|
||
</div>
|
||
</div>
|
||
<div class="stack-layer">
|
||
<div class="layer-label">Container engine</div>
|
||
<div class="layer-content">
|
||
<div class="layer-name">Docker</div>
|
||
<div class="layer-tech">The apps run in isolated containers</div>
|
||
</div>
|
||
</div>
|
||
<div class="stack-layer">
|
||
<div class="layer-label">System environment</div>
|
||
<div class="layer-content">
|
||
<div class="layer-name">Isolated system environment</div>
|
||
<div class="layer-tech">Your box — a cleanly separated system</div>
|
||
</div>
|
||
</div>
|
||
<div class="stack-layer">
|
||
<div class="layer-label">Base layer</div>
|
||
<div class="layer-content">
|
||
<div class="layer-name">Proxmox VE</div>
|
||
<div class="layer-tech">Virtualisation base · backing up the whole box, restoring</div>
|
||
</div>
|
||
</div>
|
||
<div class="stack-layer">
|
||
<div class="layer-label">Hardware</div>
|
||
<div class="layer-content">
|
||
<div class="layer-name">The server machine</div>
|
||
<div class="layer-tech">Mini PC, tower or server</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Proxmox -->
|
||
<section class="content-section alt-bg" id="proxmox">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>The base layer: <span>Proxmox</span></h2>
|
||
<p>Every Felhom machine is built on this stable base</p>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-layers"/></svg></span> What is Proxmox?</h3>
|
||
<p>Proxmox VE is a free, professional virtualisation platform — the same kind of technology data centres and companies use. It is the base of every Felhom system: we build every machine on it, and the isolated system environment your apps run in sits on top of it.</p>
|
||
|
||
<div class="highlight-box">
|
||
<p><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-layers"/></svg> <strong>The base, not an option:</strong> Proxmox is on every Felhom box. You do not need to know about it or deal with it — it works quietly in the background, and it is what makes your system safe and able to be backed up.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-target"/></svg></span> What does the Proxmox base give you?</h3>
|
||
|
||
<ul class="feature-list">
|
||
<li><strong>A backup before each update</strong> – before an app is updated, a fresh backup is made, and if the new version does not start, the box puts the previous one back by itself</li>
|
||
<li><strong>The whole system is backed up</strong> – not only your data: the whole box goes into a backup too, and it can be restored from it</li>
|
||
<li><strong>Clean separation</strong> – the control layer and your apps run well apart, which makes the system more stable and safer</li>
|
||
<li><strong>A fast, repeatable install</strong> – setting up a new box is quick and predictable, the same way every time</li>
|
||
</ul>
|
||
|
||
<div class="highlight-box">
|
||
<p><strong>One base, one job:</strong> on a Felhom box, Proxmox runs a single isolated system environment — the one your apps work in.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Hálózat -->
|
||
<section class="content-section alt-bg" id="network">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>Network and <span>security</span></h2>
|
||
<p>How do you reach your server safely, from anywhere?</p>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-rotate-cw"/></svg></span> Reverse Proxy</h3>
|
||
<p>A reverse proxy is a "doorkeeper" that takes incoming requests and passes them to the right app. It also handles the HTTPS encryption.</p>
|
||
|
||
<div class="network-flow">
|
||
<div class="flow-node">
|
||
<div class="node-icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-globe"/></svg></div>
|
||
<div class="node-label">Internet</div>
|
||
</div>
|
||
<div class="flow-arrow">→</div>
|
||
<div class="flow-node">
|
||
<div class="node-icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-lock"/></svg></div>
|
||
<div class="node-label">Reverse Proxy</div>
|
||
<div class="node-tech">Traefik</div>
|
||
</div>
|
||
<div class="flow-arrow">→</div>
|
||
<div class="flow-node">
|
||
<div class="node-icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-package"/></svg></div>
|
||
<div class="node-label">App</div>
|
||
</div>
|
||
</div>
|
||
|
||
<ul class="feature-list">
|
||
<li><strong>Traefik</strong> – every app on its own subdomain, over HTTPS</li>
|
||
<li><strong>Encrypted tunnel</strong> – the box itself builds the connection outwards, so no port has to be opened at home</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-shield"/></svg></span> Protection</h3>
|
||
<ul class="feature-list">
|
||
<li><strong>No open port</strong> – from outside, the box is reached only through the encrypted tunnel</li>
|
||
<li><strong>Own sign-in</strong> – every app has its own accounts, and the Dashboard has a password</li>
|
||
<li><strong>Family gate</strong> – some apps sit behind each family member's own sign-in, so a stranger never even reaches the app</li>
|
||
<li><strong>Security updates</strong> – the box's system gets them by itself</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Tárolás -->
|
||
<section class="content-section" id="storage">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>Storage and <span>data safety</span></h2>
|
||
<p>Where and how should you keep your data?</p>
|
||
</div>
|
||
|
||
<div class="comparison-grid">
|
||
<div class="comparison-card">
|
||
<div class="card-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-zap"/></svg></div>
|
||
<h3>SSD (NVMe/SATA)</h3>
|
||
<div class="subtitle">Fast storage</div>
|
||
<ul class="feature-list">
|
||
<li>Operating system</li>
|
||
<li>Databases</li>
|
||
<li>Apps</li>
|
||
</ul>
|
||
</div>
|
||
<div class="comparison-card">
|
||
<div class="card-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-database"/></svg></div>
|
||
<h3>HDD</h3>
|
||
<div class="subtitle">Large capacity</div>
|
||
<ul class="feature-list">
|
||
<li>Media library</li>
|
||
<li>Photo archive</li>
|
||
<li>Backups</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="info-card" style="margin-top: 32px;">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-rotate-cw"/></svg></span> Backups on three levels – how we protect your data</h3>
|
||
<p>Every night a Felhom box makes a <strong>backup on the box</strong>, a <strong>second copy on a second drive</strong>, and an <strong>encrypted copy on remote storage</strong>. The levels protect together: the local one is fast, and the remote one survives even if the box itself is physically harmed.</p>
|
||
|
||
<div class="warning-box">
|
||
<p><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-triangle-alert"/></svg> <strong>More disks are not a backup on their own!</strong> RAID-like set-ups protect against hardware failure, but not against an accidental delete or ransomware. That is why our backups always sit on a separate level, not in the disks.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Hardver konfigurációk -->
|
||
<section class="content-section alt-bg" id="hardware">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>Hardware <span>set-ups</span></h2>
|
||
<p>Which machine do you need? A few example set-ups</p>
|
||
</div>
|
||
|
||
<div class="hardware-grid">
|
||
<div class="hardware-card">
|
||
<div class="hardware-card-header">
|
||
<div class="hw-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-package"/></svg></div>
|
||
<h3>Mini PC + NAS</h3>
|
||
<div class="hw-subtitle">Starter / Home</div>
|
||
</div>
|
||
<div class="hardware-card-body">
|
||
<p>Compact, quiet and energy-saving.</p>
|
||
<ul class="spec-list">
|
||
<li><span class="spec-label">CPU</span><span class="spec-value">Intel N100</span></li>
|
||
<li><span class="spec-label">RAM</span><span class="spec-value">16-32 GB</span></li>
|
||
<li><span class="spec-label">SSD</span><span class="spec-value">256-512 GB</span></li>
|
||
<li><span class="spec-label">Power use</span><span class="spec-value">15-35W</span></li>
|
||
</ul>
|
||
<div class="price-range">
|
||
<div class="label">Estimated cost</div>
|
||
<div class="price">80.000 - 150.000 Ft</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hardware-card">
|
||
<div class="hardware-card-header">
|
||
<div class="hw-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-radio-tower"/></svg></div>
|
||
<h3>Tower server</h3>
|
||
<div class="hw-subtitle">Advanced / Family</div>
|
||
</div>
|
||
<div class="hardware-card-body">
|
||
<p>More power and more storage.</p>
|
||
<ul class="spec-list">
|
||
<li><span class="spec-label">CPU</span><span class="spec-value">Intel i5/i7</span></li>
|
||
<li><span class="spec-label">RAM</span><span class="spec-value">32-64 GB</span></li>
|
||
<li><span class="spec-label">Storage</span><span class="spec-value">4-8 TB</span></li>
|
||
<li><span class="spec-label">Power use</span><span class="spec-value">50-120W</span></li>
|
||
</ul>
|
||
<div class="price-range">
|
||
<div class="label">Estimated cost</div>
|
||
<div class="price">200.000 - 400.000 Ft</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hardware-card">
|
||
<div class="hardware-card-header">
|
||
<div class="hw-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-building-2"/></svg></div>
|
||
<h3>Rack server</h3>
|
||
<div class="hw-subtitle">Business / on request</div>
|
||
</div>
|
||
<div class="hardware-card-body">
|
||
<p>Industrial quality, high reliability.</p>
|
||
<ul class="spec-list">
|
||
<li><span class="spec-label">CPU</span><span class="spec-value">Xeon / EPYC</span></li>
|
||
<li><span class="spec-label">RAM</span><span class="spec-value">64-256 GB ECC</span></li>
|
||
<li><span class="spec-label">Storage</span><span class="spec-value">8-24 bay</span></li>
|
||
<li><span class="spec-label">Extra</span><span class="spec-value">IPMI, red. PSU</span></li>
|
||
</ul>
|
||
<div class="price-range">
|
||
<div class="label">Estimated cost (used)</div>
|
||
<div class="price">150.000 - 600.000 Ft</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="info-card" style="margin-top: 48px;">
|
||
<h3><span class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-lightbulb"/></svg></span> Which one should you choose?</h3>
|
||
<div class="highlight-box">
|
||
<p><strong>Our advice:</strong> start small! A good mini PC is enough for most homes, and you can expand it later. A rack server is a business / on-request set-up — a home rarely needs one.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CTA -->
|
||
<section class="cta-section">
|
||
<div class="container">
|
||
<h2>Not sure which <span>set-up is right for you?</span></h2>
|
||
<p>Let's talk through what you need, and we will help you find the right set-up.</p>
|
||
<a href="/en/contact" class="cta-button">Get in touch →</a>
|
||
<a href="/en/apps" class="cta-button-secondary">Browse the apps →</a>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<footer>
|
||
<div class="container">
|
||
<p>© 2026 felhom.eu — Your own cloud, your own rules. Felhom serves households in Hungary.</p>
|
||
</div>
|
||
</footer>
|
||
<script>
|
||
(function() {
|
||
var hamburger = document.getElementById('hamburger');
|
||
var navLinks = document.querySelector('.nav-links');
|
||
var overlay = document.getElementById('mobileOverlay');
|
||
var body = document.body;
|
||
|
||
if (!hamburger || !navLinks || !overlay) {
|
||
console.warn('[mobile-menu] Missing elements:', {
|
||
hamburger: !!hamburger,
|
||
navLinks: !!navLinks,
|
||
overlay: !!overlay
|
||
});
|
||
return;
|
||
}
|
||
|
||
function openMenu() {
|
||
hamburger.classList.add('is-active');
|
||
navLinks.classList.add('is-open');
|
||
overlay.classList.add('is-visible');
|
||
body.classList.add('menu-open');
|
||
hamburger.setAttribute('aria-expanded', 'true');
|
||
hamburger.setAttribute('aria-label', 'Close menu');
|
||
}
|
||
|
||
function closeMenu() {
|
||
hamburger.classList.remove('is-active');
|
||
navLinks.classList.remove('is-open');
|
||
overlay.classList.remove('is-visible');
|
||
body.classList.remove('menu-open');
|
||
hamburger.setAttribute('aria-expanded', 'false');
|
||
hamburger.setAttribute('aria-label', 'Open menu');
|
||
}
|
||
|
||
hamburger.addEventListener('click', function() {
|
||
if (navLinks.classList.contains('is-open')) {
|
||
closeMenu();
|
||
} else {
|
||
openMenu();
|
||
}
|
||
});
|
||
|
||
overlay.addEventListener('click', closeMenu);
|
||
|
||
navLinks.querySelectorAll('a').forEach(function(link) {
|
||
link.addEventListener('click', closeMenu);
|
||
});
|
||
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'Escape' && navLinks.classList.contains('is-open')) {
|
||
closeMenu();
|
||
}
|
||
});
|
||
|
||
window.addEventListener('resize', function() {
|
||
if (window.innerWidth > 900 && navLinks.classList.contains('is-open')) {
|
||
closeMenu();
|
||
}
|
||
});
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html> |