website: one picture viewer (assets/gallery.js) for app and dashboard pictures — declared data-gallery sets, a click on the big picture closes, JS-off still opens the file; site gate 20 + 4 decoys; demo-hp language read back (hu); R-908 (old Resend key in homelab-manifests history); 131 -> 132
gates / gates (push) Successful in 4m25s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-08 13:14:24 +02:00
parent 460135a15a
commit 79c53b5f1a
27 changed files with 711 additions and 734 deletions
+7
View File
@@ -48,6 +48,13 @@ household guest; method and privacy scan: `documentation/audits/website-dashboar
release that visibly changes a pictured page (Launcher, Apps, an app's page, Backup → Apps) should refresh them.**
Every caption is a claim (`captions-claims.md` there). Gate 19 keeps each page on its own language's pictures.
## The picture viewer
**One viewer, in `assets/gallery.js`** — never an inline copy (gate 20). A picture set is DECLARED in the page: each
picture is an `<a href="/assets/…" data-gallery="<set>">` (further pictures of an app card are hidden links in the card);
a set is all links with the same name, in page order. **JavaScript off must still work** — the link opens the picture.
A page with openers loads `gallery.js?v=N`; bump N when the file changes.
## The encoding fences
- **All `website/` HTML is UTF-8 *with BOM*. Preserve it.** An editor that strips the BOM is a
+1
View File
@@ -59,6 +59,7 @@ Full designs: `documentation/audits/day-2026-10-08/`.
- **A missing-page (404) page exists now.**
- **The language link is now a globe icon**, like the dashboard's: a click shows „Magyar" and „English".
- **The website now shows the dashboard**: four real pictures on the home page (and two on the technology page), Hungarian on Hungarian pages, English on English ones. Two small dashboard defects were filed.
- **One picture viewer for the whole site:** the dashboard pictures open like the app pictures, and a click on the big picture closes it.
- **The contact form's lost program code was searched for everywhere I can reach: not found.** The running program is now saved in git, so it cannot be lost. A plan for a replacement is written. One question for you: is the February folder on your Windows computer?
**Needs you:** two choices in `REPORT-website-refresh.md`. If nothing: SparkyFitness stays listed; the contact
@@ -0,0 +1,16 @@
### site/opener-without-href rc=1
mutation (website/en/apps.html): '<a href="/assets/immich-screenshot-1.webp" data-gallery="immich" class="app-shot-link">' -> '<a data-gallery="immich" class="app-shot-link">'
FAIL: en/apps.html: a data-gallery opener that is not an <a href="/assets/…">: <a data-gallery="immich" class="app-shot-link">
### site/opener-to-missing-file rc=1
mutation (website/index.html): '<a href="/assets/dashboard-apps-hu.webp" data-gallery="dashboard">' -> '<a href="/assets/dashboard-apps-hu-old.webp" data-gallery="dashboard">'
FAIL: index.html: a data-gallery opener points at a missing file: /assets/dashboard-apps-hu-old.webp
### site/openers-but-no-script rc=1
mutation (website/en/technology.html): '<script defer src="/assets/gallery.js?v=1"></script>' -> ''
FAIL: en/technology.html: 2 picture opener(s) (data-gallery) but no <script defer src="/assets/gallery.js?v=N">
### site/inline-viewer-back rc=1
mutation (website/alkalmazasok.html): '</body>' -> '<script>\n /**\n * Screenshot Gallery / Lightbox functionality\n */\n </script>\n'
FAIL: alkalmazasok.html: an inline copy of the picture viewer — it lives only in assets/gallery.js
@@ -0,0 +1,20 @@
Read-only copy of the running hub's database (hub.db + -wal + -shm via kubectl exec cat), queried locally, 2026-10-08 ~11:15 UTC.
Columns printed only: ids, language, times, event types — no secret column.
customer_configs (the household's stored language): [('demo-hp', 'hu', '2026-10-07 16:50:04')]
reports.language from demo-hp's controller since 10:00 UTC (12:00 CEST):
('2026-10-08 10:05:20', 'hu')
('2026-10-08 10:20:18', 'hu')
('2026-10-08 10:35:18', 'hu')
('2026-10-08 10:37:34', 'hu')
('2026-10-08 10:37:50', 'hu')
('2026-10-08 10:38:16', 'en')
('2026-10-08 10:38:45', 'hu')
('2026-10-08 10:39:47', 'hu')
('2026-10-08 10:40:03', 'hu')
('2026-10-08 10:50:18', 'hu')
('2026-10-08 11:05:18', 'hu')
notification_log rows since 10:00 UTC, any customer: 0
positive control — the newest notification_log rows (the query reads the table): [(1181, 'demo-felhom', 'kernel_notice', '2026-10-08 07:00:40'), (1180, 'Tester-2', 'expected_backup_missed', '2026-10-08 03:00:01'), (1179, 'Tester-2', 'expected_dbdump_missed', '2026-10-08 03:00:00')]
+2 -1
View File
@@ -191,7 +191,7 @@ stopping line that lies.
| **R-331** | Storage & devices | P4 | **Disk health Phase 3 — growth-rate detection, and retiring the static 64.** The v0.215.0 count backstop (64 unreadable sectors → Hiba) is **a judgement from ONE drive**: the observed benign excursion peaked at 16 and cleared inside an hour, and the terminal run passed 64 at 13 Aug 11:28 and never came back. It is deliberately a backstop BEHIND the sustain rule, not the primary signal, but it is still a magic number tuned on a single sample and it will be wrong for some drive. With Phase 2's history the box can ask the question that actually matters — *is this count climbing, and how fast* — which distinguishes a drive with eight stable aging sectors from one adding forty a day, something no static threshold can do. Revisit 64 when that exists | **READY (M) — NEW 2026-08-14** | R-330 | Growth-rate rule over persisted samples; re-derive or delete the static 64 | CC |
| **R-352** | Storage & devices | P4 | **Four screens state something untrue about where an app's data goes, and the configured default is consulted by nothing that places data.** Measured on `demo-hp` 2026-08-21. **(1)** **40 of 53** catalogue templates declare no data path (`grep -rl 'env_var: HDD_PATH' --include='.felhom.yml'` → 13; total 53); those apps get **no storage field and no default** — their data lands in a named Docker volume on the system drive. **(2)** `GetDefaultStoragePath()` has exactly **three** non-test callers — the metrics collector (`cmd/controller/main.go:410`), the dashboard SystemInfo panel (`web/server.go:733`) and `.fab` import landing (`handler_export_upload.go:154`). **The deploy route never reads it.** Its field comment `// new apps use this by default` (`internal/settings/settings.go:453`) has never been true — an invariant with no test pinning it. **(3)** The first-tier backup follows the data onto the same disk (`backup/backup.go:324-334` → `systemDataPath`), so data and nearest copy share one device for a customer doing nothing wrong — the posture Tier 2 refuses outright at `tier2.go:329`. **(4)** „1 alkalmazás használja" on the Drives page counts only `Env["HDD_PATH"] == path` (`web/handlers.go:2118`), so it can never include the 40-class; it truthfully means *„1 of the apps that CAN use a drive does"*. | **NARROWED** — **PARTLY CLOSED 2026-08-21** — visibility shipped; **placement OPEN** | — | **Shipped tonight (visibility only, no placement change, nothing migrated):** the deploy page now states where the app's data will live before the button is pressed, naming the system drive for the 40-class and the selected drive for the 13. **⚠ RE-FRAMED 2026-08-22 — THE FOUR MEASUREMENTS STAND; TWO OF THE CONCLUSIONS DRAWN FROM THEM DO NOT.** (1) is a measurement and is correct, but "those apps get no storage field and no default" is not a deprivation: the architecture places **hot** data (DB/config/cache) on fast storage inside the guest and states that placement is **ENFORCED** (`documentation/architecture/01-topology-and-trust.md:150-152`). The 40 are all-hot apps; the 13 are the ones with **bulk** content, which belongs on an attached drive. There is no choice being denied. (3) **overstated one risk and understated a distinction.** Since R-165 the guest carries a small OS rootfs plus **ONE** data volume at `/var/lib/felhom`; `/var/lib/docker` and `/mnt/sys_drive` are two **binds of that same volume** (`felhom-agent/configs/build-golden.sh:29-40, 99`) — the `mp0`/`mp1` split assumed here was retired 2026-08-03. **Real risk:** a physical-disk failure loses the data and its first-tier copy together — which is what the off-site and whole-machine tiers exist for, and which is equally true of a drive-resident app whose unit sits beside its data by design. **Overstated risk:** a full data volume stopping the operating system — the OS rootfs is a separate volume and the capture floor refuses per app before exhaustion (`00-capability-map.md:94`), watched working 2026-08-21 with the volume at 99% and all 15 containers healthy. **The comparison to Tier 2's same-disk refusal (`tier2.go:329`) is withdrawn:** Tier 2 refuses a SECOND copy on the same disk; Tier 1's unit is meant to sit beside the data. **(2) and (4) are untouched and remain correct** — (2) is now filed on its own as **R-368** with its scope measured, and (4) needs no ruling: the count is honest and only easy to misread. **The specification for the rest is filed at `documentation/backlog/SPEC-app-data-placement-2026-08-21.md`** (corrected 2026-08-22, framing marked inline, measurements kept) and lists the five points a ruling must settle (compose-template vs controller, existing deployments, when the SSD is legitimately right, `IsDefault` must become true or go away *with a test*, and the Drives-page count). **An earlier recommendation to refuse deployment until a drive is registered was WITHDRAWN** — it assumed the customer had failed to choose; they had no choice to make. | **Viktor rules**, CC executes |
## Security & access — 14 rows (P2 1, P3 11, P4 2)
## Security & access — 15 rows (P2 1, P3 12, P4 2)
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|---|---|---|---|---|---|---|---|
@@ -207,6 +207,7 @@ stopping line that lies.
| **R-782** | Security & access | P3 | **[P3-LOW] Two side observations of the R-753 sweep, inferred, not measured:** glance's seeded `glance.yml` has no `auth:` block (the dashboard is public to anyone with the address), and homepage's `/api/*` refuses a Host not in `HOMEPAGE_ALLOWED_HOSTS`, which the template does not set (widgets may 400). **Needs:** measure both on 9202; glance: decide whether a public link dashboard is intended (the setup gate does not cover it after setup). | **READY — rank P3-LOW; owner: CC (catalog)** **2026-10-06 night: homepage fixed on catalog branch `night-held-2026-10-06`** (`093e5ed`): `HOMEPAGE_ALLOWED_HOSTS=${SUBDOMAIN}.${DOMAIN}`; bench: `/api/services` 400 → 200. Glance measured: public (`GET /` 200 with no login, no auth block, `/login` 404) — whether it gets a login is the operator's question; the row stays open for it (`cat/R-782-red.txt`). | — | — | CC |
| **R-831** | Security & access | P3 | **The Hetzner storage API token (`HETZNER_TOKEN`, the storage project's token in `Secret/storagebox`) was printed into the 2026-10-03 session transcript** — CC read the gitignored `manifests/storagebox.secret.yaml` and its redaction pattern missed the quoted value. It can create, reset and delete Storage Box sub-accounts. Not rotated by the operator's choice (decision 73). **Rotation, whenever chosen (3 steps):** create a new token in the storage project in the Hetzner console → patch `Secret/storagebox` key `HETZNER_TOKEN` in `felhom-system` and `kubectl rollout restart deployment/hub` → delete the old token in the console. Rule for sessions: never print a file that holds secrets — read the one field needed. | **WAITING-ON-OPERATOR — rotation is his call** **Not rotated by the operator's rulings (2026-10-04 „keep using the current one"; 2026-10-05 option B) — restated 2026-10-05 18:23; the steps stay here.** | — | rotate when chosen | operator |
| **R-870** | Security & access | P3 | **Tester 1's two Cloudflare credentials — the zone API token (`infrastructure.cf_api_token`) and the tunnel token (`infrastructure.cf_tunnel_token`) of the hub's `customer_configs` row `tester-1` — were printed into the 2026-10-04 night session's transcript** (not into any file): a read-only query selected `substr(config_json,1,400)`, and both values sit in the first 400 characters. Tester 1 is CC's disposable test customer (`enkicsifelhom.hu`). **Not rotated, by the operator's ruling of 2026-10-05 06:49 (option B).** **Rotation, whenever chosen (3 steps):** in the Cloudflare dashboard create a new API token for the `enkicsifelhom.hu` zone with the same permissions and refresh the Tester 1 tunnel's token (Zero Trust → Networks → Tunnels → the tunnel → refresh token) → hub → Configs → `tester-1` → Edit → the two Cloudflare fields → Save, then confirm on the box that cloudflared reconnected (`docker ps` health `healthy`) → delete the old API token. Rule for sessions (as R-831): never select a whole config row — name the fields, and never `config_json` without `json_extract` of a non-secret field. | **WAITING-ON-OPERATOR — rotation is his call (ruled: not now)** **Not rotated by the operator's rulings (2026-10-04 „keep using the current one"; 2026-10-05 option B) — restated 2026-10-05 18:23; the steps stay here.** | — | rotate when chosen | operator |
| **R-908** | Security & access | P3 | **An old Resend API key is still in the history of the `homelab-manifests` repository; it was replaced on 2026-06-29, but whether it is also revoked at Resend is unknown.** FOUND 2026-10-08 by the contact-mailer source search (`audits/mailer-source-2026-10-08/SEARCH.md`, „A side finding"): commit c9648cd (2026-02-05, „added mailer pod") put a key literal in the old `felhom-system/contact-mailer.yaml` comment; the file was deleted in ee93b50 but the history keeps it. Compared by hash only, never printed: it is NOT today's key (`Secret/resend-api`, rotated 2026-06-29, felhom.eu feea0606). If the old key still works at Resend, anyone with read access to that repository can send mail as felhom.eu. | **OPEN — owner: operator** | — | In the Resend console, check that the old key is revoked (revoke it if not); rewriting the repository's history is NOT needed once it is revoked | operator |
| **R-525** | Security & access | P4 | **[P3-LOW] FileBrowser has its own login; putting it behind the dashboard session (traefik forwardAuth or Quantum proxy auth) is a new mechanism nobody has measured.** Filed 2026-09-15 by the P1-fixes task (B.5). R-513 closed the default-password hole with a generated password; a household still has two logins. **What it needs:** a spike on a scratch guest — forwardAuth to the controller session, and what FileBrowser Quantum does with a trusted header. | **READY — rank P3-LOW; owner: CC (spike)** **Re-ranked 2026-10-03: P3->P4: comfort feature needing a new unmeasured mechanism; the default password hole is closed.** | — | — | CC |
| **R-779** | Security & access | P4 | **[P3-LOW] Part A's "two outside addresses seen as two" is proven through the simulated tunnel only; on the REAL tunnel the second outside address (ep0, one request allowed) was refused by Cloudflare's edge with 403 and never reached the box.** Measured 2026-10-01 19:51 UTC (`audits/visitors-2026-10-01/A/L2-demo-hp-real-tunnel.txt`): no log line on demo-hp; demo-hp's box has no geo restriction in its settings, so a Cloudflare ZONE rule (country or bot, not read) refused a German datacenter address. DooPlex's own address on the real tunnel was seen as itself. **Needs:** one sign-in from a second Hungarian address (the operator's phone off wifi) while DooPlex is locked out — 2 minutes; and say which Cloudflare rule refused ep0. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator (a phone), CC reads the logs** **Re-ranked 2026-10-03: P3→P4: a proof gap on the real tunnel; operator-only follow-up.** | — | — | CC + operator |
| **R-904** | Security & access | P4 | **Cloudflare can read every household's app traffic; replacing it with our own relay is a later item.** Facts (reviewer discussion 2026-10-08; `01`): app traffic and the dashboard reach the box through the Cloudflare Tunnel (`01` §5 trust table, rows end-user ↔ apps and customer ↔ controller UI; §7), and the tunnel's public end is Cloudflare's edge, where TLS ends — so Cloudflare can technically read that traffic (the FAQ says so since 2026-10-08, R-900; „TLS ends at the edge" is not written in `01` — add it there). What Cloudflare gives today, free: inbound reach with no router setup, the CGNAT answer (`01` §4, §7); certificates (`01` §7, the free tier covers one level below a zone); the geo-WAF the hub enforces (`01` §5 last row, §7); flood protection (not in `01`). The alternative named: our own EU relay over WireGuard with TLS passthrough by SNI, certificates on the box, the geo-block on the relay. Its costs: one more machine the operator keeps up, and a single point of reach for every box; weaker flood protection; about a week of work after a spike. Operator ruling 2026-10-08 09:07 (`09` §3 decision 184): a later item. | **DEFERRED — after the first customers (operator ruling 2026-10-08 09:07)** | — | A spike after the first customers (the relay's reach, cost and flood behaviour, measured) | operator |
+7
View File
@@ -1,3 +1,10 @@
## gates — site gate 20: the one picture viewer (2026-10-08)
- Every `data-gallery` opener must be an `<a href>` to an existing file under `website/assets/`; a page with openers must
load `/assets/gallery.js?v=N`, and a page that loads it must have openers; „Screenshot Gallery / Lightbox" (the old inline
viewer) may appear on no page. Four decoys: `site/viewer-opener-without-href`, `viewer-opener-missing-file`,
`viewer-openers-no-script`, `viewer-inline-copy-back`, each with its failure line (`must=`).
## gates — site gate 19: dashboard pictures in the page's own language (2026-10-08)
- `site_gates.py` gate 19: every `/assets/dashboard-*-(hu|en).webp` on a page must match the page's language set.
+30 -1
View File
@@ -29,6 +29,8 @@ Gates (all must pass; non-zero exit on any failure):
17. faq-ld — each FAQ page's FAQPage JSON-LD carries exactly its visible questions and answers
18. tail — nothing after </html> (a stray file-dump summary sat visible below technologiak.html)
19. dash-lang — a page shows dashboard pictures only in its own language (`dashboard-*-hu.webp` / `-en.webp`)
20. viewer — data-gallery openers are <a href> to existing assets; gallery.js (with ?v=) exactly where openers are;
no inline viewer copy
"""
import html as _html, io, json, os, re, sys, unicodedata
@@ -452,8 +454,35 @@ for p, s in pages.items():
fail("%s: a %s dashboard picture (%s) on a %s page — use the page's own language" % (p, m.group(1), m.group(0), want))
print(" dashboard pictures: %d references, each in its page's language" % _dash_n)
# gate 20: the one picture viewer (2026-10-08). A set is declared in the page: every opener is an <a href> to a file
# that exists under website/assets/, carrying data-gallery. A page with openers loads assets/gallery.js with a ?v=; a
# page that loads it has openers; the old inline viewer script appears on no page.
_OPENER_RE = re.compile(r"<(\w+)\b[^>]*\bdata-gallery=\"[^\"]*\"[^>]*>")
_GJS_RE = re.compile(r'<script defer src="/assets/gallery\.js(\?v=[0-9]+)?"></script>')
_open_n = 0
for p, s in pages.items():
openers = [m.group(0) for m in _OPENER_RE.finditer(s)]
_open_n += len(openers)
js = _GJS_RE.findall(s)
if openers and not js:
fail("%s: %d picture opener(s) (data-gallery) but no <script defer src=\"/assets/gallery.js?v=N\">" % (p, len(openers)))
if js and not js[0]:
fail("%s: assets/gallery.js loaded without ?v=" % p)
if js and not openers:
fail("%s: loads assets/gallery.js but declares no data-gallery picture" % p)
for o in openers:
m = re.match(r'<a\b[^>]*\bhref="(/assets/[^"]+)"', o)
if not m:
fail("%s: a data-gallery opener that is not an <a href=\"/assets/…\">: %s" % (p, o[:120]))
continue
if not os.path.exists(os.path.join(W, m.group(1).lstrip("/"))):
fail("%s: a data-gallery opener points at a missing file: %s" % (p, m.group(1)))
if "Screenshot Gallery / Lightbox" in s:
fail("%s: an inline copy of the picture viewer — it lives only in assets/gallery.js" % p)
print(" picture viewer: %d openers, every one a link to an existing file" % _open_n)
if fails:
print("\nSITE GATES FAILED: %d problem(s)" % len(fails))
sys.exit(1)
print("site gates OK — BOM, emoji=0, nav/footer per language, analytics, no CDN, no legacy tokens, no <style>, "
"cache-busted assets, twins + hreflang + globe, lang, same apps, no Hungarian in English, FAQ JSON-LD, clean tail, dashboard pictures per language")
"cache-busted assets, twins + hreflang + globe, lang, same apps, no Hungarian in English, FAQ JSON-LD, clean tail, dashboard pictures per language, one picture viewer")
+18 -1
View File
@@ -82,7 +82,7 @@ COVERS = {
"switch at the wrong twin, lang=\"hu\" on an English page, an app missing from one apps page, "
"ASCII-only Hungarian in English text and in a script message, a 'please', an English "
"retrieval promise the Hungarian does not make, a FAQ JSON-LD drifting from the visible "
"answer, text after </html>, and a Hungarian dashboard picture on an English page — each must convict WITH its own failure line"),
"answer, text after </html>, a Hungarian dashboard picture on an English page, and four picture-viewer faults (an opener without href, an opener to a missing file, openers with no gallery.js, the inline viewer put back) — each must convict WITH its own failure line"),
"script-tests": ("R-885: FIVE cases in scripts/test_script_tests_gate.py, run from here: a suite that PRINTS "
"OK and exits 1 (label without fact), a failing suite three levels deep (scope is a walk), "
"an empty scripts/ tree (checked nothing), the genuine article (must pass), the nested mark"),
@@ -544,6 +544,23 @@ decoy("site/leftover-text-switch", "site_gates.py",
decoy("site/dashboard-picture-wrong-language", "site_gates.py",
replace_in(_EN("index.html"), 'src="/assets/dashboard-start-en.webp"', 'src="/assets/dashboard-start-hu.webp"'),
must="en/index.html: a hu dashboard picture (/assets/dashboard-start-hu.webp) on a en page")
# the one picture viewer (2026-10-08): an opener without href, an opener to a missing file, openers with no script,
# and the old inline viewer put back
decoy("site/viewer-opener-without-href", "site_gates.py",
replace_in(_EN("apps.html"), '<a href="/assets/immich-screenshot-1.webp" data-gallery="immich" class="app-shot-link">',
'<a data-gallery="immich" class="app-shot-link">'),
must="en/apps.html: a data-gallery opener that is not an <a href=")
decoy("site/viewer-opener-missing-file", "site_gates.py",
replace_in(os.path.join(_WEB, "index.html"), '<a href="/assets/dashboard-apps-hu.webp" data-gallery="dashboard">',
'<a href="/assets/dashboard-apps-hu-old.webp" data-gallery="dashboard">'),
must="index.html: a data-gallery opener points at a missing file")
decoy("site/viewer-openers-no-script", "site_gates.py",
replace_in(_EN("technology.html"), ' <script defer src="/assets/gallery.js?v=1"></script>\n', ""),
must="en/technology.html: 2 picture opener(s) (data-gallery) but no")
decoy("site/viewer-inline-copy-back", "site_gates.py",
replace_in(os.path.join(_WEB, "alkalmazasok.html"), "</body>",
" <script>\n /**\n * Screenshot Gallery / Lightbox functionality\n */\n </script>\n</body>"),
must="alkalmazasok.html: an inline copy of the picture viewer")
decoy("site/lang-attr", "site_gates.py",
replace_in(_EN("backups.html"), '<html lang="en">', '<html lang="hu">'),
must="the English set needs lang='en'")
+1 -1
View File
@@ -6,7 +6,7 @@
<title>Az oldal nem található | Felhom.eu</title>
<meta name="robots" content="noindex, follow">
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+14
View File
@@ -1,3 +1,17 @@
## 2026-10-08 (late afternoon) — one picture viewer for the whole site
- **`assets/gallery.js`** — the viewer that lived twice inline on the two apps pages is one shared file now (`defer`,
`?v=1`), its markup built by the script. The dashboard pictures (home and technology, both languages) open in it too,
as one set: Launcher → Apps → an app → Backups.
- **A set is declared, not guessed:** every picture is a real `<a href="/assets/…webp" data-gallery="<set>">`; an app
card's further pictures are hidden links in the card. The old probing for `-screenshot-N.webp` files is gone (no
request for a picture that is not in the page). JavaScript off: the link opens the picture, as before.
- **New: a click or tap on the big picture closes the viewer** (the close button, Esc and a click beside it still do);
a swipe changes the picture and does not close. Labels follow `<html lang>`; focus goes to the viewer and back to the
clicked picture; the page does not scroll behind it.
- `site.css`: the `.lightbox-…` rules are no longer scoped to the apps page; `?v=4` → `?v=5` on all sixteen pages.
- Gate 20 (`scripts/CHANGELOG.md`).
## 2026-10-08 (afternoon) — the dashboard, shown
- **A new section after „Mit tud a doboz ma?" / „What the box does today"**: „Így néz ki a vezérlőpult" / „What the
+185 -341
View File
@@ -43,8 +43,9 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<script defer src="/assets/gallery.js?v=1"></script>
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
</head>
<body class="page-alkalmazasok">
@@ -111,7 +112,9 @@
<div class="app-card-body">
<p class="app-description">Teljes értékű felhőszolgáltatás a saját szervereden. Fájlok szinkronizálása, naptár, kontaktok, dokumentumszerkesztés, és rengeteg bővítmény.</p>
<div class="app-features"><span class="app-feature">Fájl szinkron</span><span class="app-feature">Naptár</span><span class="app-feature">Dokumentumok</span><span class="app-feature">Mobil app</span></div>
<img src="/assets/nextcloud-screenshot-1.webp" alt="Nextcloud screenshot" class="app-screenshot">
<a href="/assets/nextcloud-screenshot-1.webp" data-gallery="nextcloud" class="app-shot-link"><img src="/assets/nextcloud-screenshot-1.webp" alt="Nextcloud screenshot" class="app-screenshot"></a>
<a href="/assets/nextcloud-screenshot-2.webp" data-gallery="nextcloud" data-alt="Nextcloud screenshot 2" hidden></a>
<a href="/assets/nextcloud-screenshot-3.webp" data-gallery="nextcloud" data-alt="Nextcloud screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/nextcloud/server" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -127,7 +130,8 @@
<div class="app-card-body">
<p class="app-description">Könnyű és gyors webes fájlkezelő, minden Felhom dobozba beépítve. Böngészd, töltsd fel és oszd meg a fájljaidat bárhonnan, modern felületen keresztül.</p>
<div class="app-features"><span class="app-feature">Drag & drop</span><span class="app-feature">Megosztás</span><span class="app-feature">Előnézet</span><span class="app-feature">Keresés</span></div>
<img src="/assets/filebrowser-screenshot-1.webp" alt="FileBrowser screenshot" class="app-screenshot">
<a href="/assets/filebrowser-screenshot-1.webp" data-gallery="filebrowser" class="app-shot-link"><img src="/assets/filebrowser-screenshot-1.webp" alt="FileBrowser screenshot" class="app-screenshot"></a>
<a href="/assets/filebrowser-screenshot-2.webp" data-gallery="filebrowser" data-alt="FileBrowser screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/filebrowser/filebrowser" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -143,7 +147,7 @@
<div class="app-card-body">
<p class="app-description">Könnyűsúlyú fájlmegosztó szerver lejárati idővel és letöltési limittel. Tökéletes nagy fájlok gyors és biztonságos megosztására.</p>
<div class="app-features"><span class="app-feature">Lejárati idő</span><span class="app-feature">Letöltési limit</span><span class="app-feature">Jelszóvédelem</span></div>
<img src="/assets/gokapi-screenshot-1.webp" alt="Gokapi screenshot" class="app-screenshot">
<a href="/assets/gokapi-screenshot-1.webp" data-gallery="gokapi" class="app-shot-link"><img src="/assets/gokapi-screenshot-1.webp" alt="Gokapi screenshot" class="app-screenshot"></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Forceu/Gokapi" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -159,7 +163,10 @@
<div class="app-card-body">
<p class="app-description">Modern, funkciógazdag fájl- és képmegosztó. Tökéletes screenshot megosztásra, URL rövidítésre és szövegtárolásra.</p>
<div class="app-features"><span class="app-feature">Screenshot</span><span class="app-feature">URL rövidítő</span><span class="app-feature">Galéria</span><span class="app-feature">API</span></div>
<img src="/assets/zipline-screenshot-1.webp" alt="Zipline screenshot" class="app-screenshot">
<a href="/assets/zipline-screenshot-1.webp" data-gallery="zipline" class="app-shot-link"><img src="/assets/zipline-screenshot-1.webp" alt="Zipline screenshot" class="app-screenshot"></a>
<a href="/assets/zipline-screenshot-2.webp" data-gallery="zipline" data-alt="Zipline screenshot 2" hidden></a>
<a href="/assets/zipline-screenshot-3.webp" data-gallery="zipline" data-alt="Zipline screenshot 3" hidden></a>
<a href="/assets/zipline-screenshot-4.webp" data-gallery="zipline" data-alt="Zipline screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/diced/zipline" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -175,7 +182,15 @@
<div class="app-card-body">
<p class="app-description">Teljes értékű irodai programcsomag a böngészőben. Dokumentumok, táblázatok és prezentációk szerkesztése – kiváló Microsoft Office kompatibilitással.</p>
<div class="app-features"><span class="app-feature">Dokumentumok</span><span class="app-feature">Táblázatok</span><span class="app-feature">Prezentációk</span><span class="app-feature">Együttműködés</span></div>
<img src="/assets/onlyoffice-screenshot-1.webp" alt="OnlyOffice screenshot" class="app-screenshot">
<a href="/assets/onlyoffice-screenshot-1.webp" data-gallery="onlyoffice" class="app-shot-link"><img src="/assets/onlyoffice-screenshot-1.webp" alt="OnlyOffice screenshot" class="app-screenshot"></a>
<a href="/assets/onlyoffice-screenshot-2.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 2" hidden></a>
<a href="/assets/onlyoffice-screenshot-3.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 3" hidden></a>
<a href="/assets/onlyoffice-screenshot-4.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 4" hidden></a>
<a href="/assets/onlyoffice-screenshot-5.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 5" hidden></a>
<a href="/assets/onlyoffice-screenshot-6.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 6" hidden></a>
<a href="/assets/onlyoffice-screenshot-7.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 7" hidden></a>
<a href="/assets/onlyoffice-screenshot-8.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 8" hidden></a>
<a href="/assets/onlyoffice-screenshot-9.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 9" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/ONLYOFFICE/DocumentServer" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -191,7 +206,8 @@
<div class="app-card-body">
<p class="app-description">Adatvédelem-központú PDF eszköztár, 70+ funkcióval. Összefűzés, szétválasztás, konvertálás, tömörítés, OCR, titkosítás, aláírás – minden a böngészőben, szerver nélkül.</p>
<div class="app-features"><span class="app-feature">70+ eszköz</span><span class="app-feature">Kliens-oldali</span><span class="app-feature">OCR</span><span class="app-feature">Konvertálás</span></div>
<img src="/assets/bentopdf-screenshot-1.webp" alt="BentoPDF screenshot" class="app-screenshot">
<a href="/assets/bentopdf-screenshot-1.webp" data-gallery="bentopdf" class="app-shot-link"><img src="/assets/bentopdf-screenshot-1.webp" alt="BentoPDF screenshot" class="app-screenshot"></a>
<a href="/assets/bentopdf-screenshot-2.webp" data-gallery="bentopdf" data-alt="BentoPDF screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/alam00000/bentopdf" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -207,7 +223,9 @@
<div class="app-card-body">
<p class="app-description">Letisztult, modern dokumentum archiváló. Automatikus címkézés, email import, OCR szövegfelismerés – a digitális irattár egyszerűen, szépen.</p>
<div class="app-features"><span class="app-feature">Auto címkék</span><span class="app-feature">Email import</span><span class="app-feature">OCR</span><span class="app-feature">Modern UI</span></div>
<img src="/assets/papra-screenshot-1.webp" alt="Papra screenshot" class="app-screenshot">
<a href="/assets/papra-screenshot-1.webp" data-gallery="papra" class="app-shot-link"><img src="/assets/papra-screenshot-1.webp" alt="Papra screenshot" class="app-screenshot"></a>
<a href="/assets/papra-screenshot-2.webp" data-gallery="papra" data-alt="Papra screenshot 2" hidden></a>
<a href="/assets/papra-screenshot-3.webp" data-gallery="papra" data-alt="Papra screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/papra-hq/papra" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -236,7 +254,10 @@
<div class="app-card-body">
<p class="app-description">Gyors és modern fotó/videó mentési megoldás. Automatikus feltöltés telefonról, arc- és tárgyfelismerés, megosztás és emlékek.</p>
<div class="app-features"><span class="app-feature">Auto backup</span><span class="app-feature">Arcfelismerés</span><span class="app-feature">Térkép</span><span class="app-feature">Mobil app</span></div>
<img src="/assets/immich-screenshot-1.webp" alt="Immich screenshot" class="app-screenshot">
<a href="/assets/immich-screenshot-1.webp" data-gallery="immich" class="app-shot-link"><img src="/assets/immich-screenshot-1.webp" alt="Immich screenshot" class="app-screenshot"></a>
<a href="/assets/immich-screenshot-2.webp" data-gallery="immich" data-alt="Immich screenshot 2" hidden></a>
<a href="/assets/immich-screenshot-3.webp" data-gallery="immich" data-alt="Immich screenshot 3" hidden></a>
<a href="/assets/immich-screenshot-4.webp" data-gallery="immich" data-alt="Immich screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/immich-app/immich" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -252,7 +273,8 @@
<div class="app-card-body">
<p class="app-description">Ingyenes és nyílt forráskódú média szerver. Streamelj filmeket, sorozatokat és zenét bárhonnan, bármilyen eszközre.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Transzkódolás</span><span class="app-feature">Mobil app</span><span class="app-feature">TV app</span></div>
<img src="/assets/jellyfin-screenshot-1.webp" alt="Jellyfin screenshot" class="app-screenshot">
<a href="/assets/jellyfin-screenshot-1.webp" data-gallery="jellyfin" class="app-shot-link"><img src="/assets/jellyfin-screenshot-1.webp" alt="Jellyfin screenshot" class="app-screenshot"></a>
<a href="/assets/jellyfin-screenshot-2.webp" data-gallery="jellyfin" data-alt="Jellyfin screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/jellyfin/jellyfin" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -268,7 +290,9 @@
<div class="app-card-body">
<p class="app-description">Népszerű média szerver csiszolt felülettel. Filmek, sorozatok, zene és fotók egy helyen, kiváló alkalmazás támogatással.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Plex Pass</span><span class="app-feature">Intro skip</span><span class="app-feature">Watch Together</span></div>
<img src="/assets/plex-screenshot-1.webp" alt="Plex screenshot" class="app-screenshot">
<a href="/assets/plex-screenshot-1.webp" data-gallery="plex" class="app-shot-link"><img src="/assets/plex-screenshot-1.webp" alt="Plex screenshot" class="app-screenshot"></a>
<a href="/assets/plex-screenshot-2.webp" data-gallery="plex" data-alt="Plex screenshot 2" hidden></a>
<a href="/assets/plex-screenshot-3.webp" data-gallery="plex" data-alt="Plex screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://www.plex.tv" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Weboldal</a>
@@ -284,7 +308,8 @@
<div class="app-card-body">
<p class="app-description">Személyes média szerver élő TV és DVR támogatással. Szervezett könyvtár, távoli elérés és szinkronizálás offline lejátszáshoz.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Élő TV</span><span class="app-feature">DVR</span><span class="app-feature">Szinkron</span></div>
<img src="/assets/emby-screenshot-1.webp" alt="Emby screenshot" class="app-screenshot">
<a href="/assets/emby-screenshot-1.webp" data-gallery="emby" class="app-shot-link"><img src="/assets/emby-screenshot-1.webp" alt="Emby screenshot" class="app-screenshot"></a>
<a href="/assets/emby-screenshot-2.webp" data-gallery="emby" data-alt="Emby screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://emby.media" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Weboldal</a>
@@ -300,7 +325,8 @@
<div class="app-card-body">
<p class="app-description">Könnyű és modern zeneszerver. Streameld a saját zenegyűjteményedet bárhonnan – Subsonic kompatibilis, rengeteg mobil alkalmazással.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Subsonic API</span><span class="app-feature">Mobil appok</span><span class="app-feature">Lejátszási listák</span></div>
<img src="/assets/navidrome-screenshot-1.webp" alt="Navidrome screenshot" class="app-screenshot">
<a href="/assets/navidrome-screenshot-1.webp" data-gallery="navidrome" class="app-shot-link"><img src="/assets/navidrome-screenshot-1.webp" alt="Navidrome screenshot" class="app-screenshot"></a>
<a href="/assets/navidrome-screenshot-2.webp" data-gallery="navidrome" data-alt="Navidrome screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/navidrome/navidrome" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -316,7 +342,10 @@
<div class="app-card-body">
<p class="app-description">Hangoskönyv és podcast kezelő szerver. Automatikus metaadat letöltés, folytatás ahol abbahagytad, és dedikált mobil alkalmazások.</p>
<div class="app-features"><span class="app-feature">Hangoskönyvek</span><span class="app-feature">Podcastok</span><span class="app-feature">Szinkron</span><span class="app-feature">Mobil app</span></div>
<img src="/assets/audiobookshelf-screenshot-1.webp" alt="Audiobookshelf screenshot" class="app-screenshot">
<a href="/assets/audiobookshelf-screenshot-1.webp" data-gallery="audiobookshelf" class="app-shot-link"><img src="/assets/audiobookshelf-screenshot-1.webp" alt="Audiobookshelf screenshot" class="app-screenshot"></a>
<a href="/assets/audiobookshelf-screenshot-2.webp" data-gallery="audiobookshelf" data-alt="Audiobookshelf screenshot 2" hidden></a>
<a href="/assets/audiobookshelf-screenshot-3.webp" data-gallery="audiobookshelf" data-alt="Audiobookshelf screenshot 3" hidden></a>
<a href="/assets/audiobookshelf-screenshot-4.webp" data-gallery="audiobookshelf" data-alt="Audiobookshelf screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/advplyr/audiobookshelf" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -332,7 +361,9 @@
<div class="app-card-body">
<p class="app-description">Egy videó vagy lejátszási lista letöltése a linkjéből, videóként vagy csak hangként. A letöltések a meghajtódra kerülnek, a fájlböngészőben és a médialejátszódban is látod őket. Csak a családtagjaid érik el.</p>
<div class="app-features"><span class="app-feature">Videó és hang</span><span class="app-feature">Lejátszási listák</span><span class="app-feature">Saját meghajtóra</span><span class="app-feature">Csak a családnak</span></div>
<img src="/assets/metube-screenshot-1.webp" alt="MeTube screenshot" class="app-screenshot">
<a href="/assets/metube-screenshot-1.webp" data-gallery="metube" class="app-shot-link"><img src="/assets/metube-screenshot-1.webp" alt="MeTube screenshot" class="app-screenshot"></a>
<a href="/assets/metube-screenshot-2.webp" data-gallery="metube" data-alt="MeTube screenshot 2" hidden></a>
<a href="/assets/metube-screenshot-3.webp" data-gallery="metube" data-alt="MeTube screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/alexta69/metube" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -348,7 +379,8 @@
<div class="app-card-body">
<p class="app-description">Webes felület a Calibre könyvtáradhoz. Böngészd, olvasd és töltsd le az e-könyveidet bárhonnan, Kindle támogatással.</p>
<div class="app-features"><span class="app-feature">E-könyvek</span><span class="app-feature">Kindle küldés</span><span class="app-feature">OPDS</span><span class="app-feature">Olvasó</span></div>
<img src="/assets/calibre-web-screenshot-1.webp" alt="Calibre-Web Automated screenshot" class="app-screenshot">
<a href="/assets/calibre-web-screenshot-1.webp" data-gallery="calibre-web" class="app-shot-link"><img src="/assets/calibre-web-screenshot-1.webp" alt="Calibre-Web Automated screenshot" class="app-screenshot"></a>
<a href="/assets/calibre-web-screenshot-2.webp" data-gallery="calibre-web" data-alt="Calibre-Web Automated screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/crocodilestick/Calibre-Web-Automated" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -364,7 +396,7 @@
<div class="app-card-body">
<p class="app-description">Képregények, mangák és magazinok kezelése és olvasása. Modern webes olvasó, OPDS támogatás, és népszerű mobil alkalmazások.</p>
<div class="app-features"><span class="app-feature">Webes olvasó</span><span class="app-feature">OPDS</span><span class="app-feature">Metaadatok</span><span class="app-feature">Tachiyomi</span></div>
<img src="/assets/komga-screenshot-1.webp" alt="Komga screenshot" class="app-screenshot">
<a href="/assets/komga-screenshot-1.webp" data-gallery="komga" class="app-shot-link"><img src="/assets/komga-screenshot-1.webp" alt="Komga screenshot" class="app-screenshot"></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/gotson/komga" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -380,7 +412,9 @@
<div class="app-card-body">
<p class="app-description">E-könyvek és képregények rendezett könyvtárban, borítóval és adatokkal. Olvasás a böngészőben, a haladás mentésével; Kobo- és KOReader-szinkron, OPDS-katalógus az olvasóalkalmazásoknak. Csak a családtagjaid érik el, saját belépéssel.</p>
<div class="app-features"><span class="app-feature">Böngészős olvasó</span><span class="app-feature">Kobo szinkron</span><span class="app-feature">KOReader</span><span class="app-feature">OPDS</span></div>
<img src="/assets/grimmory-screenshot-1.webp" alt="Grimmory screenshot" class="app-screenshot">
<a href="/assets/grimmory-screenshot-1.webp" data-gallery="grimmory" class="app-shot-link"><img src="/assets/grimmory-screenshot-1.webp" alt="Grimmory screenshot" class="app-screenshot"></a>
<a href="/assets/grimmory-screenshot-2.webp" data-gallery="grimmory" data-alt="Grimmory screenshot 2" hidden></a>
<a href="/assets/grimmory-screenshot-3.webp" data-gallery="grimmory" data-alt="Grimmory screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/grimmory-tools/grimmory" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -396,7 +430,9 @@
<div class="app-card-body">
<p class="app-description">Automatikus sorozat letöltő és rendszerező. Kövesd a kedvenc sorozataidat, és az új epizódok automatikusan letöltődnek.</p>
<div class="app-features"><span class="app-feature">Auto letöltés</span><span class="app-feature">Naptár</span><span class="app-feature">Minőség kezelés</span><span class="app-feature">Integráció</span></div>
<img src="/assets/sonarr-screenshot-1.webp" alt="Sonarr screenshot" class="app-screenshot">
<a href="/assets/sonarr-screenshot-1.webp" data-gallery="sonarr" class="app-shot-link"><img src="/assets/sonarr-screenshot-1.webp" alt="Sonarr screenshot" class="app-screenshot"></a>
<a href="/assets/sonarr-screenshot-2.webp" data-gallery="sonarr" data-alt="Sonarr screenshot 2" hidden></a>
<a href="/assets/sonarr-screenshot-3.webp" data-gallery="sonarr" data-alt="Sonarr screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Sonarr/Sonarr" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -412,7 +448,8 @@
<div class="app-card-body">
<p class="app-description">Automatikus film letöltő és rendszerező. Készíts kívánságlistát, és a filmek automatikusan a könyvtáradba kerülnek.</p>
<div class="app-features"><span class="app-feature">Kívánságlista</span><span class="app-feature">Auto letöltés</span><span class="app-feature">Minőség kezelés</span><span class="app-feature">Integráció</span></div>
<img src="/assets/radarr-screenshot-1.webp" alt="Radarr screenshot" class="app-screenshot">
<a href="/assets/radarr-screenshot-1.webp" data-gallery="radarr" class="app-shot-link"><img src="/assets/radarr-screenshot-1.webp" alt="Radarr screenshot" class="app-screenshot"></a>
<a href="/assets/radarr-screenshot-2.webp" data-gallery="radarr" data-alt="Radarr screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Radarr/Radarr" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -428,7 +465,8 @@
<div class="app-card-body">
<p class="app-description">Filmek és sorozatok igénylése egyszerűen. A család/barátok kérhetnek tartalmakat, amiket automatikusan letölt a rendszer.</p>
<div class="app-features"><span class="app-feature">Kérés kezelés</span><span class="app-feature">Felhasználók</span><span class="app-feature">Értesítések</span><span class="app-feature">Integráció</span></div>
<img src="/assets/seerr-screenshot-1.webp" alt="Seerr screenshot" class="app-screenshot">
<a href="/assets/seerr-screenshot-1.webp" data-gallery="seerr" class="app-shot-link"><img src="/assets/seerr-screenshot-1.webp" alt="Seerr screenshot" class="app-screenshot"></a>
<a href="/assets/seerr-screenshot-2.webp" data-gallery="seerr" data-alt="Seerr screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Fallenbagel/jellyseerr" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -444,7 +482,8 @@
<div class="app-card-body">
<p class="app-description">Gyönyörű webes felület a retro játék ROM gyűjteményed kezeléséhez. Automatikus metaadat és borítókép letöltés, platform rendszerezés és böngészőből való lejátszás.</p>
<div class="app-features"><span class="app-feature">ROM kezelés</span><span class="app-feature">Metaadatok</span><span class="app-feature">EmulatorJS</span><span class="app-feature">IGDB</span></div>
<img src="/assets/romm-screenshot-1.webp" alt="RoMM screenshot" class="app-screenshot">
<a href="/assets/romm-screenshot-1.webp" data-gallery="romm" class="app-shot-link"><img src="/assets/romm-screenshot-1.webp" alt="RoMM screenshot" class="app-screenshot"></a>
<a href="/assets/romm-screenshot-2.webp" data-gallery="romm" data-alt="RoMM screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/rommapp/romm" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -460,7 +499,9 @@
<div class="app-card-body">
<p class="app-description">Modern webes Minecraft szerver menedzser. Több szerver kezelése egyetlen felületről, automatikus mentések, játékos statisztikák és teljes távoli hozzáférés.</p>
<div class="app-features"><span class="app-feature">Multi-szerver</span><span class="app-feature">Mentések</span><span class="app-feature">Konzol</span><span class="app-feature">Statisztikák</span></div>
<img src="/assets/crafty-screenshot-1.webp" alt="Crafty Controller screenshot" class="app-screenshot">
<a href="/assets/crafty-screenshot-1.webp" data-gallery="crafty" class="app-shot-link"><img src="/assets/crafty-screenshot-1.webp" alt="Crafty Controller screenshot" class="app-screenshot"></a>
<a href="/assets/crafty-screenshot-2.webp" data-gallery="crafty" data-alt="Crafty Controller screenshot 2" hidden></a>
<a href="/assets/crafty-screenshot-3.webp" data-gallery="crafty" data-alt="Crafty Controller screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://gitlab.com/crafty-controller/crafty-4" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -489,7 +530,12 @@
<div class="app-card-body">
<p class="app-description">A világ legnépszerűbb nyílt forráskódú okos otthon platformja. Több mint 3000 integráció, helyi vezérlés, automatizációk – felhő nélkül, teljes adatvédelemmel.</p>
<div class="app-features"><span class="app-feature">3000+ integráció</span><span class="app-feature">Automatizáció</span><span class="app-feature">Helyi vezérlés</span><span class="app-feature">Mobil app</span></div>
<img src="/assets/homeassistant-screenshot-1.webp" alt="Home Assistant screenshot" class="app-screenshot">
<a href="/assets/homeassistant-screenshot-1.webp" data-gallery="homeassistant" class="app-shot-link"><img src="/assets/homeassistant-screenshot-1.webp" alt="Home Assistant screenshot" class="app-screenshot"></a>
<a href="/assets/homeassistant-screenshot-2.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 2" hidden></a>
<a href="/assets/homeassistant-screenshot-3.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 3" hidden></a>
<a href="/assets/homeassistant-screenshot-4.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 4" hidden></a>
<a href="/assets/homeassistant-screenshot-5.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 5" hidden></a>
<a href="/assets/homeassistant-screenshot-6.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 6" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/home-assistant/core" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -505,7 +551,11 @@
<div class="app-card-body">
<p class="app-description">Vizuális workflow automatizálás Zapier/Make stílusban. Köss össze bármilyen szolgáltatást, készíts automatizációkat – kód nélkül, a saját szervereden.</p>
<div class="app-features"><span class="app-feature">400+ integráció</span><span class="app-feature">Vizuális szerkesztő</span><span class="app-feature">AI funkciók</span><span class="app-feature">Webhookok</span></div>
<img src="/assets/n8n-screenshot-1.webp" alt="n8n screenshot" class="app-screenshot">
<a href="/assets/n8n-screenshot-1.webp" data-gallery="n8n" class="app-shot-link"><img src="/assets/n8n-screenshot-1.webp" alt="n8n screenshot" class="app-screenshot"></a>
<a href="/assets/n8n-screenshot-2.webp" data-gallery="n8n" data-alt="n8n screenshot 2" hidden></a>
<a href="/assets/n8n-screenshot-3.webp" data-gallery="n8n" data-alt="n8n screenshot 3" hidden></a>
<a href="/assets/n8n-screenshot-4.webp" data-gallery="n8n" data-alt="n8n screenshot 4" hidden></a>
<a href="/assets/n8n-screenshot-5.webp" data-gallery="n8n" data-alt="n8n screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/n8n-io/n8n" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -521,7 +571,9 @@
<div class="app-card-body">
<p class="app-description">Receptek tárolása, étkezés tervezés és bevásárlólista. Importálj recepteket webről, oszd meg a családdal.</p>
<div class="app-features"><span class="app-feature">Recept import</span><span class="app-feature">Étlap tervezés</span><span class="app-feature">Bevásárlólista</span><span class="app-feature">Megosztás</span></div>
<img src="/assets/tandoor-screenshot-1.webp" alt="Tandoor Recipes screenshot" class="app-screenshot">
<a href="/assets/tandoor-screenshot-1.webp" data-gallery="tandoor" class="app-shot-link"><img src="/assets/tandoor-screenshot-1.webp" alt="Tandoor Recipes screenshot" class="app-screenshot"></a>
<a href="/assets/tandoor-screenshot-2.webp" data-gallery="tandoor" data-alt="Tandoor Recipes screenshot 2" hidden></a>
<a href="/assets/tandoor-screenshot-3.webp" data-gallery="tandoor" data-alt="Tandoor Recipes screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/TandoorRecipes/recipes" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -537,7 +589,9 @@
<div class="app-card-body">
<p class="app-description">Receptkezelő és étkezéstervező a családnak. Receptek importálása weboldalakról, heti menü és bevásárlólista, megosztás a családtagokkal — magyar felülettel is.</p>
<div class="app-features"><span class="app-feature">Recept import</span><span class="app-feature">Heti menü</span><span class="app-feature">Bevásárlólista</span><span class="app-feature">Magyar felület</span></div>
<img src="/assets/mealie-screenshot-1.webp" alt="Mealie screenshot" class="app-screenshot">
<a href="/assets/mealie-screenshot-1.webp" data-gallery="mealie" class="app-shot-link"><img src="/assets/mealie-screenshot-1.webp" alt="Mealie screenshot" class="app-screenshot"></a>
<a href="/assets/mealie-screenshot-2.webp" data-gallery="mealie" data-alt="Mealie screenshot 2" hidden></a>
<a href="/assets/mealie-screenshot-3.webp" data-gallery="mealie" data-alt="Mealie screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/mealie-recipes/mealie" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -553,7 +607,9 @@
<div class="app-card-body">
<p class="app-description">Receptek importálása hat magyar oldalról (mindmegette.hu, streetkitchen.hu, nosalty.hu, sobors.hu, kiskegyed.hu, gastrohobbi.hu) Mealie-be és Tandoorba — egyenként vagy tömegesen, importálás előtti szerkesztéssel.</p>
<div class="app-features"><span class="app-feature">6 magyar oldal</span><span class="app-feature">Tömeges import</span><span class="app-feature">Mealie</span><span class="app-feature">Tandoor</span></div>
<img src="/assets/recipe-importer-screenshot-1.webp" alt="Recipe Importer screenshot" class="app-screenshot">
<a href="/assets/recipe-importer-screenshot-1.webp" data-gallery="recipe-importer" class="app-shot-link"><img src="/assets/recipe-importer-screenshot-1.webp" alt="Recipe Importer screenshot" class="app-screenshot"></a>
<a href="/assets/recipe-importer-screenshot-2.webp" data-gallery="recipe-importer" data-alt="Recipe Importer screenshot 2" hidden></a>
<a href="/assets/recipe-importer-screenshot-3.webp" data-gallery="recipe-importer" data-alt="Recipe Importer screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<span class="open-source-badge" style="color: var(--warn);"><img src="/assets/checkmark-yellow.svg" alt="">Felhom saját</span>
@@ -568,7 +624,9 @@
<div class="app-card-body">
<p class="app-description">Megosztható kívánságlista karácsonyra, születésnapokra és egyéb alkalmakra. A család lefoglalhatja az ajándékokat, így nincs több dupla ajándék.</p>
<div class="app-features"><span class="app-feature">Csoportok</span><span class="app-feature">Foglalás</span><span class="app-feature">URL import</span><span class="app-feature">PWA</span></div>
<img src="/assets/wishlist-screenshot-1.webp" alt="Wishlist screenshot" class="app-screenshot">
<a href="/assets/wishlist-screenshot-1.webp" data-gallery="wishlist" class="app-shot-link"><img src="/assets/wishlist-screenshot-1.webp" alt="Wishlist screenshot" class="app-screenshot"></a>
<a href="/assets/wishlist-screenshot-2.webp" data-gallery="wishlist" data-alt="Wishlist screenshot 2" hidden></a>
<a href="/assets/wishlist-screenshot-3.webp" data-gallery="wishlist" data-alt="Wishlist screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/cmintey/wishlist" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -584,7 +642,9 @@
<div class="app-card-body">
<p class="app-description">Tartsd számon a tárgyaidat: helyszínek, címkék és kategóriák szerint rendezve, garancia-lejárattal és beszerzési árral. Vonalkód-szkenneléssel gyorsan bővíthető, és jól jön egy biztosítási kárnál is.</p>
<div class="app-features"><span class="app-feature">Leltár</span><span class="app-feature">Garanciák</span><span class="app-feature">Vonalkód</span><span class="app-feature">Címkék</span></div>
<img src="/assets/homebox-screenshot-1.webp" alt="Homebox screenshot" class="app-screenshot">
<a href="/assets/homebox-screenshot-1.webp" data-gallery="homebox" class="app-shot-link"><img src="/assets/homebox-screenshot-1.webp" alt="Homebox screenshot" class="app-screenshot"></a>
<a href="/assets/homebox-screenshot-2.webp" data-gallery="homebox" data-alt="Homebox screenshot 2" hidden></a>
<a href="/assets/homebox-screenshot-3.webp" data-gallery="homebox" data-alt="Homebox screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/sysadminsmedia/homebox" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -600,7 +660,10 @@
<div class="app-card-body">
<p class="app-description">Webes családfa és genealógia platform. Építsd fel a családfádat, adj hozzá fotókat, dokumentumokat – és oszd meg a családdal biztonságosan.</p>
<div class="app-features"><span class="app-feature">Családfa</span><span class="app-feature">GEDCOM</span><span class="app-feature">Együttműködés</span><span class="app-feature">Szinkron</span></div>
<img src="/assets/grampsweb-screenshot-1.webp" alt="Gramps Web screenshot" class="app-screenshot">
<a href="/assets/grampsweb-screenshot-1.webp" data-gallery="grampsweb" class="app-shot-link"><img src="/assets/grampsweb-screenshot-1.webp" alt="Gramps Web screenshot" class="app-screenshot"></a>
<a href="/assets/grampsweb-screenshot-2.webp" data-gallery="grampsweb" data-alt="Gramps Web screenshot 2" hidden></a>
<a href="/assets/grampsweb-screenshot-3.webp" data-gallery="grampsweb" data-alt="Gramps Web screenshot 3" hidden></a>
<a href="/assets/grampsweb-screenshot-4.webp" data-gallery="grampsweb" data-alt="Gramps Web screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/gramps-project/gramps-web" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -616,7 +679,9 @@
<div class="app-card-body">
<p class="app-description">Napi étkezések és kalóriabevitel naplózása, testsúly és testméretek grafikonon, edzések rögzítése. Tápanyagcélok (fehérje, szénhidrát, zsír) beállítása és követése.</p>
<div class="app-features"><span class="app-feature">Kalóriaszámláló</span><span class="app-feature">Testsúly</span><span class="app-feature">Edzések</span><span class="app-feature">Tápanyagcélok</span></div>
<img src="/assets/sparkyfitness-screenshot-1.webp" alt="SparkyFitness screenshot" class="app-screenshot">
<a href="/assets/sparkyfitness-screenshot-1.webp" data-gallery="sparkyfitness" class="app-shot-link"><img src="/assets/sparkyfitness-screenshot-1.webp" alt="SparkyFitness screenshot" class="app-screenshot"></a>
<a href="/assets/sparkyfitness-screenshot-2.webp" data-gallery="sparkyfitness" data-alt="SparkyFitness screenshot 2" hidden></a>
<a href="/assets/sparkyfitness-screenshot-3.webp" data-gallery="sparkyfitness" data-alt="SparkyFitness screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/CodeWithCJ/SparkyFitness" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -632,7 +697,9 @@
<div class="app-card-body">
<p class="app-description">Helyi-központú személyes pénzügyek kezelése. Költségvetés tervezés, tranzakció követés, és pénzügyi célok.</p>
<div class="app-features"><span class="app-feature">Költségvetés</span><span class="app-feature">Szinkron</span><span class="app-feature">Bank import</span><span class="app-feature">Riportok</span></div>
<img src="/assets/actualbudget-screenshot-1.webp" alt="Actual Budget screenshot" class="app-screenshot">
<a href="/assets/actualbudget-screenshot-1.webp" data-gallery="actualbudget" class="app-shot-link"><img src="/assets/actualbudget-screenshot-1.webp" alt="Actual Budget screenshot" class="app-screenshot"></a>
<a href="/assets/actualbudget-screenshot-2.webp" data-gallery="actualbudget" data-alt="Actual Budget screenshot 2" hidden></a>
<a href="/assets/actualbudget-screenshot-3.webp" data-gallery="actualbudget" data-alt="Actual Budget screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/actualbudget/actual" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -648,7 +715,11 @@
<div class="app-card-body">
<p class="app-description">Dokumentáld az utazásaidat és kalandjaidat. Térképes megjelenítés, fotók, statisztikák a meglátogatott helyekről.</p>
<div class="app-features"><span class="app-feature">Térkép</span><span class="app-feature">Fotók</span><span class="app-feature">Statisztikák</span><span class="app-feature">Megosztás</span></div>
<img src="/assets/adventurelog-screenshot-1.webp" alt="AdventureLog screenshot" class="app-screenshot">
<a href="/assets/adventurelog-screenshot-1.webp" data-gallery="adventurelog" class="app-shot-link"><img src="/assets/adventurelog-screenshot-1.webp" alt="AdventureLog screenshot" class="app-screenshot"></a>
<a href="/assets/adventurelog-screenshot-2.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 2" hidden></a>
<a href="/assets/adventurelog-screenshot-3.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 3" hidden></a>
<a href="/assets/adventurelog-screenshot-4.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 4" hidden></a>
<a href="/assets/adventurelog-screenshot-5.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/seanmorley15/AdventureLog" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -664,7 +735,10 @@
<div class="app-card-body">
<p class="app-description">Túrák és útvonalak tervezése, GPX fájlok kezelése. Térképes megjelenítés szintvonalakkal, útvonal statisztikák.</p>
<div class="app-features"><span class="app-feature">GPX import</span><span class="app-feature">Térképek</span><span class="app-feature">Szintadatok</span><span class="app-feature">Útvonalak</span></div>
<img src="/assets/wanderer-screenshot-1.webp" alt="Wanderer screenshot" class="app-screenshot">
<a href="/assets/wanderer-screenshot-1.webp" data-gallery="wanderer" class="app-shot-link"><img src="/assets/wanderer-screenshot-1.webp" alt="Wanderer screenshot" class="app-screenshot"></a>
<a href="/assets/wanderer-screenshot-2.webp" data-gallery="wanderer" data-alt="Wanderer screenshot 2" hidden></a>
<a href="/assets/wanderer-screenshot-3.webp" data-gallery="wanderer" data-alt="Wanderer screenshot 3" hidden></a>
<a href="/assets/wanderer-screenshot-4.webp" data-gallery="wanderer" data-alt="Wanderer screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Flomp/wanderer" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -680,7 +754,9 @@
<div class="app-card-body">
<p class="app-description">Saját helyelőzmények térképen: a telefonod a te szerveredre küldi, hol jártál. Térkép, statisztika és utazások; a régi adataid Google Takeout, GPX vagy GeoJSON fájlból importálhatók.</p>
<div class="app-features"><span class="app-feature">Térkép</span><span class="app-feature">Statisztika</span><span class="app-feature">Takeout import</span><span class="app-feature">Mobil app</span></div>
<img src="/assets/dawarich-screenshot-1.webp" alt="Dawarich screenshot" class="app-screenshot">
<a href="/assets/dawarich-screenshot-1.webp" data-gallery="dawarich" class="app-shot-link"><img src="/assets/dawarich-screenshot-1.webp" alt="Dawarich screenshot" class="app-screenshot"></a>
<a href="/assets/dawarich-screenshot-2.webp" data-gallery="dawarich" data-alt="Dawarich screenshot 2" hidden></a>
<a href="/assets/dawarich-screenshot-3.webp" data-gallery="dawarich" data-alt="Dawarich screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Freika/dawarich" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -696,7 +772,12 @@
<div class="app-card-body">
<p class="app-description">Nyílt forráskódú Calendly alternatíva. Könnyű időpont egyeztetés ügyfelekkel, naptár integrációk és automatikus emlékeztetők.</p>
<div class="app-features"><span class="app-feature">Foglalási oldal</span><span class="app-feature">Naptár szinkron</span><span class="app-feature">Csapatok</span><span class="app-feature">Emlékeztetők</span></div>
<img src="/assets/calcom-screenshot-1.webp" alt="Cal.com screenshot" class="app-screenshot">
<a href="/assets/calcom-screenshot-1.webp" data-gallery="calcom" class="app-shot-link"><img src="/assets/calcom-screenshot-1.webp" alt="Cal.com screenshot" class="app-screenshot"></a>
<a href="/assets/calcom-screenshot-2.webp" data-gallery="calcom" data-alt="Cal.com screenshot 2" hidden></a>
<a href="/assets/calcom-screenshot-3.webp" data-gallery="calcom" data-alt="Cal.com screenshot 3" hidden></a>
<a href="/assets/calcom-screenshot-4.webp" data-gallery="calcom" data-alt="Cal.com screenshot 4" hidden></a>
<a href="/assets/calcom-screenshot-5.webp" data-gallery="calcom" data-alt="Cal.com screenshot 5" hidden></a>
<a href="/assets/calcom-screenshot-6.webp" data-gallery="calcom" data-alt="Cal.com screenshot 6" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/calcom/cal.com" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -725,7 +806,10 @@
<div class="app-card-body">
<p class="app-description">Nyílt forráskódú Todoist alternatíva. Feladatok, projektek, határidők – Kanban, Gantt és lista nézettel. Emlékeztetők és csapat együttműködés.</p>
<div class="app-features"><span class="app-feature">Kanban</span><span class="app-feature">Gantt</span><span class="app-feature">Emlékeztetők</span><span class="app-feature">Csapatok</span></div>
<img src="/assets/vikunja-screenshot-1.webp" alt="Vikunja screenshot" class="app-screenshot">
<a href="/assets/vikunja-screenshot-1.webp" data-gallery="vikunja" class="app-shot-link"><img src="/assets/vikunja-screenshot-1.webp" alt="Vikunja screenshot" class="app-screenshot"></a>
<a href="/assets/vikunja-screenshot-2.webp" data-gallery="vikunja" data-alt="Vikunja screenshot 2" hidden></a>
<a href="/assets/vikunja-screenshot-3.webp" data-gallery="vikunja" data-alt="Vikunja screenshot 3" hidden></a>
<a href="/assets/vikunja-screenshot-4.webp" data-gallery="vikunja" data-alt="Vikunja screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/go-vikunja/vikunja" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -741,7 +825,9 @@
<div class="app-card-body">
<p class="app-description">A telefonod naptára és névjegyei a saját szervereden, nem a Google-nél vagy az Apple-nél. Közös családi naptár; Androidon a DAVx5, iPhone-on és Macen a beépített naptár szinkronizál vele.</p>
<div class="app-features"><span class="app-feature">CalDAV</span><span class="app-feature">CardDAV</span><span class="app-feature">Családi naptár</span><span class="app-feature">Thunderbird</span></div>
<img src="/assets/radicale-screenshot-1.webp" alt="Radicale screenshot" class="app-screenshot">
<a href="/assets/radicale-screenshot-1.webp" data-gallery="radicale" class="app-shot-link"><img src="/assets/radicale-screenshot-1.webp" alt="Radicale screenshot" class="app-screenshot"></a>
<a href="/assets/radicale-screenshot-2.webp" data-gallery="radicale" data-alt="Radicale screenshot 2" hidden></a>
<a href="/assets/radicale-screenshot-3.webp" data-gallery="radicale" data-alt="Radicale screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Kozea/Radicale" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -757,7 +843,11 @@
<div class="app-card-body">
<p class="app-description">Professzionális időkövetés szabadúszóknak és csapatoknak. Projektek, ügyfelek, riportok és számlázási export egyetlen rendszerben.</p>
<div class="app-features"><span class="app-feature">Projektek</span><span class="app-feature">Riportok</span><span class="app-feature">Export</span><span class="app-feature">Számlázás</span></div>
<img src="/assets/kimai-screenshot-1.webp" alt="Kimai screenshot" class="app-screenshot">
<a href="/assets/kimai-screenshot-1.webp" data-gallery="kimai" class="app-shot-link"><img src="/assets/kimai-screenshot-1.webp" alt="Kimai screenshot" class="app-screenshot"></a>
<a href="/assets/kimai-screenshot-2.webp" data-gallery="kimai" data-alt="Kimai screenshot 2" hidden></a>
<a href="/assets/kimai-screenshot-3.webp" data-gallery="kimai" data-alt="Kimai screenshot 3" hidden></a>
<a href="/assets/kimai-screenshot-4.webp" data-gallery="kimai" data-alt="Kimai screenshot 4" hidden></a>
<a href="/assets/kimai-screenshot-5.webp" data-gallery="kimai" data-alt="Kimai screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/kimai/kimai" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -773,7 +863,8 @@
<div class="app-card-body">
<p class="app-description">Találkozók és események időpontjának egyeztetése egyszerűen. Doodle alternatíva – szavazók regisztráció nélkül, időzóna kezeléssel.</p>
<div class="app-features"><span class="app-feature">Szavazás</span><span class="app-feature">Nincs regisztráció</span><span class="app-feature">Időzónák</span><span class="app-feature">Értesítések</span></div>
<img src="/assets/rallly-screenshot-1.webp" alt="Rallly screenshot" class="app-screenshot">
<a href="/assets/rallly-screenshot-1.webp" data-gallery="rallly" class="app-shot-link"><img src="/assets/rallly-screenshot-1.webp" alt="Rallly screenshot" class="app-screenshot"></a>
<a href="/assets/rallly-screenshot-2.webp" data-gallery="rallly" data-alt="Rallly screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/lukevella/rallly" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -789,7 +880,11 @@
<div class="app-card-body">
<p class="app-description">Élő szavazások, kérdések és szófelhők prezentációkhoz. Mentimeter/AhaSlides alternatíva – tedd interaktívvá az előadásaidat.</p>
<div class="app-features"><span class="app-feature">Élő szavazás</span><span class="app-feature">Kérdések</span><span class="app-feature">Szófelhő</span><span class="app-feature">Reakciók</span></div>
<img src="/assets/claper-screenshot-1.webp" alt="Claper screenshot" class="app-screenshot">
<a href="/assets/claper-screenshot-1.webp" data-gallery="claper" class="app-shot-link"><img src="/assets/claper-screenshot-1.webp" alt="Claper screenshot" class="app-screenshot"></a>
<a href="/assets/claper-screenshot-2.webp" data-gallery="claper" data-alt="Claper screenshot 2" hidden></a>
<a href="/assets/claper-screenshot-3.webp" data-gallery="claper" data-alt="Claper screenshot 3" hidden></a>
<a href="/assets/claper-screenshot-4.webp" data-gallery="claper" data-alt="Claper screenshot 4" hidden></a>
<a href="/assets/claper-screenshot-5.webp" data-gallery="claper" data-alt="Claper screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/ClaperCo/Claper" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -805,7 +900,10 @@
<div class="app-card-body">
<p class="app-description">Modern publikációs platform bloggereknek és tartalomkészítőknek. Gyönyörű témák, beépített hírlevél, és tagság/előfizetés kezelés.</p>
<div class="app-features"><span class="app-feature">Blog</span><span class="app-feature">Hírlevél</span><span class="app-feature">Tagság</span><span class="app-feature">SEO</span></div>
<img src="/assets/ghost-screenshot-1.webp" alt="Ghost screenshot" class="app-screenshot">
<a href="/assets/ghost-screenshot-1.webp" data-gallery="ghost" class="app-shot-link"><img src="/assets/ghost-screenshot-1.webp" alt="Ghost screenshot" class="app-screenshot"></a>
<a href="/assets/ghost-screenshot-2.webp" data-gallery="ghost" data-alt="Ghost screenshot 2" hidden></a>
<a href="/assets/ghost-screenshot-3.webp" data-gallery="ghost" data-alt="Ghost screenshot 3" hidden></a>
<a href="/assets/ghost-screenshot-4.webp" data-gallery="ghost" data-alt="Ghost screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/TryGhost/Ghost" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -821,7 +919,9 @@
<div class="app-card-body">
<p class="app-description">Szkenneld be a papír dokumentumaidat és felejtsd el őket. OCR, automatikus kategorizálás, és teljes szöveges keresés.</p>
<div class="app-features"><span class="app-feature">OCR</span><span class="app-feature">Auto kategória</span><span class="app-feature">Keresés</span><span class="app-feature">Címkék</span></div>
<img src="/assets/paperless-ngx-screenshot-1.webp" alt="Paperless-ngx screenshot" class="app-screenshot">
<a href="/assets/paperless-ngx-screenshot-1.webp" data-gallery="paperless-ngx" class="app-shot-link"><img src="/assets/paperless-ngx-screenshot-1.webp" alt="Paperless-ngx screenshot" class="app-screenshot"></a>
<a href="/assets/paperless-ngx-screenshot-2.webp" data-gallery="paperless-ngx" data-alt="Paperless-ngx screenshot 2" hidden></a>
<a href="/assets/paperless-ngx-screenshot-3.webp" data-gallery="paperless-ngx" data-alt="Paperless-ngx screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/paperless-ngx/paperless-ngx" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -837,7 +937,9 @@
<div class="app-card-body">
<p class="app-description">Egyszerű, önhostolt wiki platform. Rendezd tudásodat könyvekbe, fejezetekbe és oldalakra – könnyen kereshető formában.</p>
<div class="app-features"><span class="app-feature">WYSIWYG</span><span class="app-feature">Könyvek</span><span class="app-feature">Keresés</span><span class="app-feature">Jogosultságok</span></div>
<img src="/assets/bookstack-screenshot-1.webp" alt="BookStack screenshot" class="app-screenshot">
<a href="/assets/bookstack-screenshot-1.webp" data-gallery="bookstack" class="app-shot-link"><img src="/assets/bookstack-screenshot-1.webp" alt="BookStack screenshot" class="app-screenshot"></a>
<a href="/assets/bookstack-screenshot-2.webp" data-gallery="bookstack" data-alt="BookStack screenshot 2" hidden></a>
<a href="/assets/bookstack-screenshot-3.webp" data-gallery="bookstack" data-alt="BookStack screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/BookStackApp/BookStack" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -853,7 +955,8 @@
<div class="app-card-body">
<p class="app-description">Gyönyörű wiki és tudásbázis csapatok számára. Markdown támogatás, valós idejű együttműködés, és strukturált dokumentáció.</p>
<div class="app-features"><span class="app-feature">Markdown</span><span class="app-feature">Együttműködés</span><span class="app-feature">Keresés</span><span class="app-feature">Integráció</span></div>
<img src="/assets/outline-screenshot-1.webp" alt="Outline screenshot" class="app-screenshot">
<a href="/assets/outline-screenshot-1.webp" data-gallery="outline" class="app-shot-link"><img src="/assets/outline-screenshot-1.webp" alt="Outline screenshot" class="app-screenshot"></a>
<a href="/assets/outline-screenshot-2.webp" data-gallery="outline" data-alt="Outline screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/outline/outline" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -869,7 +972,9 @@
<div class="app-card-body">
<p class="app-description">Modern wiki és dokumentáció platform Notion-szerű blokk szerkesztővel. Terek és oldalak hierarchiában, valós idejű közös szerkesztés, keresés a teljes tartalomban.</p>
<div class="app-features"><span class="app-feature">Blokk szerkesztő</span><span class="app-feature">Közös szerkesztés</span><span class="app-feature">Keresés</span><span class="app-feature">Táblázatok</span></div>
<img src="/assets/docmost-screenshot-1.webp" alt="Docmost screenshot" class="app-screenshot">
<a href="/assets/docmost-screenshot-1.webp" data-gallery="docmost" class="app-shot-link"><img src="/assets/docmost-screenshot-1.webp" alt="Docmost screenshot" class="app-screenshot"></a>
<a href="/assets/docmost-screenshot-2.webp" data-gallery="docmost" data-alt="Docmost screenshot 2" hidden></a>
<a href="/assets/docmost-screenshot-3.webp" data-gallery="docmost" data-alt="Docmost screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/docmost/docmost" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -885,7 +990,9 @@
<div class="app-card-body">
<p class="app-description">Könyvjelzők, cikkek, jegyzetek és képek egy helyen. A Karakeep letölti és elteszi a mentett oldalak tartalmát, akkor is, ha az oldal később eltűnik. Teljes szöveges keresés, böngészőbővítmény és telefonos alkalmazás.</p>
<div class="app-features"><span class="app-feature">Oldalmentés</span><span class="app-feature">Keresés</span><span class="app-feature">Böngészőbővítmény</span><span class="app-feature">Mobil app</span></div>
<img src="/assets/karakeep-screenshot-1.webp" alt="Karakeep screenshot" class="app-screenshot">
<a href="/assets/karakeep-screenshot-1.webp" data-gallery="karakeep" class="app-shot-link"><img src="/assets/karakeep-screenshot-1.webp" alt="Karakeep screenshot" class="app-screenshot"></a>
<a href="/assets/karakeep-screenshot-2.webp" data-gallery="karakeep" data-alt="Karakeep screenshot 2" hidden></a>
<a href="/assets/karakeep-screenshot-3.webp" data-gallery="karakeep" data-alt="Karakeep screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/karakeep-app/karakeep" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -901,7 +1008,8 @@
<div class="app-card-body">
<p class="app-description">Minimális, titkosított pastebin. A szerver nem látja a tartalmakat – tökéletes érzékeny szövegek biztonságos megosztására.</p>
<div class="app-features"><span class="app-feature">E2E titkosítás</span><span class="app-feature">Lejárat</span><span class="app-feature">Égés után</span><span class="app-feature">Jelszóvédelem</span></div>
<img src="/assets/privatebin-screenshot-1.webp" alt="PrivateBin screenshot" class="app-screenshot">
<a href="/assets/privatebin-screenshot-1.webp" data-gallery="privatebin" class="app-shot-link"><img src="/assets/privatebin-screenshot-1.webp" alt="PrivateBin screenshot" class="app-screenshot"></a>
<a href="/assets/privatebin-screenshot-2.webp" data-gallery="privatebin" data-alt="PrivateBin screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/PrivateBin/PrivateBin" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -930,7 +1038,7 @@
<div class="app-card-body">
<p class="app-description">Könnyű Bitwarden szerver implementáció. Tárold biztonságosan a jelszavaidat, és szinkronizáld minden eszközödön.</p>
<div class="app-features"><span class="app-feature">E2E titkosítás</span><span class="app-feature">Mobil app</span><span class="app-feature">Böngésző kieg.</span><span class="app-feature">2FA</span></div>
<img src="/assets/vaultwarden-screenshot-1.webp" alt="Vaultwarden screenshot" class="app-screenshot">
<a href="/assets/vaultwarden-screenshot-1.webp" data-gallery="vaultwarden" class="app-shot-link"><img src="/assets/vaultwarden-screenshot-1.webp" alt="Vaultwarden screenshot" class="app-screenshot"></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/dani-garcia/vaultwarden" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -946,7 +1054,10 @@
<div class="app-card-body">
<p class="app-description">Gyönyörű és funkciókban gazdag kezdőlap a szerveredhez. Szolgáltatás státuszok, widgetek, könyvjelzők egy helyen.</p>
<div class="app-features"><span class="app-feature">Widgetek</span><span class="app-feature">Integrációk</span><span class="app-feature">Témák</span><span class="app-feature">Státusz</span></div>
<img src="/assets/homepage-screenshot-1.webp" alt="Homepage screenshot" class="app-screenshot">
<a href="/assets/homepage-screenshot-1.webp" data-gallery="homepage" class="app-shot-link"><img src="/assets/homepage-screenshot-1.webp" alt="Homepage screenshot" class="app-screenshot"></a>
<a href="/assets/homepage-screenshot-2.webp" data-gallery="homepage" data-alt="Homepage screenshot 2" hidden></a>
<a href="/assets/homepage-screenshot-3.webp" data-gallery="homepage" data-alt="Homepage screenshot 3" hidden></a>
<a href="/assets/homepage-screenshot-4.webp" data-gallery="homepage" data-alt="Homepage screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/gethomepage/homepage" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -962,7 +1073,10 @@
<div class="app-card-body">
<p class="app-description">Minimális, gyors dashboard mindenféle információval. RSS, időjárás, könyvjelzők, Reddit, YouTube és sok más egy oldalon.</p>
<div class="app-features"><span class="app-feature">RSS</span><span class="app-feature">Időjárás</span><span class="app-feature">YouTube</span><span class="app-feature">Gyors</span></div>
<img src="/assets/glance-screenshot-1.webp" alt="Glance screenshot" class="app-screenshot">
<a href="/assets/glance-screenshot-1.webp" data-gallery="glance" class="app-shot-link"><img src="/assets/glance-screenshot-1.webp" alt="Glance screenshot" class="app-screenshot"></a>
<a href="/assets/glance-screenshot-2.webp" data-gallery="glance" data-alt="Glance screenshot 2" hidden></a>
<a href="/assets/glance-screenshot-3.webp" data-gallery="glance" data-alt="Glance screenshot 3" hidden></a>
<a href="/assets/glance-screenshot-4.webp" data-gallery="glance" data-alt="Glance screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/glanceapp/glance" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -978,7 +1092,9 @@
<div class="app-card-body">
<p class="app-description">Elegáns szolgáltatás monitorozó. Figyeld a weboldalaidat, API-kat, és kapj értesítést ha valami nem működik.</p>
<div class="app-features"><span class="app-feature">HTTP/TCP/DNS</span><span class="app-feature">Értesítések</span><span class="app-feature">Státusz oldal</span><span class="app-feature">Grafikonok</span></div>
<img src="/assets/uptimekuma-screenshot-1.webp" alt="Uptime Kuma screenshot" class="app-screenshot">
<a href="/assets/uptimekuma-screenshot-1.webp" data-gallery="uptimekuma" class="app-shot-link"><img src="/assets/uptimekuma-screenshot-1.webp" alt="Uptime Kuma screenshot" class="app-screenshot"></a>
<a href="/assets/uptimekuma-screenshot-2.webp" data-gallery="uptimekuma" data-alt="Uptime Kuma screenshot 2" hidden></a>
<a href="/assets/uptimekuma-screenshot-3.webp" data-gallery="uptimekuma" data-alt="Uptime Kuma screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/louislam/uptime-kuma" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -994,7 +1110,10 @@
<div class="app-card-body">
<p class="app-description">Professzionális monitoring és vizualizációs platform. Gyönyörű dashboardok, riasztások és adatelemzés – bármilyen adatforrásból.</p>
<div class="app-features"><span class="app-feature">Dashboardok</span><span class="app-feature">Riasztások</span><span class="app-feature">Adatforrások</span><span class="app-feature">Lekérdezések</span></div>
<img src="/assets/grafana-screenshot-1.webp" alt="Grafana screenshot" class="app-screenshot">
<a href="/assets/grafana-screenshot-1.webp" data-gallery="grafana" class="app-shot-link"><img src="/assets/grafana-screenshot-1.webp" alt="Grafana screenshot" class="app-screenshot"></a>
<a href="/assets/grafana-screenshot-2.webp" data-gallery="grafana" data-alt="Grafana screenshot 2" hidden></a>
<a href="/assets/grafana-screenshot-3.webp" data-gallery="grafana" data-alt="Grafana screenshot 3" hidden></a>
<a href="/assets/grafana-screenshot-4.webp" data-gallery="grafana" data-alt="Grafana screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/grafana/grafana" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -1010,7 +1129,10 @@
<div class="app-card-body">
<p class="app-description">Webes SSH terminál és szerver kezelő platform. Csatlakozz szervereidhez bárhonnan böngészőből, kezelj SSH tunneleket, szerkessz fájlokat távolról.</p>
<div class="app-features"><span class="app-feature">SSH terminál</span><span class="app-feature">Tunneling</span><span class="app-feature">Fájlkezelő</span><span class="app-feature">2FA</span></div>
<img src="/assets/termix-screenshot-1.webp" alt="Termix screenshot" class="app-screenshot">
<a href="/assets/termix-screenshot-1.webp" data-gallery="termix" class="app-shot-link"><img src="/assets/termix-screenshot-1.webp" alt="Termix screenshot" class="app-screenshot"></a>
<a href="/assets/termix-screenshot-2.webp" data-gallery="termix" data-alt="Termix screenshot 2" hidden></a>
<a href="/assets/termix-screenshot-3.webp" data-gallery="termix" data-alt="Termix screenshot 3" hidden></a>
<a href="/assets/termix-screenshot-4.webp" data-gallery="termix" data-alt="Termix screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Termix-SSH/Termix" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -1026,7 +1148,9 @@
<div class="app-card-body">
<p class="app-description">Könnyű, gyors Git hosting szolgáltatás. A saját GitHub/GitLab-od, issue tracking, CI/CD, és package registry.</p>
<div class="app-features"><span class="app-feature">Git hosting</span><span class="app-feature">Issues</span><span class="app-feature">CI/CD</span><span class="app-feature">Wiki</span></div>
<img src="/assets/gitea-screenshot-1.webp" alt="Gitea screenshot" class="app-screenshot">
<a href="/assets/gitea-screenshot-1.webp" data-gallery="gitea" class="app-shot-link"><img src="/assets/gitea-screenshot-1.webp" alt="Gitea screenshot" class="app-screenshot"></a>
<a href="/assets/gitea-screenshot-2.webp" data-gallery="gitea" data-alt="Gitea screenshot 2" hidden></a>
<a href="/assets/gitea-screenshot-3.webp" data-gallery="gitea" data-alt="Gitea screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/go-gitea/gitea" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -1042,7 +1166,8 @@
<div class="app-card-body">
<p class="app-description">Visual Studio Code a böngészőben. Fejlessz bárhonnan, bármilyen eszközről – ugyanazzal az ismerős felülettel.</p>
<div class="app-features"><span class="app-feature">VS Code</span><span class="app-feature">Bővítmények</span><span class="app-feature">Terminál</span><span class="app-feature">Git</span></div>
<img src="/assets/code-server-screenshot-1.webp" alt="Code-Server screenshot" class="app-screenshot">
<a href="/assets/code-server-screenshot-1.webp" data-gallery="code-server" class="app-shot-link"><img src="/assets/code-server-screenshot-1.webp" alt="Code-Server screenshot" class="app-screenshot"></a>
<a href="/assets/code-server-screenshot-2.webp" data-gallery="code-server" data-alt="Code-Server screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/coder/code-server" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -1058,7 +1183,9 @@
<div class="app-card-body">
<p class="app-description">Saját GitHub Gist szerver. Kód snippetek megosztása, szintaxis kiemelés, és verziókezelés Git alapokon.</p>
<div class="app-features"><span class="app-feature">Snippetek</span><span class="app-feature">Szintaxis</span><span class="app-feature">Git</span><span class="app-feature">Embed</span></div>
<img src="/assets/opengist-screenshot-1.webp" alt="OpenGist screenshot" class="app-screenshot">
<a href="/assets/opengist-screenshot-1.webp" data-gallery="opengist" class="app-shot-link"><img src="/assets/opengist-screenshot-1.webp" alt="OpenGist screenshot" class="app-screenshot"></a>
<a href="/assets/opengist-screenshot-2.webp" data-gallery="opengist" data-alt="OpenGist screenshot 2" hidden></a>
<a href="/assets/opengist-screenshot-3.webp" data-gallery="opengist" data-alt="OpenGist screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/thomiceli/opengist" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Forráskód</a>
@@ -1111,289 +1238,6 @@
</div>
</footer>
<!-- Lightbox HTML -->
<div class="lightbox-overlay" id="lightbox">
<button class="lightbox-close" aria-label="Bezárás">&times;</button>
<div class="lightbox-content">
<button class="lightbox-nav lightbox-prev" aria-label="Előző">‹</button>
<img class="lightbox-image" id="lightbox-img" src="" alt="">
<button class="lightbox-nav lightbox-next" aria-label="Következő">›</button>
</div>
<div class="lightbox-counter" id="lightbox-counter"></div>
<div class="lightbox-dots" id="lightbox-dots"></div>
</div>
<script>
/**
* Screenshot Gallery / Lightbox functionality
* - Click on app screenshot to open lightbox
* - Automatically detects multiple screenshots (app-screenshot-1.webp, app-screenshot-2.webp, etc.)
* - Navigate with arrows or keyboard
*/
(function() {
'use strict';
// Debug mode - set to true for console logging
const DEBUG = false;
function log(...args) {
if (DEBUG) console.log('[Gallery]', ...args);
}
// DOM elements
const lightbox = document.getElementById('lightbox');
const lightboxImg = document.getElementById('lightbox-img');
const lightboxCounter = document.getElementById('lightbox-counter');
const lightboxDots = document.getElementById('lightbox-dots');
const closeBtn = lightbox.querySelector('.lightbox-close');
const prevBtn = lightbox.querySelector('.lightbox-prev');
const nextBtn = lightbox.querySelector('.lightbox-next');
// State
const state = {
images: [],
currentIndex: 0,
appName: ''
};
/**
* Check if an image URL exists
* @param {string} url
* @returns {Promise<boolean>}
*/
async function imageExists(url) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(true);
img.onerror = () => resolve(false);
img.src = url;
});
}
/**
* Detect all available screenshots for an app
* @param {string} appName
* @returns {Promise<string[]>}
*/
async function detectScreenshots(appName) {
const screenshots = [];
const maxScreenshots = 10; // Maximum to check
for (let i = 1; i <= maxScreenshots; i++) {
const url = `/assets/${appName}-screenshot-${i}.webp`;
const exists = await imageExists(url);
if (exists) {
screenshots.push(url);
log(`Found: ${url}`);
} else {
// Stop checking after first missing number
break;
}
}
// Fallback: if no numbered screenshots found, use the clicked image
if (screenshots.length === 0) {
const fallbackUrl = `/assets/${appName}-screenshot-1.webp`;
screenshots.push(fallbackUrl);
}
return screenshots;
}
/**
* Extract app name from screenshot URL
* @param {string} src
* @returns {string} - The app name
*/
function extractAppName(src) {
// Match patterns: app-screenshot-1.webp or app-screenshot-1.webp
const match = src.match(/\/assets\/([a-z0-9-]+)-screenshot(?:-\d+)?\.webp/i);
return match ? match[1] : '';
}
/**
* Update the lightbox display
*/
function updateLightbox() {
if (state.images.length === 0) return;
const currentImg = state.images[state.currentIndex];
lightboxImg.src = currentImg;
lightboxImg.alt = `${state.appName} screenshot ${state.currentIndex + 1}`;
// Update counter
lightboxCounter.textContent = `${state.currentIndex + 1} / ${state.images.length}`;
// Update dots
const dots = lightboxDots.querySelectorAll('.lightbox-dot');
dots.forEach((dot, i) => {
dot.classList.toggle('active', i === state.currentIndex);
});
// Update nav buttons
prevBtn.disabled = state.currentIndex === 0;
nextBtn.disabled = state.currentIndex === state.images.length - 1;
// Hide nav and dots if only one image
const singleImage = state.images.length <= 1;
prevBtn.style.display = singleImage ? 'none' : 'flex';
nextBtn.style.display = singleImage ? 'none' : 'flex';
lightboxDots.style.display = singleImage ? 'none' : 'flex';
lightboxCounter.style.display = singleImage ? 'none' : 'block';
}
/**
* Create navigation dots
*/
function createDots() {
lightboxDots.innerHTML = '';
state.images.forEach((_, i) => {
const dot = document.createElement('button');
dot.className = 'lightbox-dot' + (i === state.currentIndex ? ' active' : '');
dot.setAttribute('aria-label', `Ugrás ${i + 1}. képhez`);
dot.addEventListener('click', () => goToImage(i));
lightboxDots.appendChild(dot);
});
}
/**
* Go to specific image
* @param {number} index
*/
function goToImage(index) {
if (index >= 0 && index < state.images.length) {
state.currentIndex = index;
updateLightbox();
}
}
/**
* Open lightbox for an app
* @param {HTMLImageElement} thumbnailImg
*/
async function openLightbox(thumbnailImg) {
const appName = extractAppName(thumbnailImg.src);
if (!appName) {
log('Could not extract app name from:', thumbnailImg.src);
return;
}
log('Opening lightbox for:', appName);
// Show loading state
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
lightboxImg.src = thumbnailImg.src; // Show thumbnail immediately
lightboxImg.alt = thumbnailImg.alt;
lightboxCounter.textContent = 'Betöltés...';
lightboxDots.innerHTML = '';
// Detect available screenshots
state.appName = appName;
state.images = await detectScreenshots(appName);
state.currentIndex = 0;
log('Found screenshots:', state.images);
createDots();
updateLightbox();
}
/**
* Close the lightbox
*/
function closeLightbox() {
lightbox.classList.remove('active');
document.body.style.overflow = '';
state.images = [];
state.currentIndex = 0;
}
/**
* Navigate to previous image
*/
function prevImage() {
if (state.currentIndex > 0) {
state.currentIndex--;
updateLightbox();
}
}
/**
* Navigate to next image
*/
function nextImage() {
if (state.currentIndex < state.images.length - 1) {
state.currentIndex++;
updateLightbox();
}
}
// Event Listeners
// Click on screenshot thumbnails
document.addEventListener('click', (e) => {
const screenshot = e.target.closest('.app-screenshot');
if (screenshot) {
e.preventDefault();
openLightbox(screenshot);
}
});
// Close button
closeBtn.addEventListener('click', closeLightbox);
// Navigation buttons
prevBtn.addEventListener('click', prevImage);
nextBtn.addEventListener('click', nextImage);
// Click on overlay (outside image) to close
lightbox.addEventListener('click', (e) => {
if (e.target === lightbox) {
closeLightbox();
}
});
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (!lightbox.classList.contains('active')) return;
switch (e.key) {
case 'Escape':
closeLightbox();
break;
case 'ArrowLeft':
prevImage();
break;
case 'ArrowRight':
nextImage();
break;
}
});
// Touch/swipe support for mobile
let touchStartX = 0;
let touchEndX = 0;
lightbox.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
}, { passive: true });
lightbox.addEventListener('touchend', (e) => {
touchEndX = e.changedTouches[0].screenX;
const diff = touchStartX - touchEndX;
if (Math.abs(diff) > 50) { // Minimum swipe distance
if (diff > 0) {
nextImage(); // Swipe left = next
} else {
prevImage(); // Swipe right = prev
}
}
}, { passive: true });
log('Gallery initialized');
})();
</script>
<script>
(function() {
var hamburger = document.getElementById('hamburger');
+170
View File
@@ -0,0 +1,170 @@
/**
* Screenshot Gallery / Lightbox functionality — the website's ONE picture viewer (2026-10-08).
*
* A set is DECLARED in the page, never guessed: every picture that opens the viewer is a real link to its full-size
* file, `<a href="/assets/…webp" data-gallery="<set>">`, and a set is all links with the same name, in page order.
* An app card's further pictures are hidden links in the same card. Nothing is probed, nothing outside the page is
* requested. With JavaScript off the link simply opens the image, so the page keeps working.
*
* Closes on: the close button, Esc, a click beside the picture, and a click or tap ON the picture. A swipe changes the
* picture and does not close. Labels follow <html lang>.
*/
(function () {
'use strict';
// Debug mode - set to true for console logging
const DEBUG = false;
function log(...args) {
if (DEBUG) console.log('[Gallery]', ...args);
}
const LABELS = {
hu: { close: 'Bezárás', prev: 'Előző', next: 'Következő', loading: 'Betöltés...', go: n => `Ugrás ${n}. képhez`, dialog: 'Képnézegető' },
en: { close: 'Close', prev: 'Previous', next: 'Next', loading: 'Loading...', go: n => `Go to image ${n}`, dialog: 'Picture viewer' },
};
const lang = (document.documentElement.lang || 'hu').slice(0, 2);
const L = LABELS[lang] || LABELS.hu;
// The markup, built once.
const box = document.createElement('div');
box.className = 'lightbox-overlay';
box.setAttribute('role', 'dialog');
box.setAttribute('aria-modal', 'true');
box.setAttribute('aria-label', L.dialog);
box.tabIndex = -1;
box.innerHTML =
'<button type="button" class="lightbox-close"></button>' +
'<div class="lightbox-content">' +
'<button type="button" class="lightbox-nav lightbox-prev">‹</button>' +
'<img class="lightbox-image" src="" alt="">' +
'<button type="button" class="lightbox-nav lightbox-next">›</button>' +
'</div>' +
'<div class="lightbox-counter"></div>' +
'<div class="lightbox-dots"></div>';
const closeBtn = box.querySelector('.lightbox-close');
const prevBtn = box.querySelector('.lightbox-prev');
const nextBtn = box.querySelector('.lightbox-next');
const img = box.querySelector('.lightbox-image');
const counter = box.querySelector('.lightbox-counter');
const dots = box.querySelector('.lightbox-dots');
closeBtn.setAttribute('aria-label', L.close);
closeBtn.innerHTML = '&times;';
prevBtn.setAttribute('aria-label', L.prev);
nextBtn.setAttribute('aria-label', L.next);
const state = { items: [], index: 0, opener: null, swiped: false };
function altOf(a, fallback) {
const i = a.querySelector('img');
return (i && i.getAttribute('alt')) || a.getAttribute('data-alt') || fallback || '';
}
function show() {
const it = state.items[state.index];
counter.textContent = L.loading;
img.onload = () => update();
img.src = it.src;
img.alt = it.alt;
update();
}
function update() {
const n = state.items.length;
counter.textContent = `${state.index + 1} / ${n}`;
dots.querySelectorAll('.lightbox-dot').forEach((d, i) => d.classList.toggle('active', i === state.index));
prevBtn.disabled = state.index === 0;
nextBtn.disabled = state.index === n - 1;
const single = n <= 1;
prevBtn.style.display = single ? 'none' : 'flex';
nextBtn.style.display = single ? 'none' : 'flex';
dots.style.display = single ? 'none' : 'flex';
counter.style.display = single ? 'none' : 'block';
}
function go(i) {
if (i >= 0 && i < state.items.length && i !== state.index) {
state.index = i;
show();
}
}
function open(link) {
const name = link.getAttribute('data-gallery');
const links = Array.from(document.querySelectorAll('a[data-gallery]')).filter(a => a.getAttribute('data-gallery') === name);
const clickedAlt = altOf(link);
state.items = links.map(a => ({ src: a.getAttribute('href'), alt: a === link ? clickedAlt : altOf(a, clickedAlt) }));
state.index = Math.max(0, links.indexOf(link));
state.opener = link;
log('open', name, state.items.length, 'pictures');
dots.innerHTML = '';
state.items.forEach((_, i) => {
const d = document.createElement('button');
d.type = 'button';
d.className = 'lightbox-dot';
d.setAttribute('aria-label', L.go(i + 1));
d.addEventListener('click', e => { e.stopPropagation(); go(i); });
dots.appendChild(d);
});
if (!box.parentNode) document.body.appendChild(box);
box.classList.add('active');
document.body.style.overflow = 'hidden';
show();
closeBtn.focus();
}
function close() {
if (!box.classList.contains('active')) return;
box.classList.remove('active');
document.body.style.overflow = '';
img.removeAttribute('src');
const back = state.opener;
state.items = [];
state.index = 0;
state.opener = null;
if (back) back.focus();
log('closed');
}
// Openers: a plain click opens the viewer; a modified click (new tab, etc.) is left to the browser.
document.addEventListener('click', e => {
const a = e.target.closest('a[data-gallery]');
if (!a || e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
e.preventDefault();
open(a);
});
closeBtn.addEventListener('click', e => { e.stopPropagation(); close(); });
prevBtn.addEventListener('click', e => { e.stopPropagation(); go(state.index - 1); });
nextBtn.addEventListener('click', e => { e.stopPropagation(); go(state.index + 1); });
// A click anywhere else closes: beside the picture, and on the picture itself — unless it ended a swipe.
box.addEventListener('click', e => {
if (state.swiped) { state.swiped = false; return; }
if (e.target === box || e.target.classList.contains('lightbox-content') || e.target === img) close();
});
document.addEventListener('keydown', e => {
if (!box.classList.contains('active')) return;
if (e.key === 'Escape') close();
else if (e.key === 'ArrowLeft') go(state.index - 1);
else if (e.key === 'ArrowRight') go(state.index + 1);
});
// Swipe on a phone: changes the picture, never closes (the click that follows a swipe is swallowed above).
let startX = 0, startY = 0;
box.addEventListener('touchstart', e => {
startX = e.changedTouches[0].screenX;
startY = e.changedTouches[0].screenY;
state.swiped = false;
}, { passive: true });
box.addEventListener('touchend', e => {
const dx = startX - e.changedTouches[0].screenX;
const dy = startY - e.changedTouches[0].screenY;
if (Math.abs(dx) > 50 && Math.abs(dx) > Math.abs(dy)) {
state.swiped = true;
if (dx > 0) go(state.index + 1); else go(state.index - 1);
}
}, { passive: true });
log('Gallery initialized');
})();
+26 -23
View File
@@ -955,9 +955,11 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
.page-alkalmazasok .app-description { color: var(--text-2); font-size: 0.9rem; line-height: 1.6; margin-bottom: 16px; flex-grow: 1; }
.page-alkalmazasok .app-features { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.page-alkalmazasok .app-feature { background: var(--blue-dim); color: var(--blue-bright); padding: 4px 10px; border-radius: var(--radius); font-size: 0.75rem; font-weight: 500; }
.page-alkalmazasok .app-shot-link { display: block; }
.page-alkalmazasok .app-screenshot { width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: var(--radius); border: 1px solid var(--line); background: var(--bg-1); cursor: pointer; transition: opacity 0.2s ease, transform 0.2s ease; }
.page-alkalmazasok .app-screenshot:hover { opacity: 0.9; transform: scale(1.02); }
.page-alkalmazasok .lightbox-overlay {
/* --- The picture viewer (assets/gallery.js), on every page that declares a data-gallery set --- */
.lightbox-overlay {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
@@ -968,8 +970,8 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
flex-direction: column;
padding: 20px;
}
.page-alkalmazasok .lightbox-overlay.active { display: flex; }
.page-alkalmazasok .lightbox-close {
.lightbox-overlay.active { display: flex; }
.lightbox-close {
position: absolute;
top: 20px; right: 24px;
background: none;
@@ -982,8 +984,8 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
transition: color 0.2s ease;
z-index: 1002;
}
.page-alkalmazasok .lightbox-close:hover { color: var(--text-1); }
.page-alkalmazasok .lightbox-content {
.lightbox-close:hover { color: var(--text-1); }
.lightbox-content {
position: relative;
max-width: 90vw;
max-height: 80vh;
@@ -991,14 +993,14 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
justify-content: center;
align-items: center;
}
.page-alkalmazasok .lightbox-image {
.lightbox-image {
max-width: 100%;
max-height: 80vh;
object-fit: contain;
border-radius: var(--radius);
cursor: zoom-out;
}
.page-alkalmazasok .lightbox-nav {
.lightbox-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
@@ -1016,24 +1018,24 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
transition: all 0.2s ease;
z-index: 1001;
}
.page-alkalmazasok .lightbox-nav:hover { background: var(--blue); border-color: var(--blue); }
.page-alkalmazasok .lightbox-nav:disabled { opacity: 0.3; cursor: not-allowed; }
.page-alkalmazasok .lightbox-nav:disabled:hover { background: var(--bg-1); border-color: var(--line); }
.page-alkalmazasok .lightbox-prev { left: -60px; }
.page-alkalmazasok .lightbox-next { right: -60px; }
.page-alkalmazasok .lightbox-counter {
.lightbox-nav:hover { background: var(--blue); border-color: var(--blue); }
.lightbox-nav:disabled { opacity: 0.3; cursor: not-allowed; }
.lightbox-nav:disabled:hover { background: var(--bg-1); border-color: var(--line); }
.lightbox-prev { left: -60px; }
.lightbox-next { right: -60px; }
.lightbox-counter {
margin-top: 16px;
color: var(--text-2);
font-size: 0.9rem;
text-align: center;
}
.page-alkalmazasok .lightbox-dots {
.lightbox-dots {
display: flex;
gap: 8px;
margin-top: 12px;
justify-content: center;
}
.page-alkalmazasok .lightbox-dot {
.lightbox-dot {
width: 10px;
height: 10px;
border-radius: 50%;
@@ -1042,17 +1044,17 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
cursor: pointer;
transition: background 0.2s ease;
}
.page-alkalmazasok .lightbox-dot:hover { background: var(--text-3); }
.page-alkalmazasok .lightbox-dot.active { background: var(--blue-bright); }
.lightbox-dot:hover { background: var(--text-3); }
.lightbox-dot.active { background: var(--blue-bright); }
@media (max-width: 768px) {
.page-alkalmazasok .lightbox-nav {
.lightbox-nav {
width: 40px;
height: 40px;
font-size: 1.2rem;
}
.page-alkalmazasok .lightbox-prev { left: 10px; }
.page-alkalmazasok .lightbox-next { right: 10px; }
.page-alkalmazasok .lightbox-content {
.lightbox-prev { left: 10px; }
.lightbox-next { right: 10px; }
.lightbox-content {
max-width: 95vw;
}
}
@@ -2058,7 +2060,8 @@ footer p { color: var(--text-2); font-size: 0.9rem; }
}
/* --- Dashboard pictures (2026-10-08): real screenshots, two per row, one on a phone. A picture links to its
full-size file; no lightbox. Hairline border, 2px radius, no shadow. --- */
full-size file, which assets/gallery.js opens in the viewer (data-gallery="dashboard"). Hairline border, 2px
radius, no shadow. --- */
.dash-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; margin: 8px 0 24px; }
.dash-shot { margin: 0; }
.dash-shot img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: var(--radius); }
+1 -1
View File
@@ -37,7 +37,7 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+185 -341
View File
@@ -43,8 +43,9 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<script defer src="/assets/gallery.js?v=1"></script>
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
</head>
<body class="page-alkalmazasok">
@@ -111,7 +112,9 @@
<div class="app-card-body">
<p class="app-description">A full cloud service on your own server. File sync, calendar, contacts, document editing and a great many add-ons.</p>
<div class="app-features"><span class="app-feature">File sync</span><span class="app-feature">Calendar</span><span class="app-feature">Documents</span><span class="app-feature">Mobile app</span></div>
<img src="/assets/nextcloud-screenshot-1.webp" alt="Nextcloud screenshot" class="app-screenshot">
<a href="/assets/nextcloud-screenshot-1.webp" data-gallery="nextcloud" class="app-shot-link"><img src="/assets/nextcloud-screenshot-1.webp" alt="Nextcloud screenshot" class="app-screenshot"></a>
<a href="/assets/nextcloud-screenshot-2.webp" data-gallery="nextcloud" data-alt="Nextcloud screenshot 2" hidden></a>
<a href="/assets/nextcloud-screenshot-3.webp" data-gallery="nextcloud" data-alt="Nextcloud screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/nextcloud/server" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -127,7 +130,8 @@
<div class="app-card-body">
<p class="app-description">A light, fast web file manager, built into every Felhom box. Browse, upload and share your files from anywhere, in a modern interface.</p>
<div class="app-features"><span class="app-feature">Drag & drop</span><span class="app-feature">Sharing</span><span class="app-feature">Preview</span><span class="app-feature">Search</span></div>
<img src="/assets/filebrowser-screenshot-1.webp" alt="FileBrowser screenshot" class="app-screenshot">
<a href="/assets/filebrowser-screenshot-1.webp" data-gallery="filebrowser" class="app-shot-link"><img src="/assets/filebrowser-screenshot-1.webp" alt="FileBrowser screenshot" class="app-screenshot"></a>
<a href="/assets/filebrowser-screenshot-2.webp" data-gallery="filebrowser" data-alt="FileBrowser screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/filebrowser/filebrowser" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -143,7 +147,7 @@
<div class="app-card-body">
<p class="app-description">A lightweight file-sharing server with expiry dates and download limits. Good for sharing large files quickly and safely.</p>
<div class="app-features"><span class="app-feature">Expiry date</span><span class="app-feature">Download limit</span><span class="app-feature">Password protection</span></div>
<img src="/assets/gokapi-screenshot-1.webp" alt="Gokapi screenshot" class="app-screenshot">
<a href="/assets/gokapi-screenshot-1.webp" data-gallery="gokapi" class="app-shot-link"><img src="/assets/gokapi-screenshot-1.webp" alt="Gokapi screenshot" class="app-screenshot"></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Forceu/Gokapi" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -159,7 +163,10 @@
<div class="app-card-body">
<p class="app-description">A modern file and image sharing server with many features. Good for sharing screenshots, shortening links and keeping text snippets.</p>
<div class="app-features"><span class="app-feature">Screenshots</span><span class="app-feature">Link shortener</span><span class="app-feature">Gallery</span><span class="app-feature">API</span></div>
<img src="/assets/zipline-screenshot-1.webp" alt="Zipline screenshot" class="app-screenshot">
<a href="/assets/zipline-screenshot-1.webp" data-gallery="zipline" class="app-shot-link"><img src="/assets/zipline-screenshot-1.webp" alt="Zipline screenshot" class="app-screenshot"></a>
<a href="/assets/zipline-screenshot-2.webp" data-gallery="zipline" data-alt="Zipline screenshot 2" hidden></a>
<a href="/assets/zipline-screenshot-3.webp" data-gallery="zipline" data-alt="Zipline screenshot 3" hidden></a>
<a href="/assets/zipline-screenshot-4.webp" data-gallery="zipline" data-alt="Zipline screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/diced/zipline" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -175,7 +182,15 @@
<div class="app-card-body">
<p class="app-description">A full office suite in your browser. Edit documents, spreadsheets and presentations, with very good Microsoft Office compatibility.</p>
<div class="app-features"><span class="app-feature">Documents</span><span class="app-feature">Spreadsheets</span><span class="app-feature">Presentations</span><span class="app-feature">Collaboration</span></div>
<img src="/assets/onlyoffice-screenshot-1.webp" alt="OnlyOffice screenshot" class="app-screenshot">
<a href="/assets/onlyoffice-screenshot-1.webp" data-gallery="onlyoffice" class="app-shot-link"><img src="/assets/onlyoffice-screenshot-1.webp" alt="OnlyOffice screenshot" class="app-screenshot"></a>
<a href="/assets/onlyoffice-screenshot-2.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 2" hidden></a>
<a href="/assets/onlyoffice-screenshot-3.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 3" hidden></a>
<a href="/assets/onlyoffice-screenshot-4.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 4" hidden></a>
<a href="/assets/onlyoffice-screenshot-5.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 5" hidden></a>
<a href="/assets/onlyoffice-screenshot-6.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 6" hidden></a>
<a href="/assets/onlyoffice-screenshot-7.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 7" hidden></a>
<a href="/assets/onlyoffice-screenshot-8.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 8" hidden></a>
<a href="/assets/onlyoffice-screenshot-9.webp" data-gallery="onlyoffice" data-alt="OnlyOffice screenshot 9" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/ONLYOFFICE/DocumentServer" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -191,7 +206,8 @@
<div class="app-card-body">
<p class="app-description">A privacy-first PDF toolkit with more than 70 tools. Merge, split, convert, compress, OCR, encrypt and sign, all in the browser, with nothing sent to a server.</p>
<div class="app-features"><span class="app-feature">70+ tools</span><span class="app-feature">Client-side</span><span class="app-feature">OCR</span><span class="app-feature">Convert</span></div>
<img src="/assets/bentopdf-screenshot-1.webp" alt="BentoPDF screenshot" class="app-screenshot">
<a href="/assets/bentopdf-screenshot-1.webp" data-gallery="bentopdf" class="app-shot-link"><img src="/assets/bentopdf-screenshot-1.webp" alt="BentoPDF screenshot" class="app-screenshot"></a>
<a href="/assets/bentopdf-screenshot-2.webp" data-gallery="bentopdf" data-alt="BentoPDF screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/alam00000/bentopdf" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -207,7 +223,9 @@
<div class="app-card-body">
<p class="app-description">A clean, modern document archive. Automatic tags, e-mail import and OCR text recognition: a digital filing cabinet, simple and tidy.</p>
<div class="app-features"><span class="app-feature">Auto tags</span><span class="app-feature">E-mail import</span><span class="app-feature">OCR</span><span class="app-feature">Modern UI</span></div>
<img src="/assets/papra-screenshot-1.webp" alt="Papra screenshot" class="app-screenshot">
<a href="/assets/papra-screenshot-1.webp" data-gallery="papra" class="app-shot-link"><img src="/assets/papra-screenshot-1.webp" alt="Papra screenshot" class="app-screenshot"></a>
<a href="/assets/papra-screenshot-2.webp" data-gallery="papra" data-alt="Papra screenshot 2" hidden></a>
<a href="/assets/papra-screenshot-3.webp" data-gallery="papra" data-alt="Papra screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/papra-hq/papra" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -236,7 +254,10 @@
<div class="app-card-body">
<p class="app-description">A fast, modern photo and video backup. Automatic upload from your phone, face and object recognition, sharing and memories.</p>
<div class="app-features"><span class="app-feature">Auto backup</span><span class="app-feature">Face recognition</span><span class="app-feature">Map</span><span class="app-feature">Mobile app</span></div>
<img src="/assets/immich-screenshot-1.webp" alt="Immich screenshot" class="app-screenshot">
<a href="/assets/immich-screenshot-1.webp" data-gallery="immich" class="app-shot-link"><img src="/assets/immich-screenshot-1.webp" alt="Immich screenshot" class="app-screenshot"></a>
<a href="/assets/immich-screenshot-2.webp" data-gallery="immich" data-alt="Immich screenshot 2" hidden></a>
<a href="/assets/immich-screenshot-3.webp" data-gallery="immich" data-alt="Immich screenshot 3" hidden></a>
<a href="/assets/immich-screenshot-4.webp" data-gallery="immich" data-alt="Immich screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/immich-app/immich" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -252,7 +273,8 @@
<div class="app-card-body">
<p class="app-description">A free, open-source media server. Stream films, series and music from anywhere, to any device.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Transcoding</span><span class="app-feature">Mobile app</span><span class="app-feature">TV app</span></div>
<img src="/assets/jellyfin-screenshot-1.webp" alt="Jellyfin screenshot" class="app-screenshot">
<a href="/assets/jellyfin-screenshot-1.webp" data-gallery="jellyfin" class="app-shot-link"><img src="/assets/jellyfin-screenshot-1.webp" alt="Jellyfin screenshot" class="app-screenshot"></a>
<a href="/assets/jellyfin-screenshot-2.webp" data-gallery="jellyfin" data-alt="Jellyfin screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/jellyfin/jellyfin" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -268,7 +290,9 @@
<div class="app-card-body">
<p class="app-description">A popular media server with a polished interface. Films, series, music and photos in one place, with very good app support.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Plex Pass</span><span class="app-feature">Intro skip</span><span class="app-feature">Watch Together</span></div>
<img src="/assets/plex-screenshot-1.webp" alt="Plex screenshot" class="app-screenshot">
<a href="/assets/plex-screenshot-1.webp" data-gallery="plex" class="app-shot-link"><img src="/assets/plex-screenshot-1.webp" alt="Plex screenshot" class="app-screenshot"></a>
<a href="/assets/plex-screenshot-2.webp" data-gallery="plex" data-alt="Plex screenshot 2" hidden></a>
<a href="/assets/plex-screenshot-3.webp" data-gallery="plex" data-alt="Plex screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://www.plex.tv" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Website</a>
@@ -284,7 +308,8 @@
<div class="app-card-body">
<p class="app-description">A personal media server with live TV and DVR support. An organised library, remote access, and sync for offline playback.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Live TV</span><span class="app-feature">DVR</span><span class="app-feature">Sync</span></div>
<img src="/assets/emby-screenshot-1.webp" alt="Emby screenshot" class="app-screenshot">
<a href="/assets/emby-screenshot-1.webp" data-gallery="emby" class="app-shot-link"><img src="/assets/emby-screenshot-1.webp" alt="Emby screenshot" class="app-screenshot"></a>
<a href="/assets/emby-screenshot-2.webp" data-gallery="emby" data-alt="Emby screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://emby.media" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Website</a>
@@ -300,7 +325,8 @@
<div class="app-card-body">
<p class="app-description">A light, modern music server. Stream your own music collection from anywhere; Subsonic-compatible, with many mobile apps.</p>
<div class="app-features"><span class="app-feature">Streaming</span><span class="app-feature">Subsonic API</span><span class="app-feature">Mobile apps</span><span class="app-feature">Playlists</span></div>
<img src="/assets/navidrome-screenshot-1.webp" alt="Navidrome screenshot" class="app-screenshot">
<a href="/assets/navidrome-screenshot-1.webp" data-gallery="navidrome" class="app-shot-link"><img src="/assets/navidrome-screenshot-1.webp" alt="Navidrome screenshot" class="app-screenshot"></a>
<a href="/assets/navidrome-screenshot-2.webp" data-gallery="navidrome" data-alt="Navidrome screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/navidrome/navidrome" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -316,7 +342,10 @@
<div class="app-card-body">
<p class="app-description">An audiobook and podcast server. Details fetched for you, carry on where you stopped, and its own mobile apps.</p>
<div class="app-features"><span class="app-feature">Audiobooks</span><span class="app-feature">Podcasts</span><span class="app-feature">Sync</span><span class="app-feature">Mobile app</span></div>
<img src="/assets/audiobookshelf-screenshot-1.webp" alt="Audiobookshelf screenshot" class="app-screenshot">
<a href="/assets/audiobookshelf-screenshot-1.webp" data-gallery="audiobookshelf" class="app-shot-link"><img src="/assets/audiobookshelf-screenshot-1.webp" alt="Audiobookshelf screenshot" class="app-screenshot"></a>
<a href="/assets/audiobookshelf-screenshot-2.webp" data-gallery="audiobookshelf" data-alt="Audiobookshelf screenshot 2" hidden></a>
<a href="/assets/audiobookshelf-screenshot-3.webp" data-gallery="audiobookshelf" data-alt="Audiobookshelf screenshot 3" hidden></a>
<a href="/assets/audiobookshelf-screenshot-4.webp" data-gallery="audiobookshelf" data-alt="Audiobookshelf screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/advplyr/audiobookshelf" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -332,7 +361,9 @@
<div class="app-card-body">
<p class="app-description">Download a video or a playlist from its link, as video or audio only. The downloads go to your drive; you see them in the file browser and your media player. Only your family members reach it.</p>
<div class="app-features"><span class="app-feature">Video and audio</span><span class="app-feature">Playlists</span><span class="app-feature">To your drive</span><span class="app-feature">Family only</span></div>
<img src="/assets/metube-screenshot-1.webp" alt="MeTube screenshot" class="app-screenshot">
<a href="/assets/metube-screenshot-1.webp" data-gallery="metube" class="app-shot-link"><img src="/assets/metube-screenshot-1.webp" alt="MeTube screenshot" class="app-screenshot"></a>
<a href="/assets/metube-screenshot-2.webp" data-gallery="metube" data-alt="MeTube screenshot 2" hidden></a>
<a href="/assets/metube-screenshot-3.webp" data-gallery="metube" data-alt="MeTube screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/alexta69/metube" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -348,7 +379,8 @@
<div class="app-card-body">
<p class="app-description">A web interface for your Calibre library. Browse, read and download your e-books from anywhere, with Kindle support.</p>
<div class="app-features"><span class="app-feature">E-books</span><span class="app-feature">Send to Kindle</span><span class="app-feature">OPDS</span><span class="app-feature">Reader</span></div>
<img src="/assets/calibre-web-screenshot-1.webp" alt="Calibre-Web Automated screenshot" class="app-screenshot">
<a href="/assets/calibre-web-screenshot-1.webp" data-gallery="calibre-web" class="app-shot-link"><img src="/assets/calibre-web-screenshot-1.webp" alt="Calibre-Web Automated screenshot" class="app-screenshot"></a>
<a href="/assets/calibre-web-screenshot-2.webp" data-gallery="calibre-web" data-alt="Calibre-Web Automated screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/crocodilestick/Calibre-Web-Automated" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -364,7 +396,7 @@
<div class="app-card-body">
<p class="app-description">Manage and read comics, manga and magazines. A modern web reader, OPDS support and popular mobile apps.</p>
<div class="app-features"><span class="app-feature">Web reader</span><span class="app-feature">OPDS</span><span class="app-feature">Metadata</span><span class="app-feature">Tachiyomi</span></div>
<img src="/assets/komga-screenshot-1.webp" alt="Komga screenshot" class="app-screenshot">
<a href="/assets/komga-screenshot-1.webp" data-gallery="komga" class="app-shot-link"><img src="/assets/komga-screenshot-1.webp" alt="Komga screenshot" class="app-screenshot"></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/gotson/komga" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -380,7 +412,9 @@
<div class="app-card-body">
<p class="app-description">E-books and comics in a tidy library, with covers and details. Read in the browser with your progress saved; Kobo and KOReader sync, and an OPDS catalog for reader apps. Only your family members reach it, each with their own sign-in.</p>
<div class="app-features"><span class="app-feature">Browser reader</span><span class="app-feature">Kobo sync</span><span class="app-feature">KOReader</span><span class="app-feature">OPDS</span></div>
<img src="/assets/grimmory-screenshot-1.webp" alt="Grimmory screenshot" class="app-screenshot">
<a href="/assets/grimmory-screenshot-1.webp" data-gallery="grimmory" class="app-shot-link"><img src="/assets/grimmory-screenshot-1.webp" alt="Grimmory screenshot" class="app-screenshot"></a>
<a href="/assets/grimmory-screenshot-2.webp" data-gallery="grimmory" data-alt="Grimmory screenshot 2" hidden></a>
<a href="/assets/grimmory-screenshot-3.webp" data-gallery="grimmory" data-alt="Grimmory screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/grimmory-tools/grimmory" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -396,7 +430,9 @@
<div class="app-card-body">
<p class="app-description">Downloads and organises series for you. Follow your favourite series and new episodes are downloaded automatically.</p>
<div class="app-features"><span class="app-feature">Auto download</span><span class="app-feature">Calendar</span><span class="app-feature">Quality profiles</span><span class="app-feature">Integrations</span></div>
<img src="/assets/sonarr-screenshot-1.webp" alt="Sonarr screenshot" class="app-screenshot">
<a href="/assets/sonarr-screenshot-1.webp" data-gallery="sonarr" class="app-shot-link"><img src="/assets/sonarr-screenshot-1.webp" alt="Sonarr screenshot" class="app-screenshot"></a>
<a href="/assets/sonarr-screenshot-2.webp" data-gallery="sonarr" data-alt="Sonarr screenshot 2" hidden></a>
<a href="/assets/sonarr-screenshot-3.webp" data-gallery="sonarr" data-alt="Sonarr screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Sonarr/Sonarr" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -412,7 +448,8 @@
<div class="app-card-body">
<p class="app-description">Downloads and organises films for you. Make a wish list and the films arrive in your library on their own.</p>
<div class="app-features"><span class="app-feature">Wish list</span><span class="app-feature">Auto download</span><span class="app-feature">Quality profiles</span><span class="app-feature">Integrations</span></div>
<img src="/assets/radarr-screenshot-1.webp" alt="Radarr screenshot" class="app-screenshot">
<a href="/assets/radarr-screenshot-1.webp" data-gallery="radarr" class="app-shot-link"><img src="/assets/radarr-screenshot-1.webp" alt="Radarr screenshot" class="app-screenshot"></a>
<a href="/assets/radarr-screenshot-2.webp" data-gallery="radarr" data-alt="Radarr screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Radarr/Radarr" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -428,7 +465,8 @@
<div class="app-card-body">
<p class="app-description">Ask for films and series the easy way. Family and friends can request titles, and the system downloads them for you.</p>
<div class="app-features"><span class="app-feature">Requests</span><span class="app-feature">Users</span><span class="app-feature">Notifications</span><span class="app-feature">Integrations</span></div>
<img src="/assets/seerr-screenshot-1.webp" alt="Seerr screenshot" class="app-screenshot">
<a href="/assets/seerr-screenshot-1.webp" data-gallery="seerr" class="app-shot-link"><img src="/assets/seerr-screenshot-1.webp" alt="Seerr screenshot" class="app-screenshot"></a>
<a href="/assets/seerr-screenshot-2.webp" data-gallery="seerr" data-alt="Seerr screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Fallenbagel/jellyseerr" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -444,7 +482,8 @@
<div class="app-card-body">
<p class="app-description">A good-looking web interface for your retro game ROM collection. Details and cover art fetched for you, sorted by platform, and playable in the browser.</p>
<div class="app-features"><span class="app-feature">ROM library</span><span class="app-feature">Metadata</span><span class="app-feature">EmulatorJS</span><span class="app-feature">IGDB</span></div>
<img src="/assets/romm-screenshot-1.webp" alt="RoMM screenshot" class="app-screenshot">
<a href="/assets/romm-screenshot-1.webp" data-gallery="romm" class="app-shot-link"><img src="/assets/romm-screenshot-1.webp" alt="RoMM screenshot" class="app-screenshot"></a>
<a href="/assets/romm-screenshot-2.webp" data-gallery="romm" data-alt="RoMM screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/rommapp/romm" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -460,7 +499,9 @@
<div class="app-card-body">
<p class="app-description">A modern web manager for Minecraft servers. Run several servers from one interface, with automatic backups, player statistics and full remote access.</p>
<div class="app-features"><span class="app-feature">Multi-server</span><span class="app-feature">Backups</span><span class="app-feature">Console</span><span class="app-feature">Statistics</span></div>
<img src="/assets/crafty-screenshot-1.webp" alt="Crafty Controller screenshot" class="app-screenshot">
<a href="/assets/crafty-screenshot-1.webp" data-gallery="crafty" class="app-shot-link"><img src="/assets/crafty-screenshot-1.webp" alt="Crafty Controller screenshot" class="app-screenshot"></a>
<a href="/assets/crafty-screenshot-2.webp" data-gallery="crafty" data-alt="Crafty Controller screenshot 2" hidden></a>
<a href="/assets/crafty-screenshot-3.webp" data-gallery="crafty" data-alt="Crafty Controller screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://gitlab.com/crafty-controller/crafty-4" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -489,7 +530,12 @@
<div class="app-card-body">
<p class="app-description">The world's most popular open-source smart home platform. More than 3000 integrations, local control and automations, with no cloud and full privacy.</p>
<div class="app-features"><span class="app-feature">3000+ integrations</span><span class="app-feature">Automations</span><span class="app-feature">Local control</span><span class="app-feature">Mobile app</span></div>
<img src="/assets/homeassistant-screenshot-1.webp" alt="Home Assistant screenshot" class="app-screenshot">
<a href="/assets/homeassistant-screenshot-1.webp" data-gallery="homeassistant" class="app-shot-link"><img src="/assets/homeassistant-screenshot-1.webp" alt="Home Assistant screenshot" class="app-screenshot"></a>
<a href="/assets/homeassistant-screenshot-2.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 2" hidden></a>
<a href="/assets/homeassistant-screenshot-3.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 3" hidden></a>
<a href="/assets/homeassistant-screenshot-4.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 4" hidden></a>
<a href="/assets/homeassistant-screenshot-5.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 5" hidden></a>
<a href="/assets/homeassistant-screenshot-6.webp" data-gallery="homeassistant" data-alt="Home Assistant screenshot 6" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/home-assistant/core" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -505,7 +551,11 @@
<div class="app-card-body">
<p class="app-description">Visual workflow automation in the style of Zapier or Make. Connect any service and build automations without code, on your own server.</p>
<div class="app-features"><span class="app-feature">400+ integrations</span><span class="app-feature">Visual editor</span><span class="app-feature">AI features</span><span class="app-feature">Webhooks</span></div>
<img src="/assets/n8n-screenshot-1.webp" alt="n8n screenshot" class="app-screenshot">
<a href="/assets/n8n-screenshot-1.webp" data-gallery="n8n" class="app-shot-link"><img src="/assets/n8n-screenshot-1.webp" alt="n8n screenshot" class="app-screenshot"></a>
<a href="/assets/n8n-screenshot-2.webp" data-gallery="n8n" data-alt="n8n screenshot 2" hidden></a>
<a href="/assets/n8n-screenshot-3.webp" data-gallery="n8n" data-alt="n8n screenshot 3" hidden></a>
<a href="/assets/n8n-screenshot-4.webp" data-gallery="n8n" data-alt="n8n screenshot 4" hidden></a>
<a href="/assets/n8n-screenshot-5.webp" data-gallery="n8n" data-alt="n8n screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/n8n-io/n8n" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -521,7 +571,9 @@
<div class="app-card-body">
<p class="app-description">Keep your recipes, plan meals and make a shopping list. Import recipes from the web and share them with your family.</p>
<div class="app-features"><span class="app-feature">Recipe import</span><span class="app-feature">Meal planning</span><span class="app-feature">Shopping list</span><span class="app-feature">Sharing</span></div>
<img src="/assets/tandoor-screenshot-1.webp" alt="Tandoor Recipes screenshot" class="app-screenshot">
<a href="/assets/tandoor-screenshot-1.webp" data-gallery="tandoor" class="app-shot-link"><img src="/assets/tandoor-screenshot-1.webp" alt="Tandoor Recipes screenshot" class="app-screenshot"></a>
<a href="/assets/tandoor-screenshot-2.webp" data-gallery="tandoor" data-alt="Tandoor Recipes screenshot 2" hidden></a>
<a href="/assets/tandoor-screenshot-3.webp" data-gallery="tandoor" data-alt="Tandoor Recipes screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/TandoorRecipes/recipes" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -537,7 +589,9 @@
<div class="app-card-body">
<p class="app-description">A recipe manager and meal planner for the household. Import a recipe from a web page, plan the week's meals and get a shopping list, and share recipes with the family; the interface speaks English and Hungarian among others.</p>
<div class="app-features"><span class="app-feature">Recipe import</span><span class="app-feature">Weekly menu</span><span class="app-feature">Shopping list</span><span class="app-feature">Multilingual</span></div>
<img src="/assets/mealie-screenshot-1.webp" alt="Mealie screenshot" class="app-screenshot">
<a href="/assets/mealie-screenshot-1.webp" data-gallery="mealie" class="app-shot-link"><img src="/assets/mealie-screenshot-1.webp" alt="Mealie screenshot" class="app-screenshot"></a>
<a href="/assets/mealie-screenshot-2.webp" data-gallery="mealie" data-alt="Mealie screenshot 2" hidden></a>
<a href="/assets/mealie-screenshot-3.webp" data-gallery="mealie" data-alt="Mealie screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/mealie-recipes/mealie" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -553,7 +607,9 @@
<div class="app-card-body">
<p class="app-description">Import recipes from six Hungarian sites (mindmegette.hu, streetkitchen.hu, nosalty.hu, sobors.hu, kiskegyed.hu, gastrohobbi.hu) into Mealie and Tandoor, one at a time or in bulk, and edit them before they are saved.</p>
<div class="app-features"><span class="app-feature">6 Hungarian sites</span><span class="app-feature">Bulk import</span><span class="app-feature">Mealie</span><span class="app-feature">Tandoor</span></div>
<img src="/assets/recipe-importer-screenshot-1.webp" alt="Recipe Importer screenshot" class="app-screenshot">
<a href="/assets/recipe-importer-screenshot-1.webp" data-gallery="recipe-importer" class="app-shot-link"><img src="/assets/recipe-importer-screenshot-1.webp" alt="Recipe Importer screenshot" class="app-screenshot"></a>
<a href="/assets/recipe-importer-screenshot-2.webp" data-gallery="recipe-importer" data-alt="Recipe Importer screenshot 2" hidden></a>
<a href="/assets/recipe-importer-screenshot-3.webp" data-gallery="recipe-importer" data-alt="Recipe Importer screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<span class="open-source-badge" style="color: var(--warn);"><img src="/assets/checkmark-yellow.svg" alt="">Felhom's own</span>
@@ -568,7 +624,9 @@
<div class="app-card-body">
<p class="app-description">A wish list you can share, for Christmas, birthdays and other occasions. The family can reserve gifts, so nobody buys the same present twice.</p>
<div class="app-features"><span class="app-feature">Groups</span><span class="app-feature">Reservations</span><span class="app-feature">Link import</span><span class="app-feature">PWA</span></div>
<img src="/assets/wishlist-screenshot-1.webp" alt="Wishlist screenshot" class="app-screenshot">
<a href="/assets/wishlist-screenshot-1.webp" data-gallery="wishlist" class="app-shot-link"><img src="/assets/wishlist-screenshot-1.webp" alt="Wishlist screenshot" class="app-screenshot"></a>
<a href="/assets/wishlist-screenshot-2.webp" data-gallery="wishlist" data-alt="Wishlist screenshot 2" hidden></a>
<a href="/assets/wishlist-screenshot-3.webp" data-gallery="wishlist" data-alt="Wishlist screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/cmintey/wishlist" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -584,7 +642,9 @@
<div class="app-card-body">
<p class="app-description">Keep track of what you own: sorted by location, tag and category, with warranties and what you paid. Scan a barcode to add something quickly, and have the list ready for an insurance claim.</p>
<div class="app-features"><span class="app-feature">Inventory</span><span class="app-feature">Warranties</span><span class="app-feature">Barcode</span><span class="app-feature">Tags</span></div>
<img src="/assets/homebox-screenshot-1.webp" alt="Homebox screenshot" class="app-screenshot">
<a href="/assets/homebox-screenshot-1.webp" data-gallery="homebox" class="app-shot-link"><img src="/assets/homebox-screenshot-1.webp" alt="Homebox screenshot" class="app-screenshot"></a>
<a href="/assets/homebox-screenshot-2.webp" data-gallery="homebox" data-alt="Homebox screenshot 2" hidden></a>
<a href="/assets/homebox-screenshot-3.webp" data-gallery="homebox" data-alt="Homebox screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/sysadminsmedia/homebox" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -600,7 +660,10 @@
<div class="app-card-body">
<p class="app-description">A web platform for family trees and genealogy. Build your family tree, add photos and documents, and share it with your family safely.</p>
<div class="app-features"><span class="app-feature">Family tree</span><span class="app-feature">GEDCOM</span><span class="app-feature">Collaboration</span><span class="app-feature">Sync</span></div>
<img src="/assets/grampsweb-screenshot-1.webp" alt="Gramps Web screenshot" class="app-screenshot">
<a href="/assets/grampsweb-screenshot-1.webp" data-gallery="grampsweb" class="app-shot-link"><img src="/assets/grampsweb-screenshot-1.webp" alt="Gramps Web screenshot" class="app-screenshot"></a>
<a href="/assets/grampsweb-screenshot-2.webp" data-gallery="grampsweb" data-alt="Gramps Web screenshot 2" hidden></a>
<a href="/assets/grampsweb-screenshot-3.webp" data-gallery="grampsweb" data-alt="Gramps Web screenshot 3" hidden></a>
<a href="/assets/grampsweb-screenshot-4.webp" data-gallery="grampsweb" data-alt="Gramps Web screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/gramps-project/gramps-web" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -616,7 +679,9 @@
<div class="app-card-body">
<p class="app-description">Log what you eat and how many calories it comes to, track your weight and measurements on a graph, and record workouts. Set nutrition targets (protein, carbohydrate, fat) and follow them.</p>
<div class="app-features"><span class="app-feature">Calorie counter</span><span class="app-feature">Weight</span><span class="app-feature">Workouts</span><span class="app-feature">Nutrition targets</span></div>
<img src="/assets/sparkyfitness-screenshot-1.webp" alt="SparkyFitness screenshot" class="app-screenshot">
<a href="/assets/sparkyfitness-screenshot-1.webp" data-gallery="sparkyfitness" class="app-shot-link"><img src="/assets/sparkyfitness-screenshot-1.webp" alt="SparkyFitness screenshot" class="app-screenshot"></a>
<a href="/assets/sparkyfitness-screenshot-2.webp" data-gallery="sparkyfitness" data-alt="SparkyFitness screenshot 2" hidden></a>
<a href="/assets/sparkyfitness-screenshot-3.webp" data-gallery="sparkyfitness" data-alt="SparkyFitness screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/CodeWithCJ/SparkyFitness" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -632,7 +697,9 @@
<div class="app-card-body">
<p class="app-description">Local-first personal finance. Plan a budget, track transactions and set money goals.</p>
<div class="app-features"><span class="app-feature">Budget</span><span class="app-feature">Sync</span><span class="app-feature">Bank import</span><span class="app-feature">Reports</span></div>
<img src="/assets/actualbudget-screenshot-1.webp" alt="Actual Budget screenshot" class="app-screenshot">
<a href="/assets/actualbudget-screenshot-1.webp" data-gallery="actualbudget" class="app-shot-link"><img src="/assets/actualbudget-screenshot-1.webp" alt="Actual Budget screenshot" class="app-screenshot"></a>
<a href="/assets/actualbudget-screenshot-2.webp" data-gallery="actualbudget" data-alt="Actual Budget screenshot 2" hidden></a>
<a href="/assets/actualbudget-screenshot-3.webp" data-gallery="actualbudget" data-alt="Actual Budget screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/actualbudget/actual" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -648,7 +715,11 @@
<div class="app-card-body">
<p class="app-description">Record your trips and adventures. A map view, photos and statistics about the places you have been.</p>
<div class="app-features"><span class="app-feature">Map</span><span class="app-feature">Photos</span><span class="app-feature">Statistics</span><span class="app-feature">Sharing</span></div>
<img src="/assets/adventurelog-screenshot-1.webp" alt="AdventureLog screenshot" class="app-screenshot">
<a href="/assets/adventurelog-screenshot-1.webp" data-gallery="adventurelog" class="app-shot-link"><img src="/assets/adventurelog-screenshot-1.webp" alt="AdventureLog screenshot" class="app-screenshot"></a>
<a href="/assets/adventurelog-screenshot-2.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 2" hidden></a>
<a href="/assets/adventurelog-screenshot-3.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 3" hidden></a>
<a href="/assets/adventurelog-screenshot-4.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 4" hidden></a>
<a href="/assets/adventurelog-screenshot-5.webp" data-gallery="adventurelog" data-alt="AdventureLog screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/seanmorley15/AdventureLog" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -664,7 +735,10 @@
<div class="app-card-body">
<p class="app-description">Plan hikes and routes and keep your GPX files. A map with contour lines, and route statistics.</p>
<div class="app-features"><span class="app-feature">GPX import</span><span class="app-feature">Maps</span><span class="app-feature">Elevation</span><span class="app-feature">Routes</span></div>
<img src="/assets/wanderer-screenshot-1.webp" alt="Wanderer screenshot" class="app-screenshot">
<a href="/assets/wanderer-screenshot-1.webp" data-gallery="wanderer" class="app-shot-link"><img src="/assets/wanderer-screenshot-1.webp" alt="Wanderer screenshot" class="app-screenshot"></a>
<a href="/assets/wanderer-screenshot-2.webp" data-gallery="wanderer" data-alt="Wanderer screenshot 2" hidden></a>
<a href="/assets/wanderer-screenshot-3.webp" data-gallery="wanderer" data-alt="Wanderer screenshot 3" hidden></a>
<a href="/assets/wanderer-screenshot-4.webp" data-gallery="wanderer" data-alt="Wanderer screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Flomp/wanderer" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -680,7 +754,9 @@
<div class="app-card-body">
<p class="app-description">Your own location history on a map: your phone sends where you have been to your own server. A map, statistics and trips; bring your old data from a Google Takeout, GPX or GeoJSON file.</p>
<div class="app-features"><span class="app-feature">Map</span><span class="app-feature">Statistics</span><span class="app-feature">Takeout import</span><span class="app-feature">Mobile app</span></div>
<img src="/assets/dawarich-screenshot-1.webp" alt="Dawarich screenshot" class="app-screenshot">
<a href="/assets/dawarich-screenshot-1.webp" data-gallery="dawarich" class="app-shot-link"><img src="/assets/dawarich-screenshot-1.webp" alt="Dawarich screenshot" class="app-screenshot"></a>
<a href="/assets/dawarich-screenshot-2.webp" data-gallery="dawarich" data-alt="Dawarich screenshot 2" hidden></a>
<a href="/assets/dawarich-screenshot-3.webp" data-gallery="dawarich" data-alt="Dawarich screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Freika/dawarich" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -696,7 +772,12 @@
<div class="app-card-body">
<p class="app-description">An open-source Calendly alternative. Easy appointment booking with clients, calendar integrations and automatic reminders.</p>
<div class="app-features"><span class="app-feature">Booking page</span><span class="app-feature">Calendar sync</span><span class="app-feature">Teams</span><span class="app-feature">Reminders</span></div>
<img src="/assets/calcom-screenshot-1.webp" alt="Cal.com screenshot" class="app-screenshot">
<a href="/assets/calcom-screenshot-1.webp" data-gallery="calcom" class="app-shot-link"><img src="/assets/calcom-screenshot-1.webp" alt="Cal.com screenshot" class="app-screenshot"></a>
<a href="/assets/calcom-screenshot-2.webp" data-gallery="calcom" data-alt="Cal.com screenshot 2" hidden></a>
<a href="/assets/calcom-screenshot-3.webp" data-gallery="calcom" data-alt="Cal.com screenshot 3" hidden></a>
<a href="/assets/calcom-screenshot-4.webp" data-gallery="calcom" data-alt="Cal.com screenshot 4" hidden></a>
<a href="/assets/calcom-screenshot-5.webp" data-gallery="calcom" data-alt="Cal.com screenshot 5" hidden></a>
<a href="/assets/calcom-screenshot-6.webp" data-gallery="calcom" data-alt="Cal.com screenshot 6" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/calcom/cal.com" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -725,7 +806,10 @@
<div class="app-card-body">
<p class="app-description">An open-source Todoist alternative. Tasks, projects and deadlines, in Kanban, Gantt and list views. Reminders and team work.</p>
<div class="app-features"><span class="app-feature">Kanban</span><span class="app-feature">Gantt</span><span class="app-feature">Reminders</span><span class="app-feature">Teams</span></div>
<img src="/assets/vikunja-screenshot-1.webp" alt="Vikunja screenshot" class="app-screenshot">
<a href="/assets/vikunja-screenshot-1.webp" data-gallery="vikunja" class="app-shot-link"><img src="/assets/vikunja-screenshot-1.webp" alt="Vikunja screenshot" class="app-screenshot"></a>
<a href="/assets/vikunja-screenshot-2.webp" data-gallery="vikunja" data-alt="Vikunja screenshot 2" hidden></a>
<a href="/assets/vikunja-screenshot-3.webp" data-gallery="vikunja" data-alt="Vikunja screenshot 3" hidden></a>
<a href="/assets/vikunja-screenshot-4.webp" data-gallery="vikunja" data-alt="Vikunja screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/go-vikunja/vikunja" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -741,7 +825,9 @@
<div class="app-card-body">
<p class="app-description">Your phone calendar and contacts on your own server, not with Google or Apple. A shared family calendar; on Android DAVx5, on iPhone and Mac the built-in calendar syncs with it.</p>
<div class="app-features"><span class="app-feature">CalDAV</span><span class="app-feature">CardDAV</span><span class="app-feature">Family calendar</span><span class="app-feature">Thunderbird</span></div>
<img src="/assets/radicale-screenshot-1.webp" alt="Radicale screenshot" class="app-screenshot">
<a href="/assets/radicale-screenshot-1.webp" data-gallery="radicale" class="app-shot-link"><img src="/assets/radicale-screenshot-1.webp" alt="Radicale screenshot" class="app-screenshot"></a>
<a href="/assets/radicale-screenshot-2.webp" data-gallery="radicale" data-alt="Radicale screenshot 2" hidden></a>
<a href="/assets/radicale-screenshot-3.webp" data-gallery="radicale" data-alt="Radicale screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Kozea/Radicale" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -757,7 +843,11 @@
<div class="app-card-body">
<p class="app-description">Professional time tracking for freelancers and teams. Projects, clients, reports and invoice export in one system.</p>
<div class="app-features"><span class="app-feature">Projects</span><span class="app-feature">Reports</span><span class="app-feature">Export</span><span class="app-feature">Invoicing</span></div>
<img src="/assets/kimai-screenshot-1.webp" alt="Kimai screenshot" class="app-screenshot">
<a href="/assets/kimai-screenshot-1.webp" data-gallery="kimai" class="app-shot-link"><img src="/assets/kimai-screenshot-1.webp" alt="Kimai screenshot" class="app-screenshot"></a>
<a href="/assets/kimai-screenshot-2.webp" data-gallery="kimai" data-alt="Kimai screenshot 2" hidden></a>
<a href="/assets/kimai-screenshot-3.webp" data-gallery="kimai" data-alt="Kimai screenshot 3" hidden></a>
<a href="/assets/kimai-screenshot-4.webp" data-gallery="kimai" data-alt="Kimai screenshot 4" hidden></a>
<a href="/assets/kimai-screenshot-5.webp" data-gallery="kimai" data-alt="Kimai screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/kimai/kimai" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -773,7 +863,8 @@
<div class="app-card-body">
<p class="app-description">Find a time for a meeting or an event, the easy way. A Doodle alternative: people vote without an account, and time zones are handled.</p>
<div class="app-features"><span class="app-feature">Polls</span><span class="app-feature">No sign-up</span><span class="app-feature">Time zones</span><span class="app-feature">Notifications</span></div>
<img src="/assets/rallly-screenshot-1.webp" alt="Rallly screenshot" class="app-screenshot">
<a href="/assets/rallly-screenshot-1.webp" data-gallery="rallly" class="app-shot-link"><img src="/assets/rallly-screenshot-1.webp" alt="Rallly screenshot" class="app-screenshot"></a>
<a href="/assets/rallly-screenshot-2.webp" data-gallery="rallly" data-alt="Rallly screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/lukevella/rallly" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -789,7 +880,11 @@
<div class="app-card-body">
<p class="app-description">Live polls, questions and word clouds for presentations. A Mentimeter and AhaSlides alternative that makes your talks interactive.</p>
<div class="app-features"><span class="app-feature">Live polls</span><span class="app-feature">Questions</span><span class="app-feature">Word cloud</span><span class="app-feature">Reactions</span></div>
<img src="/assets/claper-screenshot-1.webp" alt="Claper screenshot" class="app-screenshot">
<a href="/assets/claper-screenshot-1.webp" data-gallery="claper" class="app-shot-link"><img src="/assets/claper-screenshot-1.webp" alt="Claper screenshot" class="app-screenshot"></a>
<a href="/assets/claper-screenshot-2.webp" data-gallery="claper" data-alt="Claper screenshot 2" hidden></a>
<a href="/assets/claper-screenshot-3.webp" data-gallery="claper" data-alt="Claper screenshot 3" hidden></a>
<a href="/assets/claper-screenshot-4.webp" data-gallery="claper" data-alt="Claper screenshot 4" hidden></a>
<a href="/assets/claper-screenshot-5.webp" data-gallery="claper" data-alt="Claper screenshot 5" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/ClaperCo/Claper" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -805,7 +900,10 @@
<div class="app-card-body">
<p class="app-description">A modern publishing platform for bloggers and creators. Good-looking themes, a built-in newsletter, and members and subscriptions.</p>
<div class="app-features"><span class="app-feature">Blog</span><span class="app-feature">Newsletter</span><span class="app-feature">Members</span><span class="app-feature">SEO</span></div>
<img src="/assets/ghost-screenshot-1.webp" alt="Ghost screenshot" class="app-screenshot">
<a href="/assets/ghost-screenshot-1.webp" data-gallery="ghost" class="app-shot-link"><img src="/assets/ghost-screenshot-1.webp" alt="Ghost screenshot" class="app-screenshot"></a>
<a href="/assets/ghost-screenshot-2.webp" data-gallery="ghost" data-alt="Ghost screenshot 2" hidden></a>
<a href="/assets/ghost-screenshot-3.webp" data-gallery="ghost" data-alt="Ghost screenshot 3" hidden></a>
<a href="/assets/ghost-screenshot-4.webp" data-gallery="ghost" data-alt="Ghost screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/TryGhost/Ghost" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -821,7 +919,9 @@
<div class="app-card-body">
<p class="app-description">Scan your paper documents and stop worrying about them. OCR, automatic sorting and full-text search.</p>
<div class="app-features"><span class="app-feature">OCR</span><span class="app-feature">Auto sorting</span><span class="app-feature">Search</span><span class="app-feature">Tags</span></div>
<img src="/assets/paperless-ngx-screenshot-1.webp" alt="Paperless-ngx screenshot" class="app-screenshot">
<a href="/assets/paperless-ngx-screenshot-1.webp" data-gallery="paperless-ngx" class="app-shot-link"><img src="/assets/paperless-ngx-screenshot-1.webp" alt="Paperless-ngx screenshot" class="app-screenshot"></a>
<a href="/assets/paperless-ngx-screenshot-2.webp" data-gallery="paperless-ngx" data-alt="Paperless-ngx screenshot 2" hidden></a>
<a href="/assets/paperless-ngx-screenshot-3.webp" data-gallery="paperless-ngx" data-alt="Paperless-ngx screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/paperless-ngx/paperless-ngx" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -837,7 +937,9 @@
<div class="app-card-body">
<p class="app-description">A simple self-hosted wiki. Arrange what you know into books, chapters and pages that are easy to search.</p>
<div class="app-features"><span class="app-feature">WYSIWYG</span><span class="app-feature">Books</span><span class="app-feature">Search</span><span class="app-feature">Permissions</span></div>
<img src="/assets/bookstack-screenshot-1.webp" alt="BookStack screenshot" class="app-screenshot">
<a href="/assets/bookstack-screenshot-1.webp" data-gallery="bookstack" class="app-shot-link"><img src="/assets/bookstack-screenshot-1.webp" alt="BookStack screenshot" class="app-screenshot"></a>
<a href="/assets/bookstack-screenshot-2.webp" data-gallery="bookstack" data-alt="BookStack screenshot 2" hidden></a>
<a href="/assets/bookstack-screenshot-3.webp" data-gallery="bookstack" data-alt="BookStack screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/BookStackApp/BookStack" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -853,7 +955,8 @@
<div class="app-card-body">
<p class="app-description">A good-looking wiki and knowledge base for teams. Markdown, real-time collaboration and structured documentation.</p>
<div class="app-features"><span class="app-feature">Markdown</span><span class="app-feature">Collaboration</span><span class="app-feature">Search</span><span class="app-feature">Integrations</span></div>
<img src="/assets/outline-screenshot-1.webp" alt="Outline screenshot" class="app-screenshot">
<a href="/assets/outline-screenshot-1.webp" data-gallery="outline" class="app-shot-link"><img src="/assets/outline-screenshot-1.webp" alt="Outline screenshot" class="app-screenshot"></a>
<a href="/assets/outline-screenshot-2.webp" data-gallery="outline" data-alt="Outline screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/outline/outline" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -869,7 +972,9 @@
<div class="app-card-body">
<p class="app-description">A modern wiki and documentation platform with a Notion-like block editor. Spaces and pages in a tree, several people editing at once, and search across all of it.</p>
<div class="app-features"><span class="app-feature">Block editor</span><span class="app-feature">Co-editing</span><span class="app-feature">Search</span><span class="app-feature">Tables</span></div>
<img src="/assets/docmost-screenshot-1.webp" alt="Docmost screenshot" class="app-screenshot">
<a href="/assets/docmost-screenshot-1.webp" data-gallery="docmost" class="app-shot-link"><img src="/assets/docmost-screenshot-1.webp" alt="Docmost screenshot" class="app-screenshot"></a>
<a href="/assets/docmost-screenshot-2.webp" data-gallery="docmost" data-alt="Docmost screenshot 2" hidden></a>
<a href="/assets/docmost-screenshot-3.webp" data-gallery="docmost" data-alt="Docmost screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/docmost/docmost" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -885,7 +990,9 @@
<div class="app-card-body">
<p class="app-description">Bookmarks, articles, notes and images in one place. Karakeep downloads and keeps the content of the pages you save, even if a page disappears later. Full-text search, a browser extension and a phone app.</p>
<div class="app-features"><span class="app-feature">Page saving</span><span class="app-feature">Search</span><span class="app-feature">Browser extension</span><span class="app-feature">Mobile app</span></div>
<img src="/assets/karakeep-screenshot-1.webp" alt="Karakeep screenshot" class="app-screenshot">
<a href="/assets/karakeep-screenshot-1.webp" data-gallery="karakeep" class="app-shot-link"><img src="/assets/karakeep-screenshot-1.webp" alt="Karakeep screenshot" class="app-screenshot"></a>
<a href="/assets/karakeep-screenshot-2.webp" data-gallery="karakeep" data-alt="Karakeep screenshot 2" hidden></a>
<a href="/assets/karakeep-screenshot-3.webp" data-gallery="karakeep" data-alt="Karakeep screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/karakeep-app/karakeep" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -901,7 +1008,8 @@
<div class="app-card-body">
<p class="app-description">A minimal, encrypted pastebin. The server cannot see what you share, which makes it right for sending sensitive text safely.</p>
<div class="app-features"><span class="app-feature">E2E encryption</span><span class="app-feature">Expiry</span><span class="app-feature">Burn after reading</span><span class="app-feature">Password protection</span></div>
<img src="/assets/privatebin-screenshot-1.webp" alt="PrivateBin screenshot" class="app-screenshot">
<a href="/assets/privatebin-screenshot-1.webp" data-gallery="privatebin" class="app-shot-link"><img src="/assets/privatebin-screenshot-1.webp" alt="PrivateBin screenshot" class="app-screenshot"></a>
<a href="/assets/privatebin-screenshot-2.webp" data-gallery="privatebin" data-alt="PrivateBin screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/PrivateBin/PrivateBin" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -930,7 +1038,7 @@
<div class="app-card-body">
<p class="app-description">A light Bitwarden server. Keep your passwords safe and in sync on every device.</p>
<div class="app-features"><span class="app-feature">E2E encryption</span><span class="app-feature">Mobile app</span><span class="app-feature">Browser extension</span><span class="app-feature">2FA</span></div>
<img src="/assets/vaultwarden-screenshot-1.webp" alt="Vaultwarden screenshot" class="app-screenshot">
<a href="/assets/vaultwarden-screenshot-1.webp" data-gallery="vaultwarden" class="app-shot-link"><img src="/assets/vaultwarden-screenshot-1.webp" alt="Vaultwarden screenshot" class="app-screenshot"></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/dani-garcia/vaultwarden" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -946,7 +1054,10 @@
<div class="app-card-body">
<p class="app-description">A good-looking, feature-rich start page for your server. Service status, widgets and bookmarks in one place.</p>
<div class="app-features"><span class="app-feature">Widgets</span><span class="app-feature">Integrations</span><span class="app-feature">Themes</span><span class="app-feature">Status</span></div>
<img src="/assets/homepage-screenshot-1.webp" alt="Homepage screenshot" class="app-screenshot">
<a href="/assets/homepage-screenshot-1.webp" data-gallery="homepage" class="app-shot-link"><img src="/assets/homepage-screenshot-1.webp" alt="Homepage screenshot" class="app-screenshot"></a>
<a href="/assets/homepage-screenshot-2.webp" data-gallery="homepage" data-alt="Homepage screenshot 2" hidden></a>
<a href="/assets/homepage-screenshot-3.webp" data-gallery="homepage" data-alt="Homepage screenshot 3" hidden></a>
<a href="/assets/homepage-screenshot-4.webp" data-gallery="homepage" data-alt="Homepage screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/gethomepage/homepage" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -962,7 +1073,10 @@
<div class="app-card-body">
<p class="app-description">A minimal, fast dashboard for all kinds of information. RSS, weather, bookmarks, Reddit, YouTube and more on one page.</p>
<div class="app-features"><span class="app-feature">RSS</span><span class="app-feature">Weather</span><span class="app-feature">YouTube</span><span class="app-feature">Fast</span></div>
<img src="/assets/glance-screenshot-1.webp" alt="Glance screenshot" class="app-screenshot">
<a href="/assets/glance-screenshot-1.webp" data-gallery="glance" class="app-shot-link"><img src="/assets/glance-screenshot-1.webp" alt="Glance screenshot" class="app-screenshot"></a>
<a href="/assets/glance-screenshot-2.webp" data-gallery="glance" data-alt="Glance screenshot 2" hidden></a>
<a href="/assets/glance-screenshot-3.webp" data-gallery="glance" data-alt="Glance screenshot 3" hidden></a>
<a href="/assets/glance-screenshot-4.webp" data-gallery="glance" data-alt="Glance screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/glanceapp/glance" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -978,7 +1092,9 @@
<div class="app-card-body">
<p class="app-description">A neat service monitor. Watch your websites and APIs and get told when something stops working.</p>
<div class="app-features"><span class="app-feature">HTTP/TCP/DNS</span><span class="app-feature">Notifications</span><span class="app-feature">Status page</span><span class="app-feature">Charts</span></div>
<img src="/assets/uptimekuma-screenshot-1.webp" alt="Uptime Kuma screenshot" class="app-screenshot">
<a href="/assets/uptimekuma-screenshot-1.webp" data-gallery="uptimekuma" class="app-shot-link"><img src="/assets/uptimekuma-screenshot-1.webp" alt="Uptime Kuma screenshot" class="app-screenshot"></a>
<a href="/assets/uptimekuma-screenshot-2.webp" data-gallery="uptimekuma" data-alt="Uptime Kuma screenshot 2" hidden></a>
<a href="/assets/uptimekuma-screenshot-3.webp" data-gallery="uptimekuma" data-alt="Uptime Kuma screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/louislam/uptime-kuma" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -994,7 +1110,10 @@
<div class="app-card-body">
<p class="app-description">A professional monitoring and visualisation platform. Good-looking dashboards, alerts and analysis, from any data source.</p>
<div class="app-features"><span class="app-feature">Dashboards</span><span class="app-feature">Alerts</span><span class="app-feature">Data sources</span><span class="app-feature">Queries</span></div>
<img src="/assets/grafana-screenshot-1.webp" alt="Grafana screenshot" class="app-screenshot">
<a href="/assets/grafana-screenshot-1.webp" data-gallery="grafana" class="app-shot-link"><img src="/assets/grafana-screenshot-1.webp" alt="Grafana screenshot" class="app-screenshot"></a>
<a href="/assets/grafana-screenshot-2.webp" data-gallery="grafana" data-alt="Grafana screenshot 2" hidden></a>
<a href="/assets/grafana-screenshot-3.webp" data-gallery="grafana" data-alt="Grafana screenshot 3" hidden></a>
<a href="/assets/grafana-screenshot-4.webp" data-gallery="grafana" data-alt="Grafana screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/grafana/grafana" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -1010,7 +1129,10 @@
<div class="app-card-body">
<p class="app-description">A web SSH terminal and server management platform. Connect to your servers from a browser anywhere, manage SSH tunnels and edit files remotely.</p>
<div class="app-features"><span class="app-feature">SSH terminal</span><span class="app-feature">Tunnels</span><span class="app-feature">File manager</span><span class="app-feature">2FA</span></div>
<img src="/assets/termix-screenshot-1.webp" alt="Termix screenshot" class="app-screenshot">
<a href="/assets/termix-screenshot-1.webp" data-gallery="termix" class="app-shot-link"><img src="/assets/termix-screenshot-1.webp" alt="Termix screenshot" class="app-screenshot"></a>
<a href="/assets/termix-screenshot-2.webp" data-gallery="termix" data-alt="Termix screenshot 2" hidden></a>
<a href="/assets/termix-screenshot-3.webp" data-gallery="termix" data-alt="Termix screenshot 3" hidden></a>
<a href="/assets/termix-screenshot-4.webp" data-gallery="termix" data-alt="Termix screenshot 4" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/Termix-SSH/Termix" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -1026,7 +1148,9 @@
<div class="app-card-body">
<p class="app-description">Light, fast Git hosting. Your own GitHub or GitLab, with issue tracking, CI/CD and a package registry.</p>
<div class="app-features"><span class="app-feature">Git hosting</span><span class="app-feature">Issues</span><span class="app-feature">CI/CD</span><span class="app-feature">Wiki</span></div>
<img src="/assets/gitea-screenshot-1.webp" alt="Gitea screenshot" class="app-screenshot">
<a href="/assets/gitea-screenshot-1.webp" data-gallery="gitea" class="app-shot-link"><img src="/assets/gitea-screenshot-1.webp" alt="Gitea screenshot" class="app-screenshot"></a>
<a href="/assets/gitea-screenshot-2.webp" data-gallery="gitea" data-alt="Gitea screenshot 2" hidden></a>
<a href="/assets/gitea-screenshot-3.webp" data-gallery="gitea" data-alt="Gitea screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/go-gitea/gitea" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -1042,7 +1166,8 @@
<div class="app-card-body">
<p class="app-description">Visual Studio Code in the browser. Work from anywhere, on any device, with the same familiar interface.</p>
<div class="app-features"><span class="app-feature">VS Code</span><span class="app-feature">Extensions</span><span class="app-feature">Terminal</span><span class="app-feature">Git</span></div>
<img src="/assets/code-server-screenshot-1.webp" alt="Code-Server screenshot" class="app-screenshot">
<a href="/assets/code-server-screenshot-1.webp" data-gallery="code-server" class="app-shot-link"><img src="/assets/code-server-screenshot-1.webp" alt="Code-Server screenshot" class="app-screenshot"></a>
<a href="/assets/code-server-screenshot-2.webp" data-gallery="code-server" data-alt="Code-Server screenshot 2" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/coder/code-server" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -1058,7 +1183,9 @@
<div class="app-card-body">
<p class="app-description">Your own GitHub Gist server. Share code snippets with syntax highlighting and Git-based version history.</p>
<div class="app-features"><span class="app-feature">Snippets</span><span class="app-feature">Syntax</span><span class="app-feature">Git</span><span class="app-feature">Embed</span></div>
<img src="/assets/opengist-screenshot-1.webp" alt="OpenGist screenshot" class="app-screenshot">
<a href="/assets/opengist-screenshot-1.webp" data-gallery="opengist" class="app-shot-link"><img src="/assets/opengist-screenshot-1.webp" alt="OpenGist screenshot" class="app-screenshot"></a>
<a href="/assets/opengist-screenshot-2.webp" data-gallery="opengist" data-alt="OpenGist screenshot 2" hidden></a>
<a href="/assets/opengist-screenshot-3.webp" data-gallery="opengist" data-alt="OpenGist screenshot 3" hidden></a>
</div>
<div class="app-card-footer">
<a href="https://github.com/thomiceli/opengist" target="_blank" rel="noopener" class="github-link"><img src="/assets/github.svg" alt="GitHub">Source code</a>
@@ -1111,289 +1238,6 @@
</div>
</footer>
<!-- Lightbox HTML -->
<div class="lightbox-overlay" id="lightbox">
<button class="lightbox-close" aria-label="Close">&times;</button>
<div class="lightbox-content">
<button class="lightbox-nav lightbox-prev" aria-label="Previous">‹</button>
<img class="lightbox-image" id="lightbox-img" src="" alt="">
<button class="lightbox-nav lightbox-next" aria-label="Next">›</button>
</div>
<div class="lightbox-counter" id="lightbox-counter"></div>
<div class="lightbox-dots" id="lightbox-dots"></div>
</div>
<script>
/**
* Screenshot Gallery / Lightbox functionality
* - Click on app screenshot to open lightbox
* - Automatically detects multiple screenshots (app-screenshot-1.webp, app-screenshot-2.webp, etc.)
* - Navigate with arrows or keyboard
*/
(function() {
'use strict';
// Debug mode - set to true for console logging
const DEBUG = false;
function log(...args) {
if (DEBUG) console.log('[Gallery]', ...args);
}
// DOM elements
const lightbox = document.getElementById('lightbox');
const lightboxImg = document.getElementById('lightbox-img');
const lightboxCounter = document.getElementById('lightbox-counter');
const lightboxDots = document.getElementById('lightbox-dots');
const closeBtn = lightbox.querySelector('.lightbox-close');
const prevBtn = lightbox.querySelector('.lightbox-prev');
const nextBtn = lightbox.querySelector('.lightbox-next');
// State
const state = {
images: [],
currentIndex: 0,
appName: ''
};
/**
* Check if an image URL exists
* @param {string} url
* @returns {Promise<boolean>}
*/
async function imageExists(url) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(true);
img.onerror = () => resolve(false);
img.src = url;
});
}
/**
* Detect all available screenshots for an app
* @param {string} appName
* @returns {Promise<string[]>}
*/
async function detectScreenshots(appName) {
const screenshots = [];
const maxScreenshots = 10; // Maximum to check
for (let i = 1; i <= maxScreenshots; i++) {
const url = `/assets/${appName}-screenshot-${i}.webp`;
const exists = await imageExists(url);
if (exists) {
screenshots.push(url);
log(`Found: ${url}`);
} else {
// Stop checking after first missing number
break;
}
}
// Fallback: if no numbered screenshots found, use the clicked image
if (screenshots.length === 0) {
const fallbackUrl = `/assets/${appName}-screenshot-1.webp`;
screenshots.push(fallbackUrl);
}
return screenshots;
}
/**
* Extract app name from screenshot URL
* @param {string} src
* @returns {string} - The app name
*/
function extractAppName(src) {
// Match patterns: app-screenshot-1.webp or app-screenshot-1.webp
const match = src.match(/\/assets\/([a-z0-9-]+)-screenshot(?:-\d+)?\.webp/i);
return match ? match[1] : '';
}
/**
* Update the lightbox display
*/
function updateLightbox() {
if (state.images.length === 0) return;
const currentImg = state.images[state.currentIndex];
lightboxImg.src = currentImg;
lightboxImg.alt = `${state.appName} screenshot ${state.currentIndex + 1}`;
// Update counter
lightboxCounter.textContent = `${state.currentIndex + 1} / ${state.images.length}`;
// Update dots
const dots = lightboxDots.querySelectorAll('.lightbox-dot');
dots.forEach((dot, i) => {
dot.classList.toggle('active', i === state.currentIndex);
});
// Update nav buttons
prevBtn.disabled = state.currentIndex === 0;
nextBtn.disabled = state.currentIndex === state.images.length - 1;
// Hide nav and dots if only one image
const singleImage = state.images.length <= 1;
prevBtn.style.display = singleImage ? 'none' : 'flex';
nextBtn.style.display = singleImage ? 'none' : 'flex';
lightboxDots.style.display = singleImage ? 'none' : 'flex';
lightboxCounter.style.display = singleImage ? 'none' : 'block';
}
/**
* Create navigation dots
*/
function createDots() {
lightboxDots.innerHTML = '';
state.images.forEach((_, i) => {
const dot = document.createElement('button');
dot.className = 'lightbox-dot' + (i === state.currentIndex ? ' active' : '');
dot.setAttribute('aria-label', `Go to image ${i + 1}`);
dot.addEventListener('click', () => goToImage(i));
lightboxDots.appendChild(dot);
});
}
/**
* Go to specific image
* @param {number} index
*/
function goToImage(index) {
if (index >= 0 && index < state.images.length) {
state.currentIndex = index;
updateLightbox();
}
}
/**
* Open lightbox for an app
* @param {HTMLImageElement} thumbnailImg
*/
async function openLightbox(thumbnailImg) {
const appName = extractAppName(thumbnailImg.src);
if (!appName) {
log('Could not extract app name from:', thumbnailImg.src);
return;
}
log('Opening lightbox for:', appName);
// Show loading state
lightbox.classList.add('active');
document.body.style.overflow = 'hidden';
lightboxImg.src = thumbnailImg.src; // Show thumbnail immediately
lightboxImg.alt = thumbnailImg.alt;
lightboxCounter.textContent = 'Loading...';
lightboxDots.innerHTML = '';
// Detect available screenshots
state.appName = appName;
state.images = await detectScreenshots(appName);
state.currentIndex = 0;
log('Found screenshots:', state.images);
createDots();
updateLightbox();
}
/**
* Close the lightbox
*/
function closeLightbox() {
lightbox.classList.remove('active');
document.body.style.overflow = '';
state.images = [];
state.currentIndex = 0;
}
/**
* Navigate to previous image
*/
function prevImage() {
if (state.currentIndex > 0) {
state.currentIndex--;
updateLightbox();
}
}
/**
* Navigate to next image
*/
function nextImage() {
if (state.currentIndex < state.images.length - 1) {
state.currentIndex++;
updateLightbox();
}
}
// Event Listeners
// Click on screenshot thumbnails
document.addEventListener('click', (e) => {
const screenshot = e.target.closest('.app-screenshot');
if (screenshot) {
e.preventDefault();
openLightbox(screenshot);
}
});
// Close button
closeBtn.addEventListener('click', closeLightbox);
// Navigation buttons
prevBtn.addEventListener('click', prevImage);
nextBtn.addEventListener('click', nextImage);
// Click on overlay (outside image) to close
lightbox.addEventListener('click', (e) => {
if (e.target === lightbox) {
closeLightbox();
}
});
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (!lightbox.classList.contains('active')) return;
switch (e.key) {
case 'Escape':
closeLightbox();
break;
case 'ArrowLeft':
prevImage();
break;
case 'ArrowRight':
nextImage();
break;
}
});
// Touch/swipe support for mobile
let touchStartX = 0;
let touchEndX = 0;
lightbox.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
}, { passive: true });
lightbox.addEventListener('touchend', (e) => {
touchEndX = e.changedTouches[0].screenX;
const diff = touchStartX - touchEndX;
if (Math.abs(diff) > 50) { // Minimum swipe distance
if (diff > 0) {
nextImage(); // Swipe left = next
} else {
prevImage(); // Swipe right = prev
}
}
}, { passive: true });
log('Gallery initialized');
})();
</script>
<script>
(function() {
var hamburger = document.getElementById('hamburger');
+1 -1
View File
@@ -37,7 +37,7 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+1 -1
View File
@@ -26,7 +26,7 @@
<meta name="twitter:description" content="A question? Write to us: info@felhom.eu">
<meta name="twitter:image" content="https://felhom.eu/assets/og-image-en.png">
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+1 -1
View File
@@ -24,7 +24,7 @@
<meta name="twitter:description" content="Download, checksum, and what to check before you install.">
<meta name="twitter:image" content="https://felhom.eu/assets/og-image.png">
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+1 -1
View File
@@ -363,7 +363,7 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+6 -5
View File
@@ -54,8 +54,9 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<script defer src="/assets/gallery.js?v=1"></script>
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
</head>
<body class="page-index">
@@ -159,19 +160,19 @@
</div>
<div class="dash-grid">
<figure class="dash-shot">
<a href="/assets/dashboard-start-en.webp"><img src="/assets/dashboard-start-en.webp" alt="The Dashboard's Launcher: tiles of the apps installed at home" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-start-en.webp" data-gallery="dashboard"><img src="/assets/dashboard-start-en.webp" alt="The Dashboard's Launcher: tiles of the apps installed at home" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Launcher</strong> — every app you have, one click away.</figcaption>
</figure>
<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>
<a href="/assets/dashboard-apps-en.webp" data-gallery="dashboard"><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-app-en.webp"><img src="/assets/dashboard-app-en.webp" alt="An app's own page: what it is for, pictures, and the first steps" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-app-en.webp" data-gallery="dashboard"><img src="/assets/dashboard-app-en.webp" alt="An app's own page: what it is for, pictures, and the first steps" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>An app's page</strong> — what it is for, where your files go, and how to start.</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>
<a href="/assets/dashboard-backups-en.webp" data-gallery="dashboard"><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>
+4 -3
View File
@@ -38,8 +38,9 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<script defer src="/assets/gallery.js?v=1"></script>
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
</head>
<body class="page-technologiak">
@@ -165,11 +166,11 @@
<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>
<a href="/assets/dashboard-apps-en.webp" data-gallery="dashboard"><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>
<a href="/assets/dashboard-backups-en.webp" data-gallery="dashboard"><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>
+1 -1
View File
@@ -363,7 +363,7 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+6 -5
View File
@@ -54,8 +54,9 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<script defer src="/assets/gallery.js?v=1"></script>
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
</head>
<body class="page-index">
@@ -159,19 +160,19 @@
</div>
<div class="dash-grid">
<figure class="dash-shot">
<a href="/assets/dashboard-start-hu.webp"><img src="/assets/dashboard-start-hu.webp" alt="A vezérlőpult Indítópultja: az otthon telepített alkalmazások csempéi" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-start-hu.webp" data-gallery="dashboard"><img src="/assets/dashboard-start-hu.webp" alt="A vezérlőpult Indítópultja: az otthon telepített alkalmazások csempéi" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Indítópult</strong> — minden alkalmazásod egy kattintásra.</figcaption>
</figure>
<figure class="dash-shot">
<a href="/assets/dashboard-apps-hu.webp"><img src="/assets/dashboard-apps-hu.webp" alt="Az Alkalmazások oldal: telepített és telepíthető alkalmazások kártyái, állapottal" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-apps-hu.webp" data-gallery="dashboard"><img src="/assets/dashboard-apps-hu.webp" alt="Az Alkalmazások oldal: telepített és telepíthető alkalmazások kártyái, állapottal" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Alkalmazások</strong> — telepítés pár kattintással, és látod, mi fut és mi naprakész.</figcaption>
</figure>
<figure class="dash-shot">
<a href="/assets/dashboard-app-hu.webp"><img src="/assets/dashboard-app-hu.webp" alt="Egy alkalmazás saját oldala: mire jó, képek, és az első lépések" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-app-hu.webp" data-gallery="dashboard"><img src="/assets/dashboard-app-hu.webp" alt="Egy alkalmazás saját oldala: mire jó, képek, és az első lépések" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Egy alkalmazás oldala</strong> — mire jó, hova tedd a fájlokat, és hogyan kezdj hozzá.</figcaption>
</figure>
<figure class="dash-shot">
<a href="/assets/dashboard-backups-hu.webp"><img src="/assets/dashboard-backups-hu.webp" alt="A mentések oldala: minden alkalmazás adatbázisának éjszakai mentése, ellenőrizve" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-backups-hu.webp" data-gallery="dashboard"><img src="/assets/dashboard-backups-hu.webp" alt="A mentések oldala: minden alkalmazás adatbázisának éjszakai mentése, ellenőrizve" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Mentések</strong> — minden éjjel minden alkalmazás adatbázisa mentésre kerül, és ellenőrizzük.</figcaption>
</figure>
</div>
+1 -1
View File
@@ -26,7 +26,7 @@
<meta name="twitter:description" content="Kérdésed van? Írj nekünk: info@felhom.eu">
<meta name="twitter:image" content="https://felhom.eu/assets/og-image.png">
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+1 -1
View File
@@ -24,7 +24,7 @@
<meta name="twitter:description" content="Letöltés, ellenőrző összeg, és mire figyelj a telepítés előtt.">
<meta name="twitter:image" content="https://felhom.eu/assets/og-image.png">
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<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>
+1 -1
View File
@@ -6,7 +6,7 @@
<meta name="description" content="Felhom.eu - Szolgáltatások és árak. Otthoni szerver telepítés, üzemeltetés, monitoring és támogatás.">
<title>Szolgáltatások - Felhom.eu</title>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<!-- analytics intentionally omitted for draft page -->
</head>
+4 -3
View File
@@ -38,8 +38,9 @@
}
</script>
<!-- shared assets: bump ?v= together on any site.css/icons.svg change -->
<link rel="stylesheet" href="/assets/site.css?v=4">
<link rel="stylesheet" href="/assets/site.css?v=5">
<link rel="icon" type="image/png" href="/assets/logo_favicon_2.svg">
<script defer src="/assets/gallery.js?v=1"></script>
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-5e1c-48df-bdb3-c29f25fb1661"></script>
</head>
<body class="page-technologiak">
@@ -165,11 +166,11 @@
<div class="dash-grid">
<figure class="dash-shot">
<a href="/assets/dashboard-apps-hu.webp"><img src="/assets/dashboard-apps-hu.webp" alt="Az Alkalmazások oldal: telepített és telepíthető alkalmazások kártyái, állapottal" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-apps-hu.webp" data-gallery="dashboard"><img src="/assets/dashboard-apps-hu.webp" alt="Az Alkalmazások oldal: telepített és telepíthető alkalmazások kártyái, állapottal" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Alkalmazások</strong> — telepítés pár kattintással, és látod, mi fut és mi naprakész.</figcaption>
</figure>
<figure class="dash-shot">
<a href="/assets/dashboard-backups-hu.webp"><img src="/assets/dashboard-backups-hu.webp" alt="A mentések oldala: minden alkalmazás adatbázisának éjszakai mentése, ellenőrizve" width="1440" height="900" loading="lazy"></a>
<a href="/assets/dashboard-backups-hu.webp" data-gallery="dashboard"><img src="/assets/dashboard-backups-hu.webp" alt="A mentések oldala: minden alkalmazás adatbázisának éjszakai mentése, ellenőrizve" width="1440" height="900" loading="lazy"></a>
<figcaption><strong>Mentések</strong> — minden éjjel minden alkalmazás adatbázisa mentésre kerül, és ellenőrizzük.</figcaption>
</figure>
</div>