0b34be8449
gates / gates (push) Successful in 8m50s
Staged under /preview/m3/. Nothing live. 19 shell pages in total with the home.
Each page keeps its own <head> byte-for-byte apart from two additions (shell.css
and the no-js/js hook), so title, meta description, canonical, hreflang, Open Graph
and JSON-LD all survive the move untouched. The body loses the website's
<nav>/<footer> and the old hamburger script, and gains the shell.
PROVED, not assumed - a word-level diff of every page's visible text, live vs
shell, with the nav and footer removed from both:
* 18 of 18 pages: visible text IDENTICAL after the one allowed substitution
* adatkezeles and feltetelek: identical with NO substitution permitted at all.
The legal texts are reviewed documents; the frame changed, the words did not.
That check earned itself immediately. The first version of the page-header
transform rebuilt the block from its <h1> and first <p> and SILENTLY DROPPED the
rest: the "Fontos tudnivalok" / "Good to know" disclaimer banner on both apps
pages and the 404's English line - 168 words across three pages. Nothing looked
wrong on the page. The diff found it.
Em dashes: 318 replaced with the Hungarian gondolatjel across 16 pages (gyik and
en/faq 104 each). The FAQ pages' JSON-LD is swept with the SAME substitution, so
gate 17's equality with the visible answers still holds - it does, on both.
scripts/site_gates.py:
* SHELL now holds all 19 pages.
* is_en(): a page is English if it is a TWINS value OR lives under an en/
directory. Without the second half the dash-language, <html lang> and
no-Hungarian gates all judged preview/m3/en/* as Hungarian - 30 false fails.
* norm_block() also drops `is-open` and `aria-expanded`, because the shell
renders the nav group containing the active page open, exactly as the
controller does, and that legitimately differs per page.
The last change LOOSENS a check, so it was red-proofed BOTH ways: a one-character
difference in one menu label still convicts, and a state-only difference (the
active marker moving to another item) correctly does not.
One generator now owns the shell. The home page's content comes from m3.py and its
shell from the same function every other page uses, so the two cannot drift - which
they already had, and gate 3b caught it.
371 lines
23 KiB
HTML
371 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="hu" class="no-js">
|
||
<head>
|
||
<script>document.documentElement.className=document.documentElement.className.replace('no-js','js');</script>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Biztonsági mentés — 3-2-1 mentési stratégia otthoni szerverekhez | Felhom.eu</title>
|
||
<meta name="description" content="Professzionális 3-2-1 biztonsági mentés otthoni szerverhez. Automatikus backup három szinten: a dobozon, egy második meghajtón és titkosítva egy távoli tárhelyen.">
|
||
<meta name="keywords" content="biztonsági mentés, backup, 3-2-1 mentési szabály, offsite backup, adatmentés, otthoni szerver backup, titkosított mentés, automatikus mentés">
|
||
<meta name="robots" content="index, follow">
|
||
<link rel="canonical" href="https://felhom.eu/biztonsagimentes">
|
||
<link rel="alternate" hreflang="hu" href="https://felhom.eu/biztonsagimentes">
|
||
<link rel="alternate" hreflang="en" href="https://felhom.eu/en/backups">
|
||
<link rel="alternate" hreflang="x-default" href="https://felhom.eu/biztonsagimentes">
|
||
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:url" content="https://felhom.eu/biztonsagimentes">
|
||
<meta property="og:title" content="3-2-1 biztonsági mentés otthoni szerverhez">
|
||
<meta property="og:description" content="Professzionális szintű adatbiztonság otthon. Automatikus backup, és egy titkosított másolat távol is.">
|
||
<meta property="og:image" content="https://felhom.eu/assets/og-image.png">
|
||
<meta property="og:locale" content="hu_HU">
|
||
<meta property="og:site_name" content="Felhom.eu">
|
||
|
||
<meta name="twitter:card" content="summary_large_image">
|
||
<meta name="twitter:title" content="3-2-1 biztonsági mentés otthoni szerverhez">
|
||
<meta name="twitter:description" content="Professzionális adatvédelem otthoni szerveredre. Automatikus backup, offsite mentés.">
|
||
<meta name="twitter:image" content="https://felhom.eu/assets/og-image.png">
|
||
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "Article",
|
||
"headline": "3-2-1 biztonsági mentési stratégia otthoni szerverekhez",
|
||
"description": "Hogyan védd meg az adataidat professzionális mentési stratégiával otthoni környezetben.",
|
||
"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/biztonsagimentes"
|
||
}
|
||
</script>
|
||
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
|
||
<link rel="stylesheet" href="/assets/site.css?v=19">
|
||
<link rel="stylesheet" href="/assets/shell.css?v=19">
|
||
<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="shell page-biztonsagimentes">
|
||
<header class="mobile-topbar">
|
||
<a href="/preview/m3/" class="mobile-topbar-logo"><img src="/assets/logo_notext_white.svg" alt="Felhom.eu"></a>
|
||
<button type="button" class="nav-burger" id="navBurger" aria-expanded="false" aria-controls="sidebar" aria-label="Menü">
|
||
<span class="hamburger-box"><span class="hamburger-line"></span><span class="hamburger-line"></span><span class="hamburger-line"></span></span>
|
||
</button>
|
||
</header>
|
||
<div class="nav-backdrop" id="navBackdrop" hidden></div>
|
||
<nav class="sidebar" id="sidebar">
|
||
<div class="sidebar-header">
|
||
<a href="/preview/m3/" class="sidebar-logo-link">
|
||
<img src="/assets/logo_notext_white.svg" alt="" class="sidebar-logo" aria-hidden="true">
|
||
<img src="/assets/logo-wordmark.png" alt="felhom.eu" class="sidebar-word">
|
||
</a>
|
||
</div>
|
||
<ul class="nav-links">
|
||
<li><a href="/preview/m3/"><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-home"/></svg>Kezdőlap</a></li>
|
||
<li><a href="/preview/m3/#szolgaltatasok"><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-rocket"/></svg>Szolgáltatások</a></li>
|
||
<li class="nav-group">
|
||
<button type="button" class="nav-group-toggle" aria-expanded="false" aria-controls="nav-group-apps"><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-package"/></svg>Alkalmazások<svg class="ico nav-chevron" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-chevron-down"/></svg></button>
|
||
<ul id="nav-group-apps" class="nav-links nav-links-sub nav-links-nested">
|
||
<li><a href="/preview/m3/alkalmazasok">Minden alkalmazás</a></li>
|
||
<li><a href="/preview/m3/alkalmazasok#fajlkezeles-irodai">Fájlkezelés & Irodai</a></li>
|
||
<li><a href="/preview/m3/alkalmazasok#media-szorakozas">Média & Szórakozás</a></li>
|
||
<li><a href="/preview/m3/alkalmazasok#otthon-eletmod">Otthon & Életmód</a></li>
|
||
<li><a href="/preview/m3/alkalmazasok#produktivitas-tudaskezeles">Produktivitás & Tudáskezelés</a></li>
|
||
<li><a href="/preview/m3/alkalmazasok#rendszer-fejlesztes">Rendszer & Fejlesztés</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="/preview/m3/technologiak"><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-layers"/></svg>Technológiák</a></li>
|
||
<li><a href="/preview/m3/biztonsagimentes" class="active"><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-shield-check"/></svg>Biztonsági mentés</a></li>
|
||
</ul>
|
||
<div class="sidebar-bottom">
|
||
<a href="/preview/m3/teszteles" class="btn btn-outline sidebar-cta">Jelentkezem tesztelőnek →</a>
|
||
<div class="nav-group-label">A Felhomról</div>
|
||
<ul class="nav-links nav-links-sub">
|
||
<li><a href="/preview/m3/#hogyan-mukodik">Hogyan működik</a></li>
|
||
<li><a href="/preview/m3/gyik">GYIK</a></li>
|
||
<li><a href="/preview/m3/kapcsolat">Kapcsolat</a></li>
|
||
</ul>
|
||
<div class="sidebar-footer">
|
||
<details class="lang-globe"><summary class="lang-globe-btn" aria-label="Nyelv" title="Nyelv"><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-globe"/></svg></summary><ul class="lang-globe-menu"><li><a href="/preview/m3/biztonsagimentes" lang="hu" hreflang="hu" class="lang-globe-item current" aria-current="true">Magyar</a></li><li><a href="/preview/m3/en/backups" lang="en" hreflang="en" class="lang-globe-item">English</a></li></ul></details>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
|
||
<main class="content">
|
||
<div class="page-header">
|
||
<h1>Biztonsági <span>Mentés</span></h1>
|
||
</div>
|
||
<p class="page-lede">Az adataid biztonsága az első. Professzionális mentési stratégiával gondoskodunk róla, hogy egy hiba vagy baleset után is legyen honnan visszahozni.</p>
|
||
|
||
|
||
<!-- Bevezető -->
|
||
<section class="content-section">
|
||
<div class="container">
|
||
<div class="info-card">
|
||
<h3><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-circle-help"/></svg> Miért fontos ez?</h3>
|
||
<p>Amikor valaki felhőszolgáltatást választ – legyen az Google Drive, iCloud, vagy bármilyen más – az egyik legfontosabb szempont az <strong>adatbiztonság</strong>. Nem az a kérdés, hogy valaki hozzáfér-e az adatainkhoz, hanem hogy <strong>megmaradnak-e</strong>.</p>
|
||
<p>A nagy szolgáltatók ezt milliárd dolláros infrastruktúrával oldják meg: több adatközpont, redundáns tárolás, automatikus mentések. De vajon otthoni szerveren is elérhető ugyanez a biztonság?</p>
|
||
<div class="highlight-box">
|
||
<p><strong>A válasz: igen.</strong> A megfelelő mentési stratégiával az otthoni szervered ugyanolyan biztonságos lehet, mint bármely felhőszolgáltató – sőt, te irányítasz mindent.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 3-2-1 szabály -->
|
||
<section class="content-section alt-bg">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>A 3-2-1 <span>Mentési Szabály</span></h2>
|
||
<p>Az iparági szabvány, amit a professzionális rendszergazdák és vállalatok használnak világszerte</p>
|
||
</div>
|
||
|
||
<div class="backup-rule">
|
||
<div class="rule-number">3</div>
|
||
<div class="rule-content">
|
||
<h3>Három másolat az adataidból</h3>
|
||
<p>Mindig legyen legalább három példány minden fontos adatodból: az eredeti, és két biztonsági másolat. Ha az egyik sérül vagy elvész, még mindig van kettő tartalékban.</p>
|
||
<div class="example-box">
|
||
<div class="label">Példa</div>
|
||
<p>A családi fotóid megvannak a szerveren (1), egy külső merevlemezen (2), és egy távoli helyen (3).</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="backup-rule">
|
||
<div class="rule-number">2</div>
|
||
<div class="rule-content">
|
||
<h3>Két különböző tárolótípus</h3>
|
||
<p>Az adatokat legalább kétféle tárolóeszközön tartsd. A különböző eszközök különböző meghibásodási módokkal rendelkeznek – ha az egyik típus elromlik, a másik valószínűleg rendben lesz.</p>
|
||
<div class="example-box">
|
||
<div class="label">Példa</div>
|
||
<p>A szerver belső SSD-jén tárolod az adatokat, de a mentés külső HDD-re vagy NAS-ra kerül.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="backup-rule">
|
||
<div class="rule-number">1</div>
|
||
<div class="rule-content">
|
||
<h3>Egy offsite (távoli) másolat</h3>
|
||
<p>Legalább egy másolat legyen fizikailag más helyen. Ez véd a lokális katasztrófák ellen: tűz, vízkár, betörés, vagy akár egy villámcsapás sem veszélyeztetheti az összes adatodat.</p>
|
||
<div class="example-box">
|
||
<div class="label">Példa</div>
|
||
<p>A mentés automatikusan átmásolódik egy barát/rokon szerverére, vagy titkosítva felhőbe kerül.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="backup-diagram">
|
||
<h3>Így néz ki a gyakorlatban</h3>
|
||
<div class="diagram-visual">
|
||
<div class="diagram-node primary">
|
||
<div class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-monitor"/></svg></div>
|
||
<div class="label">Szerver</div>
|
||
<div class="sublabel">Eredeti adat</div>
|
||
</div>
|
||
<div class="diagram-arrow">→</div>
|
||
<div class="diagram-node">
|
||
<div class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-hard-drive"/></svg></div>
|
||
<div class="label">Helyi backup</div>
|
||
<div class="sublabel">Külső HDD/NAS</div>
|
||
</div>
|
||
<div class="diagram-arrow">→</div>
|
||
<div class="diagram-node">
|
||
<div class="icon"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-globe"/></svg></div>
|
||
<div class="label">Offsite backup</div>
|
||
<div class="sublabel">Távoli hely</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Offsite megoldások -->
|
||
<section class="content-section">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>Offsite <span>Mentési Megoldások</span></h2>
|
||
<p>Az "1" a 3-2-1 szabályban – a legfontosabb, és sokszor a legelhanyagoltabb</p>
|
||
</div>
|
||
|
||
<div class="methods-grid">
|
||
<div class="method-card">
|
||
<div class="method-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-users"/></svg></div>
|
||
<h3>„Haver rendszer"</h3>
|
||
<p>A legegyszerűbb és legolcsóbb megoldás: cserélj mentéseket egy megbízható ismerőssel. Te mentesz az ő szerverére, ő ment a tiédre.</p>
|
||
<ul class="method-pros">
|
||
<li>Nincs havi díj</li>
|
||
<li>Teljes kontroll az adatok felett</li>
|
||
<li>Kölcsönös biztonság</li>
|
||
<li>End-to-end titkosítás lehetséges</li>
|
||
</ul>
|
||
<div class="example-box">
|
||
<div class="label">Hogyan működik?</div>
|
||
<p>Titkosított mentések automatikusan szinkronizálódnak VPN kapcsolaton keresztül.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="method-card">
|
||
<div class="method-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-building-2"/></svg></div>
|
||
<h3>Otthon ↔ Iroda</h3>
|
||
<p>Ha van munkahelyed vagy saját irodád, használd ki! A két helyszín természetes földrajzi távolságot biztosít.</p>
|
||
<ul class="method-pros">
|
||
<li>Meglévő infrastruktúra használata</li>
|
||
<li>Biztonságos, ismert környezet</li>
|
||
<li>Gyors helyreállítás szükség esetén</li>
|
||
</ul>
|
||
<div class="example-box">
|
||
<div class="label">Tipp</div>
|
||
<p>Egy kis, csendes mini PC az iroda sarkában tökéletes backup célpont lehet.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="method-card">
|
||
<div class="method-icon"><svg class="ico-tile" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-cloud"/></svg></div>
|
||
<h3>Titkosított felhő backup</h3>
|
||
<p>Ha nincs megbízható ismerős vagy második helyszín, a felhő a megoldás. Fontos: az adatokat a feltöltés előtt titkosítjuk!</p>
|
||
<ul class="method-pros">
|
||
<li>Professzionális infrastruktúra</li>
|
||
<li>Földrajzilag elosztott tárolás</li>
|
||
<li>Nincs szükség hardverre</li>
|
||
</ul>
|
||
<ul class="method-pros method-cons">
|
||
<li>Havi/éves díj (tárolás méretétől függően)</li>
|
||
</ul>
|
||
<div class="example-box">
|
||
<div class="label">Megjegyzés</div>
|
||
<p>A tárhely díja a mentett adatmennyiségtől függ. A Felhom dobozon ezt a megoldást használjuk.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Mi hogyan csináljuk -->
|
||
<section class="content-section alt-bg">
|
||
<div class="container">
|
||
<div class="section-header">
|
||
<h2>Mi Hogyan <span>Oldjuk Meg?</span></h2>
|
||
<p>Minden általunk telepített szerveren alapértelmezetten beállítjuk a mentéseket</p>
|
||
</div>
|
||
|
||
<div class="info-card">
|
||
<h3><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-wrench"/></svg> Automatizált mentési rendszer</h3>
|
||
<p>A szerver minden éjjel magától készít mentéseket, három szinten: <strong>a dobozon</strong>, egy <strong>második meghajtón</strong> (ha van), és <strong>titkosítva egy távoli tárhelyen</strong>. Nem kell semmire sem emlékezned – a rendszer gondoskodik róla.</p>
|
||
<p>A mentések inkrementálisak, ami azt jelenti, hogy csak a változások kerülnek mentésre. Ez helyet és időt takarít meg, miközben a teljes visszaállítási lehetőség megmarad.</p>
|
||
|
||
<div class="highlight-box">
|
||
<p><svg class="ico" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-monitor"/></svg> <strong>Nem csak az adatok:</strong> a Proxmox alapnak köszönhetően nem csupán a fájljaid és adatbázisaid menthetők, hanem az <strong>egész rendszered</strong> is – a teljes doboz is biztonsági mentésbe kerül, és ebből visszaállítható. Ha maga a doboz megy tönkre, az újratelepített rendszerre a titkosított távoli mentésből visszahozhatók az alkalmazásaid adatai – a helyreállítási kóddal.</p>
|
||
</div>
|
||
|
||
<div class="highlight-box">
|
||
<p><strong>A távoli mentés helye:</strong> a Felhom dobozon a távoli másolat egy általunk biztosított tárhelyre kerül, titkosítva. A „haver rendszer” és az iroda általános lehetőségek a 3-2-1 szabályhoz – ezeket ma nem állítjuk be.</p>
|
||
</div>
|
||
|
||
<h3 style="margin-top: 24px;"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-lock"/></svg> A helyreállítási kód – amit csak te ismersz</h3>
|
||
<p>A távoli mentésed titkosított, és a titkosítás kulcsa egy <strong>helyreállítási kód</strong>. Ez a kód pontosan egyszer jelenik meg: a te képernyődön, a beállításkor. Nálunk nem marad belőle másolat.</p>
|
||
<p>Ez tudatos döntés, és két oldala van. Az egyik, hogy a távoli mentésedet rajtad kívül <strong>senki</strong> nem tudja elolvasni – mi sem. A másik, hogy ha a doboz megsemmisül és a kód is elveszett, akkor a távoli mentés <strong>nekünk sem visszaállítható</strong>. Ezért a kód papírra kerül, és jó helyre.</p>
|
||
|
||
<h3 style="margin-top: 24px;"><svg class="ico-lg" aria-hidden="true"><use href="/assets/icons.svg?v=1#i-chart-column"/></svg> Monitoring és értesítések</h3>
|
||
<p>A mentéseket folyamatosan figyeljük. Ha probléma van – sikertelen mentés, betelő tárhely, kapcsolati hiba – az a felügyeleti rendszerünkben megjelenik, és e-mail értesítés is indul róla. A zárt teszt egyik célja épp az, hogy ezeket az értesítéseket éles körülmények között csiszoljuk.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CTA -->
|
||
<section class="cta-section">
|
||
<div class="container">
|
||
<h2>Kérdésed van a <span>mentésekről?</span></h2>
|
||
<p>Beszéljük át, mi a legjobb megoldás a te helyzetedben. Segítünk megtalálni az egyensúlyt a biztonság és a költségek között.</p>
|
||
<a href="/kapcsolat" class="cta-button">Kapcsolatfelvétel →</a>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
<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', 'Menü bezárása');
|
||
}
|
||
|
||
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', 'Menü megnyitása');
|
||
}
|
||
|
||
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>
|
||
<script>
|
||
(function(){
|
||
var b=document.getElementById('navBurger'),s=document.getElementById('sidebar'),k=document.getElementById('navBackdrop');
|
||
if(!b||!s||!k)return;
|
||
function open(){s.classList.add('is-open');k.hidden=false;document.body.classList.add('nav-open');b.setAttribute('aria-expanded','true');}
|
||
function close(){s.classList.remove('is-open');k.hidden=true;document.body.classList.remove('nav-open');b.setAttribute('aria-expanded','false');}
|
||
b.addEventListener('click',function(){s.classList.contains('is-open')?close():open();});
|
||
k.addEventListener('click',close);
|
||
document.addEventListener('keydown',function(e){if(e.key==='Escape'&&s.classList.contains('is-open')){close();b.focus();}});
|
||
s.querySelectorAll('a').forEach(function(l){l.addEventListener('click',close);});
|
||
window.addEventListener('resize',function(){if(window.innerWidth>768)close();});
|
||
})();
|
||
document.addEventListener('click',function(e){
|
||
var btn=e.target.closest?e.target.closest('.nav-group-toggle'):null;
|
||
if(!btn)return;
|
||
var g=btn.closest('.nav-group');if(!g)return;
|
||
var willOpen=!g.classList.contains('is-open');
|
||
document.querySelectorAll('.nav-group.is-open').forEach(function(x){
|
||
x.classList.remove('is-open');
|
||
var t=x.querySelector('.nav-group-toggle');if(t)t.setAttribute('aria-expanded','false');
|
||
});
|
||
if(willOpen){g.classList.add('is-open');btn.setAttribute('aria-expanded','true');}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|