Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,41 @@ function initSlider() {
renderShot(0)
}

/* ---------- lightbox de capturas ---------- */
function initLightbox() {
const lightbox = document.getElementById('lightbox')
const lightboxImg = document.getElementById('lightboxImg')
const lightboxCaption = document.getElementById('lightboxCaption')
const lightboxClose = document.getElementById('lightboxClose')
if (!lightbox || !lightboxImg) return

function openLightbox(img) {
lightboxImg.src = img.currentSrc || img.src
lightboxImg.alt = img.alt
lightboxCaption.textContent = img.alt
lightbox.hidden = false
lightbox.setAttribute('aria-hidden', 'false')
if (lightboxClose) lightboxClose.focus()
document.body.style.overflow = 'hidden'
}

function closeLightbox() {
lightbox.hidden = true
lightbox.setAttribute('aria-hidden', 'true')
document.body.style.overflow = ''
}

document.querySelectorAll('img[data-shot]').forEach((img) => {
img.addEventListener('click', () => openLightbox(img))
})
if (lightboxClose) lightboxClose.addEventListener('click', closeLightbox)
lightbox.addEventListener('click', (e) => { if (e.target === lightbox) closeLightbox() })
document.addEventListener('keydown', (e) => {
if (lightbox.hidden) return
if (e.key === 'Escape') closeLightbox()
})
}

document.addEventListener('DOMContentLoaded', () => {
initAppearance()
initBackgroundCanvas()
Expand All @@ -1403,5 +1438,6 @@ document.addEventListener('DOMContentLoaded', () => {
initKofi()
initTrafficRanges()
initSlider()
initLightbox()
heroCountUps()
})
Binary file modified web/assets/shot-alerts-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-alerts-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-alerts-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-alerts-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-devices-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-devices-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-devices-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-devices-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-overview-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-overview-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-overview-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-overview-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-routers-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-routers-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-routers-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-routers-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-settings-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-settings-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-settings-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-settings-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-topology-en-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-topology-en-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-topology-es-dark.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified web/assets/shot-topology-es-light.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions web/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ const I18N = {
s5: 'Alerts · the feed of what happens in your network',
s6: 'Settings · appearance, users, routers and services',
},
lightbox: {
close: 'Close screenshot',
alt: 'Screenshot enlarged',
},
},

/* ---------------- ESPAÑOL ---------------- */
Expand Down Expand Up @@ -250,6 +254,10 @@ const I18N = {
s5: 'Alertas · el feed de lo que pasa en tu red',
s6: 'Ajustes · apariencia, usuarios, routers y servicios',
},
lightbox: {
close: 'Cerrar captura',
alt: 'Captura ampliada',
},
},

/* ---------------- 中文 (简体) ---------------- */
Expand Down
15 changes: 11 additions & 4 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="styles.css?v=20260806" />
<link rel="stylesheet" href="styles.css?v=20260806b" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
Expand Down Expand Up @@ -487,7 +487,7 @@ <h2 class="font-display text-balance" data-i18n="shots.title">Un vistazo a la in
<button class="slider-arrow prev" id="shotPrev" aria-label="Captura anterior" data-i18n-aria="shots.prev">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" width="20" height="20" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
</button>
<img id="shotImg" src="assets/shot-overview-es-light.webp" alt="" width="1440" height="900">
<img id="shotImg" src="assets/shot-overview-es-light.webp" alt="" width="1440" height="900" data-shot>
<button class="slider-arrow next" id="shotNext" aria-label="Captura siguiente" data-i18n-aria="shots.next">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" width="20" height="20" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
</button>
Expand Down Expand Up @@ -627,7 +627,14 @@ <h5 data-i18n="appearance.title">Apariencia</h5>
<div class="panel-note" data-i18n="appearance.note">Mismos tokens que la app — pruébalo en vivo.</div>
</div>

<script src="i18n.js?v=20260806"></script>
<script src="app.js?v=20260806"></script>
<!-- ============ LIGHTBOX CAPTURAS ============ -->
<div id="lightbox" class="lightbox" hidden aria-hidden="true">
<button class="lightbox-close" id="lightboxClose" data-i18n-aria="lightbox.close" aria-label="Cerrar">×</button>
<img id="lightboxImg" class="lightbox-img" src="" alt="" data-i18n-alt="lightbox.alt" />
<p class="lightbox-caption" id="lightboxCaption"></p>
</div>

<script src="i18n.js?v=20260806b"></script>
<script src="app.js?v=20260806b"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions web/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -521,3 +521,32 @@ html[dir="rtl"] .honest { border-left: none; border-right: 3px solid rgb(var(--w
.slider-thumbs { justify-content: flex-start; overflow-x: auto; padding-bottom: 0.5rem; }
.thumb { width: 110px; flex: none; }
}

/* ---------- lightbox de capturas ---------- */
#shotImg[data-shot] { cursor: zoom-in; }
.lightbox {
position: fixed; inset: 0; z-index: 100;
background: rgb(5 8 14 / 0.94);
align-items: center; justify-content: center;
flex-direction: column; gap: 1rem;
padding: 2rem;
cursor: zoom-out;
}
.lightbox:not([hidden]) { display: flex; }
.lightbox[hidden] { display: none; }
.lightbox-img {
max-width: 92vw; max-height: 82vh;
border-radius: var(--radius);
box-shadow: 0 20px 60px rgb(0 0 0 / 0.55);
}
.lightbox-caption { color: rgb(var(--text-secondary)); font-size: 0.95rem; text-align: center; }
.lightbox-close {
position: absolute; top: 1.25rem; right: 1.5rem;
width: 44px; height: 44px; border-radius: 50%;
border: 1px solid rgb(255 255 255 / 0.3);
background: transparent; color: #fff;
font-size: 1.8rem; line-height: 1; cursor: pointer;
display: flex; align-items: center; justify-content: center;
}
.lightbox-close:hover { background: rgb(255 255 255 / 0.15); }
.lightbox-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
Loading