c9b9432986
gates / gates (push) Successful in 6m5s
The voice sweep reached the visible text and stopped there. description, og:description and twitter:description on both contact pages still said "Irj nekunk es szemelyre szabott ajanlatot keszitunk" / "Write to us and we will make a personal offer" - six lines nobody sees on the page and everybody sees under a shared link, which is where the operator was about to post one.
704 lines
55 KiB
Markdown
704 lines
55 KiB
Markdown
## 2026-10-12 (night) — the share card shows the product
|
||
|
||
The operator went to post the link and found the card out of date (2026-10-12): it was the
|
||
2026-07-18 design — a headline and two lines of text on a dark field, nothing of the product, and
|
||
older than everything the site has become since.
|
||
|
||
**Found while rebuilding the card:** the voice sweep reached the visible text and stopped there.
|
||
The contact pages' `description`, `og:description` and `twitter:description` still said „Írj nekünk
|
||
és személyre szabott ajánlatot készítünk” / „Write to us and we will make a personal offer” — six
|
||
lines nobody sees on the page and everybody sees under a shared link, which is precisely where the
|
||
operator was about to post one. First person now. The legal pages keep their plural on purpose:
|
||
their metas describe documents whose own text is plural and frozen.
|
||
|
||
- **`og-image.png` and `og-image-en.png` rebuilt around the laptop**, with the hero's own poster
|
||
frame on its screen: what somebody sees shared in a feed is now the thing itself.
|
||
- **The typography is the old card's, to the pixel.** The site's font is a woff2 and no font file
|
||
here can be handed to a drawing library, so `scripts/make_og_card.py` lifts the headline, the logo
|
||
and the button out of the previous card as pixels and composites them with `lighter` onto flat
|
||
`--bg-0` — the crop's own background is the same colour, so there is no seam. **Nothing in that
|
||
script draws a glyph, so new words cannot be made with it**: a new headline goes back to the
|
||
design tool and the script then takes that card as its source. The two lines of lede are gone
|
||
(they would have needed the font); the laptop says what they said.
|
||
- **`?v=2` on every `og:image` and `twitter:image`** (20 pages). A scraper caches by URL, so a new
|
||
picture at the old URL would have reached nobody. **A card already attached to a post does not
|
||
change** — that post has to drop the preview and re-add the link, after a re-scrape.
|
||
- The English card carries the same Hungarian-language Immich screen as the Hungarian one, because
|
||
it is the same recording the hero uses on both pages. Worth a retake if the English page ever
|
||
gets its own.
|
||
|
||
## 2026-10-12 (review round) — the reviewer's findings, fixed
|
||
|
||
A page-by-page review of the live site (Playwright, 1440 px and 390 px) found six real defects and
|
||
two editorial questions. The operator answered three questions first; the answers are in
|
||
`REPORT-review-2026-10-12.md`.
|
||
|
||
**Fixed**
|
||
|
||
- **The contact form showed its consent error before anyone pressed anything** (both languages).
|
||
`#privacyError` sits OUTSIDE any `.form-group`, and the rule that hides error messages was scoped
|
||
to `.form-group`, so it never reached it — it was on screen from the first paint. Scoped to the
|
||
page instead. Checked: load (no error) — submit unticked (error) — tick (error gone).
|
||
- **The consent checkbox was the browser's own 18 px control.** It is the site's now: a 24 px box in
|
||
the design system's border and blue, a keyboard focus ring, and a second `<label for="privacy">`
|
||
wrapped round it at 44×44 px (pulled back with negative margins, so the layout does not move) —
|
||
a label toggles the control it names, so the whole square is tappable.
|
||
- **The contact page promised more than the terms allow.** It said „24 órán belül válaszolunk” while
|
||
`/feltetelek` 1.1 §4 says „Nem ígérünk válaszidőt”. Now: „Általában 1–2 napon belül válaszolok. A
|
||
zárt teszt alatt válaszidőt nem vállalok — ez a teszt feltételeiben is így áll.”
|
||
- **The services pages were missing from `sitemap.xml`.** `/szolgaltatasok` and `/en/services` added
|
||
with their hreflang pair; 18 URLs — 20.
|
||
- **A pre-shell mobile-menu script still ran on every inner page**, logging
|
||
`[mobile-menu] Missing elements` to the console. Removed from all 20 pages (the home pages never
|
||
had it). Its elements (`#hamburger`, `#mobileOverlay`) stopped existing with the M3 switch.
|
||
- **The sidebar's tester button looked second-class** — it was `btn-outline` while the hero's was
|
||
`btn-primary`. Both are primary now (that blue passes AA since R-930).
|
||
- **The home page's biggest section said nothing.** „Mit tud a doboz ma?” was three bare links; each
|
||
card now carries 2–3 of the services page's own item names, word for word, with the
|
||
„Minden szolgáltatás →” link kept under them.
|
||
- **A plain `Facebook` link in the footer** (all 22 pages, both languages), pointing at the Page. No
|
||
script, widget, pixel or embed — the privacy notice says the site loads nothing from anywhere
|
||
else, and that stays true.
|
||
|
||
**The voice** (operator ruling: *„‚I’ everywhere a person speaks”*)
|
||
|
||
- The contact, tester and FAQ pages in both languages now speak in the first person singular, which
|
||
is what the „Ki áll mögötte” bio already did and what is true: one person runs Felhom. The home
|
||
and services pages follow, so no sentence contradicts another.
|
||
- **An inclusive „we” stays plural** („Megbeszéljük”, „átbeszéljük”, „egyeztetjük” — you and I,
|
||
talking), and **the legal texts are untouched**, so `/adatkezeles` and `/feltetelek` are still
|
||
byte-for-byte what they were.
|
||
- Every FAQ answer exists twice (the FAQPage JSON-LD and the visible text) and gate 18 holds the two
|
||
equal, so each change was made to both copies — five answers carry `<strong>` inside the sentence
|
||
and the gate caught exactly those five when the first pass missed them.
|
||
- **„Miben segíthetünk?” is „Miben segíthetek?”**, and its list is what the closed test actually
|
||
offers (operator ruling): app installation, backup set-up, questions about the test. Server
|
||
consulting, maintaining someone else's server and remote-access set-up are gone.
|
||
|
||
**The hero clip, rebuilt**
|
||
|
||
- **Immich is the first scene**, so the poster — the still every blocked or paused video shows — is
|
||
a wall of real photographs rather than a cartoon llama.
|
||
- **The Jellyfin scene starts one second in**, after the demo's library wall. That removes eleven
|
||
pieces of film poster art whose licences cannot be quoted from a first-party source, and the
|
||
„Stable Demo” branding with them.
|
||
- **The film that does play is credited.** On Blender's own video platform *Caminandes 3: Llamigos*
|
||
carries `"licence": {"id": 1, "label": "Attribution"}` — CC BY, which **requires** attribution and
|
||
is **not** public domain, as this file wrongly said yesterday. The caption now reads
|
||
„A film a képernyőn: Caminandes: Llamigos © Blender Foundation, CC BY”, linked to the film's page.
|
||
- **1.3 s of blank screen is gone from the OnlyOffice scene** (a loading page, then an empty
|
||
spreadsheet before the data arrived): the scene is 0–3.30 s plus 4.60 s–end, cut on the frame.
|
||
- 34.3 s now: mp4 1 084 KB, webm 1 185 KB, poster 69 KB.
|
||
|
||
`site.css` — `?v=30` on all 22 pages; the clip and poster are `?v=2`.
|
||
|
||
## 2026-10-12 (night) — the headings are two-tone again, and the home page has rules between its sections
|
||
|
||
Both from the operator, 2026-10-12: the white/blue heading split was lost in the M3 switch and
|
||
should come back everywhere (*„on the apps page too, the categories should be white/blue”*), and the
|
||
home page's sections were hard to tell apart.
|
||
|
||
- **41 headings got their `<span>` back**, white lead-in and blue tail, which is what
|
||
`h1 span, h2 span, h3 span, h4 span { color: var(--blue-bright) }` has always rendered — the
|
||
rule never went away, the markup did. **No text changed**: the span is wrapped around words that
|
||
were already there, so every page says exactly what it said before.
|
||
- Home (5 + 5): the three that existed before M3 are split where they were split then
|
||
(`Mit tud | a doboz ma?`, `Így néz ki | a vezérlőpult`, `Hogyan | működik?`).
|
||
- Apps (6 + 6) and FAQ (6 + 7): **new**, these category headers never had it. A two-part name
|
||
splits at its `&` (`Fájlkezelés & | Irodai`), a phrase on its last words.
|
||
- Services (3 + 3): the three group headings.
|
||
- **Left plain, deliberately:** a one-word heading has nowhere to split — `Alapkérdések`,
|
||
`Költségek`, `Costs`, `Letöltés`, `Download`. Four other pages (technology, testing, backups,
|
||
contact) still carried their splits and were not touched.
|
||
- **A hairline between the home page's sections**, in the design system's own `--line`, with equal
|
||
air above and below it (2.75rem each) so the rule sits centred in the gap rather than hugging the
|
||
heading below. The first one also separates the hero from the page. Only the home page: every
|
||
other page is a single run of one kind of thing.
|
||
- Blue on the page background measures **7.9:1** — AA at any size, so the split is safe on the
|
||
small headings too.
|
||
- `site.css` — `?v=28` on all 22 pages.
|
||
|
||
## 2026-10-12 (night) — the laptop screen moves: six real apps behind the cut-out frame
|
||
|
||
The operator recorded the six scenes himself and ruled on their length: *„use the full length for
|
||
all of them, they had been cut as I liked them”*. Jellyfin, Paperless and RomM were filmed on those
|
||
projects' own public demo sites, so nothing in the clip is anyone's private library; ~~the films in
|
||
the Jellyfin scene are public-domain prints~~ — **that sentence was wrong, see the entry above
|
||
for 2026-10-12 (review round): the film that plays is CC BY, which is not public domain, and it is
|
||
credited on the page now.**
|
||
|
||
- **`website/assets/hero-clip.mp4` (1 134 KB) + `hero-clip.webm` (1 295 KB) + `hero-poster.webp`
|
||
(53 KB)** — Jellyfin, Tandoor, OnlyOffice, Immich, RomM, Paperless, in that order, 0.6s
|
||
crossfades, **36.6s** in all at 904×556 (2× the rendered size). Built by
|
||
`scripts/make_hero_clip.py`, which now plays each scene at its own length instead of a fixed
|
||
window.
|
||
- **The hero on `/` and `/en/` is the clip**, behind `hero-laptop-frame.webp`: `.hero-screen` sits
|
||
in the cut-out hole (`left 11.041%` / `top 12.345%` / `79.817%×64.305%`) at `z-index: 1`, the
|
||
frame above it at `z-index: 2`, so bezel, glare and keyboard stay in front of the moving picture.
|
||
- **Nothing autoplays by attribute.** `preload="none"` + a poster; the page's own script starts the
|
||
clip when it scrolls into view, pauses it when it leaves, and **never starts it at all under
|
||
`prefers-reduced-motion: reduce`**. With JavaScript off the poster simply stays. First paint costs
|
||
the frame (59 KB) + poster (53 KB); the clip is fetched after.
|
||
- **One set serves both languages** — the recordings are the same on both pages, so there is no
|
||
`-hu`/`-en` pair to keep in step. The still composites (`dashboard-laptop-{hu,en}.webp`) stay in
|
||
the repo, now unreferenced, as the fallback if the clip is ever pulled.
|
||
- Caption and `aria-label` name the six apps and claim nothing about whose box they ran on.
|
||
- **The language menu opened off the left edge of the window.** The controller's own rule centres
|
||
it on the globe (`left: 50%` + `translateX(-50%)`), which is right where the globe sits in the
|
||
middle of its row — but on the website the globe is at the far left of the sidebar footer, so
|
||
60 px of a 120 px menu hung outside the window and both labels were cut (operator, 2026-10-12).
|
||
Anchored to the button's left edge in the website's own file, opening rightwards into the
|
||
sidebar; `shell.css` stays a verbatim copy. Measured after: menu `x 24→144` inside a 240 px
|
||
sidebar.
|
||
- `site.css` — `?v=27` on all 22 pages.
|
||
- **Not verified: playback in this workstation's Chrome.** Its media pipeline loads nothing at all
|
||
today — a 1 KB generated WAV blob also stalls at `readyState 0` with no error, which rules the
|
||
clip out as the cause. Geometry, layering and the poster were verified in the browser; the moving
|
||
picture needs a Chrome restart to confirm.
|
||
|
||
## 2026-10-12 (evening) — the laptop frame, cut open for a moving screen
|
||
|
||
Prepared, **not yet on the page**: the live hero still shows the still. The clip itself is the
|
||
operator's to record (his decision, 2026-10-12: he films the apps, the assembly is built here).
|
||
|
||
- **`website/assets/hero-laptop-frame.webp`** (59 KB) — the same laptop render, with the **screen cut
|
||
out to transparency** so a clip can play underneath while the bezel, the keyboard and the glass
|
||
reflection stay on top. The reflection is painted, not lifted: lifting the bright pixels out of the
|
||
AI-drawn screen dragged a ghost of the drawn UI with it.
|
||
- The hole is `left 11.041% · top 12.345% · width 79.817% · height 64.305%` of the frame, ratio
|
||
**1.626:1**. Two pixels of slack: the lid keystones slightly, so a tight rectangle let the drawn
|
||
sidebar's highlight show and a loose one showed page background at the top left. Both were seen.
|
||
- **What will load, and when:** `<video muted loop playsinline preload="none">` with the first frame
|
||
as its poster, started only when the hero scrolls into view, and never started under
|
||
`prefers-reduced-motion`. First paint costs the frame (59 KB) + the poster (~80 KB) against today's
|
||
single still (57 KB); the clip itself (~330 KB) is fetched after, or not at all if the visitor
|
||
never reaches it. **No „loading" graphic is needed** — the poster is the loading state.
|
||
- Layering proven in the browser against a placeholder clip: content inside the bezel, frame on top,
|
||
and a magenta backdrop behind the frame showed the cut-out is clean all the way round.
|
||
|
||
## 2026-10-12 (afternoon) — four more notes, and the leak shape gate 22 could not see
|
||
|
||
`site.css?v=25`.
|
||
|
||
- **The home page talked about the operator in the third person** („Ha írsz, ő válaszol") while the
|
||
page it links to is in the first („Ha írsz, én válaszolok"). Both home pages now read
|
||
„**Nagyfenyvesi Viktor vagyok**, a Felhom mögött én állok" / „**I am Viktor Nagyfenyvesi**, and I
|
||
am the one behind Felhom", and the link after it is „Rólam bővebben →" / „More about me →" rather
|
||
than repeating the question the sentence has just answered. The legal pages keep the formal
|
||
third-person name, which is what they are for.
|
||
- **36px of dead space under the language globe, and the cause was a leak.** The old chrome's
|
||
`nav { position: fixed; padding: 20px 0; backdrop-filter: blur(12px); z-index: 200 }` is a **bare
|
||
element selector**, so it matched `<nav class="sidebar">` too — and `.sidebar` declares none of
|
||
those four properties, so all four were in force on the sidebar. The rule is scoped
|
||
`body:not(.shell)` now, and the footer row's own padding went from 16px to ~8px. Gate 22 could not
|
||
see this: it compares selectors that appear in BOTH stylesheets, and `nav` is not a selector
|
||
`shell.css` ever writes.
|
||
- **Gate 22 now also refuses a bare `nav`/`header`/`main`/`aside` rule** that is not scoped — the
|
||
shell's own elements are `<nav class="sidebar">`, `<header class="mobile-topbar">` and
|
||
`<main class="content">`, so an unscoped element rule reaches them whatever shell.css calls them.
|
||
It convicted a second one on its first run: `@media (max-width: 900px) and (scripting: none)
|
||
nav { position: static }`, R-903's no-JavaScript fallback, which had been overriding the sidebar's
|
||
`position: fixed` on a phone with scripting off. `footer` is deliberately NOT on the list: the
|
||
shell carries the website's own footer, so those rules are meant to apply.
|
||
- **The comparison table and the two cards under it were touching** on the home page — `.vs` ends on
|
||
its own border and `.band` opens with a 2px blue rule, so they read as one block. 2rem between them.
|
||
- **„Minden alkalmazás" is now „Az alkalmazásokról" / „About the apps".** Every app is on that one
|
||
page, so the first submenu item is not a filter — it is the top of the page, where the intro and
|
||
the „Fontos tudnivalók" box are.
|
||
|
||
## 2026-10-12 — the operator's seven notes from his own screens
|
||
|
||
Seven things, found by looking at the live site on a desktop and a phone. Five were defects, two were
|
||
design. `site.css?v=24`.
|
||
|
||
- **The category links in the sidebar were dead — all 100 of them.** The five app-category items
|
||
pointed at `#fajlkezeles-irodai`, `#media-szorakozas` and friends; the sections' ids are
|
||
`#fajlkezeles`, `#media`. The sidebar is copied into every page, so one wrong fragment was wrong
|
||
twenty times, and a dead fragment raises no error anywhere — the browser simply stays put.
|
||
**New gate 23** resolves every in-site `#fragment` against the page it names (360 of them today),
|
||
and it found two more live ones while being written: the home page's four hero tiles pointed at
|
||
`/alkalmazasok#immich` and friends, which nothing had ever carried, and the FAQ's contact button
|
||
pointed at a home-page section that moved out. **Every app card now carries its slug as an id**, so
|
||
`/alkalmazasok#immich` works — the slug comes from the card's own logo file, which gate 21 already
|
||
ties to the catalog.
|
||
- **„Szolgáltatások" is a page now**, `/szolgaltatasok` and `/en/services`, not an anchor into the
|
||
home page. The ten capability items moved verbatim; the home keeps the promise sentence, the three
|
||
group names as links, and a button. The home page is 345 Hungarian words shorter.
|
||
- **The home headline is back in the hero**, beside the picture, two lines with the second in
|
||
`--blue-bright` at `clamp(2.1rem, 4.4vw, 3.2rem)` — the shape and size it had before M3. It had
|
||
been moved into `.page-header`, which is the INNER pages' heading, so it shrank to 2.1rem and the
|
||
domain badge ended up stranded beside it.
|
||
- **The hero picture is a real screenshot in a laptop.** The frame is the operator's own supplied
|
||
render; the screen is `dashboard-start-{hu,en}.webp` composited into it, so what a visitor sees is
|
||
a real box's Launcher and not a drawing of one. 57 KB, named `dashboard-laptop-<lang>.webp` so
|
||
gate 19 holds it to the page's language like every other dashboard picture.
|
||
- **`.page-lede` had no CSS at all** — on 16 pages it rendered as a bare paragraph the full width of
|
||
the content column, hard against the box beneath it. It now shares the box's 760px measure, sits
|
||
over its centre, and has 28px of air beneath.
|
||
- **The sidebar logo**: the wordmark was 0.67× the mark's width where the real lockup
|
||
(`assets/logo.png`, measured) has it at 1.28× — less than half the intended size. Mark 112px,
|
||
wordmark 25px tall, and 28px less vertical padding.
|
||
- **The scrollbars are the page's own**, thin and in the palette. The first attempt missed the big
|
||
one: the viewport's scrollbar is painted from `<html>`, and a `body.shell ::-webkit-…` rule only
|
||
reaches scrollers inside the page.
|
||
- **The two Latin font subsets are preloaded.** With `font-display: swap` the page reflowed after
|
||
first paint; measured on `/alkalmazasok#media`, the anchor target sat 1339px lower once the font
|
||
arrived.
|
||
|
||
## 2026-10-11 (evening) — the two M3 defects a real phone found, and the gate that now holds them
|
||
|
||
Both were mine, both shipped in the morning's switch, and both were reported by the operator from his
|
||
own phone rather than caught here. `site.css?v=23` / `shell.css?v=23`, live and read back on all 20
|
||
pages at 390 / 860 / 1440 px.
|
||
|
||
- **The phone menu was empty.** The drawer slid open correctly and had nothing in it: `site.css`'s old
|
||
mobile nav still reached the shell's sidebar, because under `@media (max-width: 900px)` it sets
|
||
`.nav-links { position: fixed; right: -100% }` — which parked the menu off-canvas *inside* the open
|
||
drawer. Fixed at the source: every selector belonging to the website's OLD chrome (`nav`,
|
||
`.nav-links*`, `.mobile-overlay`, `.hamburger`, `.logo*`, `.lang-globe-li` — 29 occurrences) is now
|
||
scoped `body:not(.shell)`. Scoped, not deleted, so a page without the shell still works.
|
||
`.hamburger-box` and `.hamburger-line` stay unscoped on purpose: the shell's burger uses them.
|
||
- **Why the morning's check missed it.** The STOP-1 leak diff compared the two stylesheets'
|
||
declaration sets **with `@media` blocks excluded**, and reported „exactly six" leaking declarations.
|
||
Media-aware, the number is **forty** — and the worst of them only apply below 900 px, which is why
|
||
the desktop looked right and a phone did not. A check that silently skips part of its subject is not
|
||
a check; this one returned a confident wrong number and was believed.
|
||
- **The footer rendered as a second column** at the top right of 16 pages. `body` is a flex row on a
|
||
shell page, and the insert moved the footer inside `<main>` only on pages that *ended* with
|
||
`</main>`; a page with a `<script>` after it kept the footer as a direct child of `body` — a flex
|
||
sibling of the sidebar. Moved inside `<main class="content">` on all 16, each move asserted to have
|
||
landed inside.
|
||
- **Both are now gated, each red-proofed by putting the live defect back** (`site_gates.py` gate 3b
|
||
and the new gate 22; decoys `site/footer-outside-main` and `site/shell-css-leak-in-media`).
|
||
|
||
## 2026-10-11 (M3) — the whole site moves into the controller's shell
|
||
|
||
The operator's own direction, after three mockups were rejected: the **controller's frame** (left
|
||
sidebar, phone top bar, off-canvas drawer) around **the website's own content**. Switched in one
|
||
commit — never half old, half new. 20 pages: 12 Hungarian, 8 English.
|
||
|
||
- **`website/assets/shell.css`** — **117 rules copied VERBATIM** from
|
||
`felhom-controller/controller/internal/web/templates/style.css` @ `dcd89364a4`, plus **exactly one
|
||
adapted rule** that says so (`body.shell { display:flex; min-height:100vh }`, which lives in the
|
||
controller's base rather than in a component, scoped so a page without the shell is untouched).
|
||
The generator **names every rule it copies and refuses to write the file if one has disappeared
|
||
upstream** — which already caught two things: a selector that no longer exists, and
|
||
`prefers-reduced-motion` being split across **five** separate blocks, four of which a naive copy
|
||
would have lost. That is M1's failure, prevented.
|
||
- **`shell.css` loads after `site.css` deliberately.** Thirteen selectors exist in both with
|
||
different meanings. „Later wins" is **per property, not per rule**, so six declarations still
|
||
leaked through and are reset in `site.css`: `.nav-links` `display:flex`+`gap` (the sidebar rendered
|
||
as a horizontal row across the page), `.lang-globe-menu` `top`+`right`, `.page-header`
|
||
`padding`+`text-align`. Found by diffing declaration sets, not by looking — only one was visible.
|
||
- **The footer is kept**, carried verbatim into the bottom of the content column. Stripping the old
|
||
chrome had removed it from all 19 pages, taking with it the only route to the **Adatkezelési
|
||
tájékoztató and the Feltételek**, the operator's name and `info@felhom.eu`. Caught before the
|
||
switch.
|
||
- **The English home page is now a true twin** of the Hungarian one (operator's decision): every
|
||
string lifted verbatim from the live English page, except twelve faithful translations of sentences
|
||
the `/preview/` round introduced. 35.8 KB → 25.4 KB.
|
||
- **Em dashes: 326 replaced** with the Hungarian gondolatjel across 17 pages. The FAQ pages' JSON-LD
|
||
is swept with the same substitution so it still equals the visible answers (gate 17 green).
|
||
**The legal texts are byte-identical** — proven by a word-level diff with no substitution allowed.
|
||
- **`site.css`** gains the M3 page rules, the six leak resets, AA fixes for the copied
|
||
`.btn-primary` and `.nav-group-label`, and `overflow-wrap` for long checksums and URLs — the last
|
||
one repairing a **pre-existing** sideways scroll on `/letoltes` and `/adatkezeles` (609 px and
|
||
478 px at a 390 px viewport, measured on the live pages).
|
||
- **`website/preview/` deleted entirely** (the A, M1, M2 and M3 studies) with its `robots.txt` line.
|
||
`site.css?v=22` / `shell.css?v=22` everywhere.
|
||
- **`scripts/site_gates.py`**: gate 3 extended rather than duplicated — a `SHELL` set whose pages must
|
||
carry an **identical sidebar and footer**. `is_en()` makes the language gates path-aware.
|
||
`norm_block()` also normalises `is-open`/`aria-expanded`. Every change red-proofed, the loosening
|
||
one **both ways**: a one-character menu difference convicts, a state-only difference does not.
|
||
|
||
**What the head-tag diff caught, and why it was worth doing.** Head tags were captured on all 19
|
||
pages before the switch and compared after. The home page was about to ship carrying
|
||
**`noindex, nofollow`** from the preview, and had lost `meta keywords`, `meta author`, all seven
|
||
Open Graph tags, all four Twitter tags and the `LocalBusiness` JSON-LD — because its head was
|
||
hand-built while every other page carried its live one over. Nothing on the rendered page would have
|
||
shown it. After the fix the **only** head-tag difference anywhere is the dash substitution inside the
|
||
two FAQ pages' JSON-LD, verified by applying the same substitution to the „before" copy and getting
|
||
an exact match.
|
||
|
||
**Live read-back, all 20 pages:** 200, sidebar present, footer present, legal link present,
|
||
`?v=22` on both stylesheets. Home page: 12 requests, 282 KB, zero third-party hosts, `index, follow`,
|
||
canonical and JSON-LD intact, **0 em dashes**, 10 967 px → 4 340 px tall.
|
||
|
||
## 2026-10-11 (este) — „Ki áll mögötte" a kapcsolati oldalakra költözött
|
||
|
||
Operator's call after seeing the preview. **This one IS live**, on `/kapcsolat` and `/en/contact`;
|
||
the home page itself is still the old design.
|
||
|
||
- **The full block moved to `/kapcsolat` + `/en/contact`.** On the home page it sat between the
|
||
dashboard gallery and „Hogyan működik?", interrupting *what it does* → *how you get it* with a
|
||
life story — and its last sentence, „Ha írsz, én válaszolok", is a contact-page sentence that
|
||
belongs beside „Válaszidő". Both halves of the twin moved in the same commit; the English uses the
|
||
site's established „the box" and promises nothing the Hungarian does not.
|
||
- **The home page preview keeps a compact trace** in its closing call to action: a 56×70 portrait,
|
||
one line, and a link to the full block. Deliberate, not a leftover — the audit's **R-11** finding
|
||
was „nobody is behind it" *on the home page*, so deleting every human trace would have re-opened
|
||
it. The preview is now **9 sections, 9 layout families**, 6 385 px at 1440 and 10 145 px at 390
|
||
(from 10 922 / 19 913: 42% and 49% shorter).
|
||
- A dedicated `/rolam` page was weighed and rejected: five sentences cannot carry a page, and filling
|
||
one would have meant inventing biography.
|
||
- **The `.who*` rules are no longer page-scoped.** They were `.page-index .who*`; the block now lives
|
||
on two pages and will live on the home page's twin later, so it follows `69035f4af5`'s lesson that
|
||
a genuinely shared pattern goes site-wide rather than being duplicated per scope. No existing page
|
||
used `.who`, so nothing else moved.
|
||
- `assets/operator-portrait-small.webp` — 160×200, 8.4 KB, same crop, metadata stripped and verified
|
||
by read-back.
|
||
- **A layout bug caught by looking at the deployed page**, not at the markup: `.who-mini` was
|
||
`inline-flex` inside a `text-align: center` block, so it flowed onto the same line as the CTA
|
||
button and pushed the pair off-centre. Now `flex` with `max-width` and `margin: auto`.
|
||
- `site.css?v=` → 14 on all 21 files.
|
||
|
||
## 2026-10-11 — the footer dash site-wide, and the primary button meets WCAG AA
|
||
|
||
Two operator decisions taken at the redesign review. **The home page itself was NOT switched** — the
|
||
operator chose to sit with the preview, so `/` still serves the old design. Only these two things
|
||
changed on it, and on every other page.
|
||
|
||
- **The footer's em dash became the correct spaced en dash, on all 21 page files** (12 Hungarian,
|
||
8 English, plus the preview). It could never have been a one-page edit: `site_gates.py` gate 3
|
||
requires every page in a language set to carry an **identical** footer. Verified on all 18 live
|
||
URLs after deploy: `em=0 en=1` on each.
|
||
**Scope, stated:** this clears the footer only. **300 em dashes remain in the bodies of the other
|
||
19 pages** (`gyik` 53, `en/faq` 53, `adatkezeles` 33, `szolgaltatasok-nonpublic` 27, `teszteles` 23,
|
||
`en/testing` 24, `index` 17, `en/index` 19, …). Enumerated per page in
|
||
`documentation/audits/redesign-2026-10-10/NEXT.md`. The preview is the only page at zero.
|
||
- **R-930 — `.cta-button` is now 1.2rem/700** (was 1rem/600). White on `--blue` measures **4.01:1**,
|
||
under WCAG AA's 4.5:1 floor for body text; at ≥ 18.66 px and ≥ 700 weight WCAG counts the label as
|
||
**large text**, where the floor is 3:1 and 4.01 clears it. Chosen by the operator over darkening
|
||
`--blue`, which is shared with the hub and controller UIs. Horizontal padding trimmed 32→26 px to
|
||
protect the one-line rule for the longest label.
|
||
**Measured, not assumed:** every primary button renders on **one line** and **no page overflows**,
|
||
checked in the browser on 11 pages at both 390 px and 1440 px. The defect was pre-existing and
|
||
site-wide — it measured the same 4.01:1 on the live page before any of this work — so the fix
|
||
reaches the primary button on 16 pages, which is the point. `.cta-button-secondary` is untouched at
|
||
7.17:1.
|
||
- **`site.css?v=` → 12 on all 21 files.** The pages sat at `v=10` and the preview at `v=11`; leaving
|
||
them split would have served a returning visitor the old stylesheet and the change would have
|
||
looked like it did not deploy.
|
||
|
||
## 2026-10-10 (este) — a redesigned home page, staged at /preview/
|
||
|
||
- **Why:** the home page read as AI-made — eleven sections but only eight layout families, every
|
||
section header the same centred two-word-plus-blue-tail shape, the hero showing the **logo** where the
|
||
product belongs, and a value proposition („Professzionális otthoni szerver telepítés és
|
||
üzemeltetés") that says nothing. Measured audit, against the live site:
|
||
`documentation/audits/redesign-2026-10-10/AUDIT.md`.
|
||
- **`website/preview/index.html`** — the new home page, `noindex` + `Disallow: /preview/`, not in the
|
||
sitemap, linked from nowhere. It becomes `index.html` only on the operator's go.
|
||
- **New: „Ki áll mögötte"** with the operator's photograph and five sentences in his own words.
|
||
Every claim traced in `audits/redesign-2026-10-10/ki-all-mogotte.md`. The photo
|
||
(`assets/operator-portrait.webp`) is cropped from an original that **stays outside the repo**, and all
|
||
metadata is stripped and **verified by read-back** (0 EXIF tags, 0 GPS entries, and none of the phone's
|
||
identifying byte sequences survive). The original carried no GPS tag to begin with; it did carry the
|
||
phone model and the timestamp.
|
||
- **Ten sections, ten different layout families.** `why-grid` no longer runs three times and
|
||
`apps-showcase` no longer twice: the ten capability cards become three labelled clusters, the three
|
||
cloud-problem cards and the four own-server cards merge into **one two-column comparison**, and the two
|
||
tile walls shrink to a two-item band that keeps the app names and links to the pages that already list
|
||
them.
|
||
- **The hero** shows a real dashboard screenshot instead of the logo, is sized by its content instead of a
|
||
forced `100vh` band, and drops the infinite float animation. Its sentence is now four concrete facts.
|
||
- **Numbers off the mono font.** The `1..5` process badges and `01..05` service numbers are gone
|
||
(taste-skill §9.F), and the 3-2-1 figures move to the UI font — together these were the **only** 13
|
||
characters on the page loading JetBrains Mono, so the page no longer fetches it.
|
||
- **Em dashes: 18 → 0** in the page's own copy. The `<title>`, meta description, Open Graph, Twitter and
|
||
JSON-LD keep theirs by operator decision (they are indexed strings; changing them deserves its own
|
||
pass). **One remains in the shared footer**, which gate 3 requires to be identical on all 14 pages —
|
||
a site-wide edit, carried as a separate decision.
|
||
- **CSS: additions only.** Every new rule is a new class under `.page-index`; nothing existing was
|
||
modified, so `index.html` and every other page render exactly as before while the preview exists.
|
||
`site.css?v=11` on the preview page only.
|
||
- **Gate:** `preview/index.html` is registered in `site_gates.py` `NO_TWIN`, with the reason in a comment
|
||
— a preview URL **cannot** go in `TWINS`, because gate 3 wants its nav identical to `index.html`'s
|
||
(globe pointing at `/` and `/en/`) while the twin check wants the globe pointing at the pair's own URLs.
|
||
The English twin is written in the same commit as the switch, as a real twin.
|
||
- **CRLF, again.** The page builder wrote LF and the nav/footer gate went red for the preview exactly as
|
||
the 2026-10-10 morning entry above describes. Builder now writes **BOM + CRLF** and asserts both.
|
||
|
||
## 2026-10-10 — a tester recruitment page, and terms 1.1 (the domain)
|
||
|
||
- **New page pair: `/teszteles` + `/en/testing`** — the website asked for testers without saying what a
|
||
tester needs or what Felhom pays for. The page states it: who it is for (a Hungarian household, no IT
|
||
knowledge, but patience), **what you need** (a machine that can stay on and home internet — both
|
||
**quoted verbatim from the FAQ** rather than invented, plus a domain), **what you get** (the six
|
||
promises of the test terms §3, nothing new), what we ask for (feedback; the terms' own „keep your own
|
||
copy"), and **how many places there are**. No price, no availability promise, no response-time promise.
|
||
- **Operator ruling D1 (2026-10-10) — the domain:** registered in the **tester's own name**, Felhom pays
|
||
its fee **for two years**, and **the tester keeps it** when the test ends or they leave. DNS is managed
|
||
with a token scoped to **that one zone only**. Recorded in `CONTEXT.md`.
|
||
- **Operator ruling D2 (2026-10-10):** the closed test runs with **at most 5 households**; the page says
|
||
„legfeljebb 5 háztartás".
|
||
- **Terms 1.1** (`feltetelek.html`, record `documentation/legal/feltetelek-1.1.md`): one new section,
|
||
**§4 (the domain)**, with the D1 text. Sections 4–11 of 1.0 are renumbered 5–12; nothing else changed.
|
||
No document or page referenced those numbers — checked before renumbering. The terms' §11 promises
|
||
testers an e-mail before a change, so one is drafted at `marketing/testers/EMAIL-terms-1.1.md` for the
|
||
operator to send.
|
||
- **Every „Jelentkezem tesztelőnek" button now goes to the page**, not to an anchor or the contact form:
|
||
the home page hero (was `#zart-teszt`) and its „Zárt teszt" section (was `/kapcsolat?tema=zart-teszt`),
|
||
and the English pair. **The contact form needed no change** — `?tema=zart-teszt` already preselects the
|
||
closed-test subject on both contact pages, so the page's apply button uses it.
|
||
- **Registered and listed:** the pair is in `site_gates.py` `TWINS` and `URL` (gate 13 refuses a page the
|
||
gates do not scan), and both URLs are in `sitemap.xml` with their hreflang trio — 18 URLs now.
|
||
- **Encoding, the hard way:** rewriting pages with a Python helper converted five files from the working
|
||
tree's **CRLF to LF**, which made `index.html`'s nav and footer differ from every other page's and
|
||
turned the nav/footer gate red for all 15 pages at once. The cause looked like a content change and was
|
||
not. Restored to CRLF, BOM intact; `site_gates.py` green.
|
||
## 2026-10-10 (afternoon) — the phone menu works with JavaScript off; the dashboard pictures retaken
|
||
|
||
- **R-903: on a phone with JavaScript off the menu links and the language globe were unreachable** (the three-line
|
||
button is scripted; the list sat off-canvas). `site.css` now has `@media (max-width: 900px) and (scripting: none)`:
|
||
the list sits in the header as a wrapped row and the header scrolls with the page. Script-on pages are unchanged.
|
||
`site.css?v=9` on all 18 pages. Measured in headless Chrome at 376 px, JavaScript off, `/` and `/en/`: links reachable
|
||
0/7 before, 7/7 after; with JavaScript on, the closed menu is as before
|
||
(`documentation/audits/register-shrink-2026-10-10/r903-phone-nojs.txt`).
|
||
- **R-910: all eight `dashboard-*.webp` retaken** on demo-hp's household guest (Launcher, Apps, Paperless-ngx's page on
|
||
controller 0.305.0; Backup → Apps on 0.307.0), hu + en, 1440 × 900, WebP q82. The Apps card shows the new header
|
||
(tags on their own row). Captions unchanged — every caption's claim still holds. Privacy scan:
|
||
`documentation/audits/register-shrink-2026-10-10/r910/`.
|
||
|
||
## 2026-10-10 — two new apps on the apps page: Grocy and LubeLogger
|
||
|
||
- **Two cards added** to the „Otthon & Életmód" / "Home & Lifestyle" section of both apps pages, in the
|
||
same commit: **Grocy** (household stock, shopping list, barcodes, chores) and **LubeLogger** (the family
|
||
car's services, fuel, reminders and costs). Both went through `NEW-APP-CHECKLIST.md` end to end;
|
||
the records are in the catalog and the evidence in `documentation/audits/new-apps-2026-10-10/`.
|
||
- **Assets**: `grocy-logo.svg` is grocy's own `public/img/icon.svg` with its single fill made white, like
|
||
the other logos; `lubelogger-logo.png` is the app's own icon with its dark background dropped and the
|
||
mark made white, the same rule SparkyFitness's PNG follows. The six screenshots are each app's own
|
||
**Hungarian** UI with a household's own data, taken headless on the bench from the published template.
|
||
- **The app count moved 56 → 58** in every place the website states it, in both language sets (15 places
|
||
each): the apps page title, meta description, og:title, twitter:title, the JSON-LD `numberOfItems`, the
|
||
page's own sentence and its stats tile; the home page's meta description, feature heading and line; two
|
||
FAQ answers and their JSON-LD copies; and the technology page's bullet. The open-source tile moved
|
||
**49 → 51** (both apps are MIT). Checked by re-running the same patterns against the new number.
|
||
- **Not changed, and said here instead:** `marketing/facebook/COPY.md` §2 still says „56 alkalmazás" in
|
||
the post drafts, and the post scheduled for 2026-10-12 carries that number. It is already written and
|
||
the brief forbids editing posted text, so it stays — the next post should say 58.
|
||
## 2026-10-08 (evening) — every app logo white; five logo sets renamed to the catalog's names
|
||
|
||
- **Seven coloured logos made white like the other 49** (operator request): Mealie (one fill → white), Homebox (white
|
||
line drawing), Dawarich, Komga, Radicale, Recipe Importer (an in-file `feColorMatrix` filter: coloured and dark parts
|
||
white, white parts see-through; Dawarich keeps only its route, Recipe Importer keeps the white cloud), SparkyFitness
|
||
(PNG, same rule). Checked rendered in headless Chrome against the white logos. These files are also the dashboard's
|
||
logos (the controller and hub builds copy `*-logo.*` from here).
|
||
- **Renamed to the catalog slug** (the dashboard asks for `<slug>-logo.svg` / `<slug>-screenshot-N.webp`, so these five
|
||
showed the grey placeholder and no pictures there): `crafty` → `crafty-controller`, `grampsweb` → `gramps-web`,
|
||
`homeassistant` → `home-assistant`, `plantit` → `plant-it`, `uptimekuma` → `uptime-kuma` (24 files, `git mv`); 40
|
||
references each in `alkalmazasok.html` and `en/apps.html` (paths and `data-gallery` set names).
|
||
|
||
## 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=2` — v2 keeps focus inside the viewer when the last „next" turns off), 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
|
||
Dashboard looks like" — four real screenshots (Launcher, Apps, an app's page, Backup → Apps), each with a one-line
|
||
caption; the technology page's dashboard card gets the Apps and Backup pictures. Hungarian pages show the Hungarian
|
||
dashboard, English pages the English one.
|
||
- Taken on demo-hp's household guest (controller 0.303.0, no warnings, last night's backups OK); 1440 × 900 WebP,
|
||
31–83 KB each; `loading="lazy"`, `width`/`height` set, each links to its full-size picture (no script).
|
||
- `site.css`: `.dash-grid` / `.dash-shot` (two per row, one below 700 px); `?v=3` → `?v=4` on all sixteen pages.
|
||
- Gate 19: a page may only show dashboard pictures in its own language (decoy seen failing first).
|
||
- Evidence, captions-to-capability rows and the privacy scan: `documentation/audits/website-dashboard-2026-10-08/`.
|
||
|
||
## 2026-10-08 — the FAQ's GDPR answer tells the truth about where copies and traffic go (R-900; operator approved the text in chat)
|
||
|
||
- `gyik.html` and `en/faq.html`, the GDPR answer, both the visible text and its structured-data copy: the line „az adataid a
|
||
saját infrastruktúrádon vannak — nem harmadik félnél" / „not with a third party" is replaced. It now says the data lives
|
||
on the household's own box; backup copies are encrypted on the box before they leave and stored at Hetzner in the EU
|
||
(Germany), where the provider cannot read them; remote access goes through Cloudflare, which could technically see that
|
||
traffic; small businesses are pointed to the privacy notice (not published yet, so no link). The „not lawyers" line
|
||
stays. Searched the rest of the site (ASCII fragments, positive control „Hetzner" = 2 per page): no other page makes
|
||
the claim.
|
||
|
||
## 2026-10-08 (later) — the language switch becomes a globe, like the dashboard's
|
||
|
||
- The text link in every page's nav („English" / „Magyar") is replaced by a **globe** (`i-globe` from the sprite): a
|
||
`<details>` whose list names each language in its own language — Magyar, English, in that order on every page. The
|
||
page's own language is marked (bold, a blue rule, `aria-current="true"`); the other item goes to the twin page.
|
||
`aria-label`/`title` „Nyelv" / „Language". Works with JavaScript off; no script added (the controller adds none).
|
||
- Phone: inside the opened menu the globe is the last item and its list opens in place.
|
||
- `site.css`: the globe's rules (desktop and the ≤900 px menu); `?v=2` → `?v=3` on all sixteen pages. There was no
|
||
`.lang-switch` rule to retire — the text switch was unstyled.
|
||
- `404.html` and the hidden prices page carry the globe too (their foreign item points at `/en/`): the shared nav
|
||
must compare equal across the Hungarian set, so they keep what every page carries.
|
||
- Gates: the globe replaces `SWITCH_RE` in gates 3 and 13 (`scripts/CHANGELOG.md`).
|
||
|
||
## 2026-10-08 — the website catches up with the product: true numbers, the missing apps, an English twin of every page
|
||
|
||
The last content refresh was 2026-07-18. Every claim on the eight public Hungarian pages was checked again against
|
||
`documentation/architecture/00-capability-map.md` (and `07`, `09`, `10`, the catalog, the licence read) — the
|
||
table is `documentation/audits/website-refresh-2026-10-08/claims.md`. No redesign; the July tone and layout stay.
|
||
|
||
- **One app count, measured: 56.** The catalog has 58 templates; `plant-it` (abandoned) and `wger` (hidden) are
|
||
not offered to a household (`visibleCatalogStacks`). „53" and „több mint 45" are gone from every page, title,
|
||
meta tag and JSON-LD (`numberOfItems` read 45).
|
||
- **„100% nyílt forráskódú" was false.** The licence read (`audits/licences-2026-10-02/TABLE.md`): Plex and Emby are
|
||
proprietary; n8n, Outline, Tandoor and SparkyFitness carry restricted licences; Recipe Importer is Felhom's own.
|
||
Now „szinte mind"; each exception carries its own badge (*Zárt forráskód* / *Korlátozott licenc* /
|
||
*Felhom saját*); the stat reads 49 open source.
|
||
- **The apps page shows what a household can install.** Plant-it and wger cards cut; ten cards added (Dawarich,
|
||
Docmost, Grimmory, Homebox, Karakeep, Mealie, MeTube, Radicale, Recipe Importer, SparkyFitness), Hungarian
|
||
from the catalog's own text. FileBrowser stays, badged *Beépített* (it is on every box, not in the catalog).
|
||
Calibre-web → Calibre-Web Automated (the image the catalog ships). Twelve logos pointed at a missing `.svg`
|
||
and fell back to `.png` through an `onerror` — they point at the `.png` now.
|
||
- **Claims cut or softened** (no capability row): firewall/Fail2ban/geo-blocking/WireGuard-for-households, RAID,
|
||
„pillanatkép minden változtatás előtt" (the update path takes a backup and undoes itself — that is now said),
|
||
„egy új gépre visszaállítható", the „önálló modell", „bármilyen nyílt forráskódú alkalmazás telepíthető",
|
||
household VPN, „soha nem vész el" ×4, the off-site „havi pár száz forint" (the operator's own price is per
|
||
100 GB), „TV-re streamelés hamarosan" (now „még nincs").
|
||
- **Added, each on a PROVEN-LIVE row:** backups on three levels (on the box, a second drive, encrypted off-site);
|
||
careful app updates (tested versions only, a backup first, the box undoes a failed update); the dashboard in
|
||
Hungarian or English; OS security updates (the kernel lane is not claimed).
|
||
- **`technologiak.html` showed a file-dump footer** („Summary: 13 files included, 218 skipped") under `</html>`
|
||
— removed; a gate now refuses text after `</html>`.
|
||
- **`404.html`** — nginx's `error_page 404` pointed at a page that did not exist. Hungarian first, one English line,
|
||
a link home; `noindex`.
|
||
- **The English twin of every public page** (operator ruling 2026-10-08; choice B — public at once):
|
||
`/en/`, `/en/apps`, `/en/technology`, `/en/backups`, `/en/faq`, `/en/contact`, and `/en/download` moved onto the
|
||
new English nav and footer. `hreflang` hu/en/x-default both ways, `canonical` to itself, `lang="en"`, English
|
||
JSON-LD (the FAQ's JSON-LD is now rebuilt from its visible answers on both pages — the Hungarian one had drifted
|
||
from them), an English `og-image-en.png` (the card carries Hungarian text). The English footer says Felhom
|
||
serves households in Hungary. The contact form posts to the same `/api/contact` with English subject labels
|
||
marked „(EN)"; `?tema=` takes the same values.
|
||
- **The language switch** — one nav item on every page, „English" / „Magyar", pointing at the twin; it replaces the
|
||
header link R-559 put on the two download pages. No redirect, no cookie.
|
||
- **`sitemap.xml`** lists both languages with `xhtml:link` alternates.
|
||
- Gates: `scripts/site_gates.py` gates 3 and 13–18, eleven new decoys (see `scripts/CHANGELOG.md`).
|
||
|
||
**Published:** push to `main`, git-sync. No `site.css` or `icons.svg` change, so no cache-bust bump.
|
||
|
||
## 2026-09-18 — an English download page (R-559)
|
||
|
||
- **`website/en/download.html`** — the English twin of `letoltes.html`. Same installer, same checksum,
|
||
same structure; `<html lang="en">`, its own English nav and footer, `hreflang` alternates both ways
|
||
(`x-default` points at the Hungarian), and an entry in `sitemap.xml`.
|
||
- **`letoltes.html` changed by FOUR lines and nothing else**: three `hreflang` alternates and one
|
||
`English` link in the page header. The link is deliberately **not** in the nav — the nav is a shared
|
||
block that `site_gates.py` pins across every page, and the gate convicted the first attempt, which
|
||
is how the link found its right home.
|
||
- **The rest of the marketing site stays Hungarian** (operator ruling 1b, 2026-09-17).
|
||
- **New gate 12: the two download pages must name the SAME installer file and the SAME checksum.**
|
||
Publishing an ISO now means editing a filename, a size and a 64-character hash on two pages; update
|
||
one and forget the other and an English reader checks a new image against an old hash, fails, and is
|
||
told by the page itself not to use the file. Red-proofed both ways.
|
||
- `en/download.html` is registered in `PAGES` and in the new `EN_PAGES` set, which exempts it from the
|
||
Hungarian nav/footer comparison and from nothing else.
|
||
|
||
**Published:** the site's normal path — push to `main`, git-sync picks it up in ~1–2 min. No
|
||
`site.css` change, so no cache-bust bump was needed.
|
||
|
||
# website/ changelog (newest on top)
|
||
|
||
## 2026-09-15 — New page: /letoltes (the installer download)
|
||
|
||
The volunteer guide sends people to `felhom.eu/letoltes`; the page did not exist. It now names installer
|
||
**1.27.1**, its size and SHA-256, how to check the sum on Linux/Mac and Windows, and — first — the disk
|
||
warning: the installer erases the disk you choose, never picks one, unplug the backup drive, call the
|
||
operator if unsure. `noindex` (it is for people holding the guide). Same skeleton as the other pages, no
|
||
nav entry; added to `sitemap.xml` and to `scripts/site_gates.py` PAGES; site gate OK. Published together
|
||
with the ISO (round trip verified first), so the link never pointed at a missing file.
|
||
|
||
## 2026-07-19 — Restored: the index grid background
|
||
|
||
The subtle grid behind the hero was **not** removed on purpose. It lived as a fixed `body::before` in
|
||
`index.html`'s inline `<style>` block and was dropped when `bed8675` ("D3 Part 2") migrated the page
|
||
onto the shared `assets/site.css`; `dd54e4c`, the commit that created `site.css`, has no
|
||
`body::before` at all. A porting omission, and nothing took its place. No asset was lost — it was
|
||
pure CSS (two stacked `linear-gradient`s), so there was nothing missing from the worktree to notice.
|
||
|
||
Restored, not redesigned: same 50px cells, same 1px lines, same 3% opacity, same `position:fixed` /
|
||
`z-index:-1` so it does not scroll. One deliberate difference — the accent is the v2 `--blue`
|
||
`#0083D8` instead of the retired legacy `#0088cc`, which `site_gates.py` bans. Scoped to
|
||
`body.page-index`, because index is the only page that ever had it.
|
||
|
||
`site.css` cache-bust bumped `?v=1` → `?v=2` on all seven pages (nginx caches 7 days). Verified live
|
||
on desktop and in a 376px viewport: grid renders, no horizontal overflow, mobile layout unchanged.
|
||
|
||
## 2026-07-18 — Pre-Facebook content refresh: capability-map alignment + „Zárt teszt" landing
|
||
|
||
The site's audience changes from zero-stakes to real Hungarian households arriving from a Facebook
|
||
post, mostly on phones. Every claim re-checked against
|
||
`documentation/architecture/00-capability-map.md`; overclaims cut, the last week's shipped
|
||
capabilities added. No redesign — the design language, nav, footer, and CSS are untouched.
|
||
|
||
- **Naming ruling applied — „Felhő Felügyelő" is gone (0 occurrences site-wide).** The brand is
|
||
**Felhom**; the customer-facing interface is the **vezérlőpult** (matching the controller login
|
||
page). 14 occurrences replaced across `index.html` + `technologiak.html`, incl. `<title>`,
|
||
meta description, keywords, og/twitter descriptions, and the JSON-LD `description`.
|
||
- **`index.html` — new „Mit tud a doboz ma?" section** (8 cards, every one map-traceable):
|
||
photos/documents/media, **Hálózati megosztás** (Windows Intéző + Mac Finder, map §E
|
||
PROVEN-LIVE 2026-07-18), two-tier automatic backup, **the recovery code only the customer
|
||
knows** (zero-knowledge wording, map §A escrow PROVEN-LIVE), 53 apps, remote monitoring +
|
||
automatic updates, LAN-works-when-the-internet-is-down, restore-when-something-breaks.
|
||
- **`index.html` — new „Zárt teszt" section** (the Facebook post's landing target): what being a
|
||
tester means, and the **stated limitations** — one shared household password for the vezérlőpult
|
||
(map §E multi-user = MISSING), **TV-re streamelés hamarosan** (map §E DLNA = MISSING), and an
|
||
explicit "you will find bugs, that's the point". CTA wires to the **existing, live**
|
||
contact-mailer as `/kapcsolat?tema=zart-teszt`; no new backend.
|
||
- **`kapcsolat.html`** — new „Zárt teszt — jelentkezem tesztelőnek" subject option + its label
|
||
mapping (mail subject `Jelentkezés — zárt teszt`), and a `?tema=` preselect that ignores
|
||
unknown values.
|
||
- **`og:image` was a 404 site-wide** — every page pointed at `/assets/og-image.png`, which did not
|
||
exist (only `.svg` did). A branded **1200×630** card is now generated from the existing logo and
|
||
brand tokens, plus `og:image:width/height/alt`. This was load-bearing for the Facebook post:
|
||
the link previously would have rendered with no image.
|
||
- **App count corrected 45+ → 53** (real catalog count: 53 `*.felhom.yml` templates) in
|
||
`index.html`, `technologiak.html`, and the four `alkalmazasok.html` head tags.
|
||
- **Overclaims cut:**
|
||
- The whole **Kubernetes/k3s section** in `technologiak.html` (+ its TOC entry and the
|
||
multi-node hardware tier) — no customer-facing capability-map row backs it, and it carried a
|
||
bare availability promise („a szolgáltatás nem állhat le") on a page now read by recruits.
|
||
- **Tailscale VPN** → **WireGuard VPN** (Tailscale is not what ships).
|
||
- The **RAID** card → an honest two-tier backup card; the „4-8 TB (RAID)" spec row → „4-8 TB".
|
||
(RAID has no map row; the shipped model is second-drive tier-2 + encrypted offsite.)
|
||
- **`gyik.html` multi-user answer** rewritten in both copies (JSON-LD **and** the visible
|
||
accordion — they must stay in sync): apps do have per-person accounts, the **vezérlőpult has
|
||
one shared household password**. Previously it read „Minden családtag saját fiókot kap".
|
||
- **`biztonsagimentes.html`** — „azonnal értesítést kapsz" softened (map §F health-degradation
|
||
e-mail is IMPLEMENTED, never live-fired), and a new **helyreállítási kód** block stating both
|
||
sides plainly: nobody else can read the remote backup, and without the code neither can we.
|
||
- Gates: `python scripts/site_gates.py` green (BOM, emoji=0, nav/footer identical, analytics,
|
||
no CDN, no legacy tokens, no `<style>`, cache-busted assets). Mobile verified by measurement at
|
||
380 px: `scrollWidth == clientWidth == 365` (no horizontal scroll), CTA 275×58.
|
||
|
||
## 2026-07-02 — TASK-D3: design system v2 re-skin (content-preserving)
|
||
|
||
All seven pages re-skinned to the v2 language (`documentation/design/design-system.md`); URLs,
|
||
copy, meta/SEO, analytics, and the contact form's functional markup unchanged.
|
||
|
||
- **One stylesheet:** the seven near-identical embedded `<style>` blocks (≈120 KB combined)
|
||
extracted into `assets/site.css?v=1` — vendored `@font-face`, the v2 `:root` tokens, a deduped
|
||
shared base, and per-page sections scoped by `page-<name>` body classes. Zero `<style>` blocks
|
||
remain.
|
||
- **Self-hosted fonts:** Plus Jakarta Sans + JetBrains Mono (variable woff2, latin+latin-ext,
|
||
copied byte-identical from felhom-controller) served from `/assets/fonts/` — the Google Fonts
|
||
CDN (a GDPR exposure for a data-sovereignty product) is gone, preconnect hints included.
|
||
- **Icons:** all 182 emoji replaced by a 70-symbol external Lucide sprite
|
||
(`/assets/icons.svg?v=1#i-name`): feature tiles as `.ico-tile` 48px bg-2 squares, heading icons
|
||
`.ico-lg`, inline `.ico`; the alkalmazasok "Open Source" green checkmark image → sprite check
|
||
(`.ico-yes`, blue). CSS-generated ✓/✗/★ content → currentColor mask marks / plain text.
|
||
- **Nav/footer normalized** across all seven pages (index's `#szolgaltatasok` →
|
||
`/#szolgaltatasok`); byte-identical after the active-marker strip.
|
||
- **Visual v2:** navy tokens, single 2px radius, no shadows/gradients/hover-lifts, two-tone
|
||
heading kept as solid `--blue-bright`, `prefers-reduced-motion` respected.
|
||
- **Gates:** `scripts/site_gates.py` (BOM ×7, emoji, nav/footer, analytics, no-CDN, banned
|
||
tokens, style-blocks, `?v=` cache-busting) — baseline 84 problems + 182 emoji → **all green**.
|
||
- kapcsolat: form fields/JS/endpoint byte-identical; live TESZT submission accepted
|
||
(contact-mailer `[OK] Email sent`, resend id logged).
|