225afa0f30d1720f8bc11e0536985ceddb0c78cd
97 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
225afa0f30 |
legal+marketing: privacy notice 1.1 (the domain registration) and a tester kit
gates / gates (push) Successful in 6m4s
The first real tester answered on Prohardver today. His domain is bought in his name (terms 1.1 §4), so his name, address, e-mail and phone leave this house - and the privacy notice did not say so. Now it does, before the purchase. Operator rulings, asked before the work and recorded in CONTEXT.md: - Registrar for a tester's .hu domain: Nethely Kft. - The tester's zone lives in FELHOM's Cloudflare account during the test. This is what the build already assumed (day0-install A.1 + the one-zone token guard of 01 §7 / R-138 option C) and nothing had recorded it; it answers open point 9 of the privacy draft. Privacy notice 1.1: - New §10 "A domained regisztrációja": exactly the four fields the .hu Domainregisztrációs Szabályzat §1.2.2.1 requires of a natural person (the optional mother's name, birth date and ID number are NOT asked for), by e-mail, to Nethely and the .hu registry (both named with seats), why, how long, and what is public - a natural person shows as "Természetes személy" only. - It also states whose Cloudflare account holds the zone and that the domain moves to the tester's own account when he leaves. - §11 (recipients) gained the two new names: a recipients list that omits two recipients is wrong. That is the one change beyond the new section. - 1.0 -> 1.1 diff: the only removed/changed lines are the record's title and derived-on date, the version line, and four renumbered headings. marketing/testers/kit/: five files + README, Hungarian, first person. Questions about the machine and the net (each traced to day0-install Part B or the FAQ), the domain data request, the tester's acceptance e-mail (no domain purchase before it arrives), the welcome e-mail with the recovery-code warning, and the operator's own step list. No personal data in any of it - placeholders only. Also: EMAIL-privacy-1.1.md for the existing testers, the legal README pointing at the 1.1 records, and one plural verb the voice sweep missed in the FAQ. |
||
|
|
c0a2953bea |
website: the share card's wordmark is the brand's own, with the blue .eu
gates / gates (push) Successful in 6m15s
The old card's lettering was plain white and in some other face. The card now takes assets/logo-wordmark.png - the same file the sidebar shows - scaled to the old lettering's ink height and alpha-composited in its place, so felhom is white, .eu is blue, and the drawn outline is there. The cloud mark beside it is still the old card's pixels, which were always right. og:image ?v=3. |
||
|
|
c9b9432986 |
website: the contact pages' share text speaks in the first person too
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. |
||
|
|
d328147322 |
website: the share card shows the product, not just the words
gates / gates (push) Successful in 6m13s
The operator went to post the link and found the card out of date: 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. - og-image.png and og-image-en.png rebuilt around the laptop, with the hero's own poster frame on its screen. - scripts/make_og_card.py: the headline, logo and button are lifted as PIXELS from the previous card and composited with `lighter` onto flat --bg-0, because the site's font is a woff2 and nothing here can draw a glyph with it. A new headline therefore CANNOT be made with this script - new words go back to the design tool and this takes that card as its source. The lede lines are gone; 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 reach nobody. A card already attached to a post still does not change - that post must drop the preview and re-add the link after a re-scrape. |
||
|
|
02be8ea7f0 |
website: the reviewer's findings - consent error, reply time, sitemap, voice, clip
gates / gates (push) Successful in 6m12s
A page-by-page review of the live site (1440px and 390px) found six defects and
two editorial questions. The operator answered three questions; the answers and
the evidence are in REPORT-review-2026-10-12.md.
Fixed:
- The contact form showed its consent error before any submit, on both pages:
#privacyError sits outside any .form-group and the hide rule was scoped to
.form-group. Scoped to the page. Checked: load (none) -> submit unticked
(shown) -> tick (gone), with no message sent.
- The consent checkbox is the site's own control now: 24px box, keyboard focus
ring, and a second <label for="privacy"> at 44x44 round it for touch.
- The contact page promised a reply within 24 hours while /feltetelek 1.1 §4
promises no reply time. Now 1-2 days usually, and no promise during the test.
- sitemap.xml was missing /szolgaltatasok and /en/services: 18 -> 20 URLs.
- The pre-shell mobile-menu script still ran on 20 pages and logged
"[mobile-menu] Missing elements" on every one. Removed.
- The sidebar's tester button was btn-outline while the hero's was btn-primary.
- The home page's "Mit tud a doboz ma?" was three bare links; each card now
carries 2-3 of the services page's own items, word for word.
- A plain Facebook link in the footer of all 22 pages. No script, widget or
pixel: the only external hosts any page refers to are still felhom.eu and
stats.felhom.eu.
Voice (operator ruling: "I" everywhere a person speaks): contact, tester and FAQ
pages in both languages, and the home and services pages that repeat the same
promises. An inclusive "we" (you and I, talking) stays plural, and the legal
texts are untouched. Each FAQ answer exists twice (JSON-LD + visible) and gate 18
holds them equal - it caught the five answers whose markup split the sentence.
Hero clip rebuilt: Immich first, so the poster is a wall of real photographs;
the Jellyfin scene starts after the demo's library wall (eleven pieces of poster
art whose licence cannot be quoted from a first-party source); 1.3s of blank
screen cut from the OnlyOffice scene. The film that plays, Caminandes 3:
Llamigos, is CC BY per Blender's own video platform ("licence": {"id": 1,
"label": "Attribution"}) - NOT public domain as website/CHANGELOG.md said
yesterday. That sentence is corrected in place and the film is credited under
the hero caption.
New gate 24: sitemap.xml lists every public page once, with its twin's hreflang
pair, and lists nothing else. Decoy: site/sitemap-missing-page, the exact shape
the reviewer found by hand.
site.css ?v=30; hero clip and poster ?v=2.
|
||
|
|
25ab47eeaa |
website: the two-tone headings are back, and the home page's sections are ruled apart
gates / gates (push) Failing after 6m59s
Two notes from the operator, 2026-10-12: the white/blue heading split was lost in the M3 switch and should return everywhere, the apps page categories included; and the home page's sections ran into one another. - 41 headings get their <span> back (home 5+5, apps 6+6, FAQ 6+7, services 3+3). The style never went away - site.css has styled `h2 span` blue all along; the M3 rewrite dropped the markup. No text changed: the span wraps words that were already there. The three home headings that predate M3 are split where they were split then. - Apps and FAQ categories are new to the treatment: a name with an & splits there, a phrase on its last words. Five one-word headings stay plain. - The home page's sections get a 1px --line rule with 2.75rem of air on each side, so it sits centred in the gap; the first also parts the hero from the page. Home page only. - Blue on the page background measures 7.9:1 - AA at any size. - site.css ?v=28. |
||
|
|
6b6aca900c |
website: the language menu opened off the left edge of the window
gates / gates (push) Failing after 7m1s
The controller's rule centres the menu on the globe (left: 50% + translateX(-50%)). On the website the globe sits at the far left of the sidebar footer, so 60px of the 120px menu hung outside the window and both labels were cut. Anchored to the button's left edge in site.css instead, opening rightwards into the sidebar; shell.css stays a verbatim copy. Measured after the fix: menu x 24->144 inside a 240px sidebar. site.css ?v=27. |
||
|
|
b0ef27e914 |
website: the laptop screen moves - six real apps behind the cut-out frame
gates / gates (push) Failing after 7m17s
The operator recorded the six scenes and ruled on their length: use them whole, "they had been cut as I liked them". Jellyfin, Tandoor, OnlyOffice, Immich, RomM, Paperless, 0.6s crossfades, 36.6s looping at 904x556. - hero-clip.mp4 (1 134 KB) + hero-clip.webm (1 295 KB) + hero-poster.webp (53 KB), one set for both languages: the recordings are the same on / and /en/. - The hero <video> sits in the frame's cut-out hole at z-index 1, the frame above it at 2. No autoplay attribute: the page's script starts it when the hero is on screen, pauses it when it leaves, and never starts it under prefers-reduced-motion. With JS off the poster stays. - make_hero_clip.py reads each scene's own length (ffprobe) instead of cutting every one to a fixed window, and the xfade offsets count from the running sum minus one fade per transition already made. - site.css ?v=26 on all 22 pages. NOT verified: playback in this workstation's Chrome, whose media pipeline loads nothing at all today (a 1 KB generated WAV blob stalls the same way, with no error) - which rules the clip out as the cause. Geometry, layering and the poster frame were verified in the browser. Jellyfin, Paperless and RomM were filmed on those projects' own public demo sites; the films in the Jellyfin scene are public-domain prints. |
||
|
|
7733d7b754 |
website: prepare the moving laptop screen - the cut-out frame and the clip builder
gates / gates (push) Failing after 14m28s
The operator asked for the laptop's screen to show a few seconds of real apps
running. His decision: he records the raw clips, the assembly is built here. So no
Playwright and no new dependency - ffmpeg 7.1.5 is already on DooPlex.
NOT ON THE PAGE YET. The live hero still shows the still picture; this commit is the
two finished pieces plus the measurements behind the format choice.
scripts/make_hero_clip.py
NN-appname.ext in -> scaled and centre-cropped to the screen's 1.626:1, crossfaded,
out as mp4 (h264) + webm (VP9) + a webp poster. Runs on DooPlex; Windows has no
ffmpeg. Not part of any build, gate or deploy: the site has no build step, so the
output is committed like any other picture. Proven end to end against six
placeholder scenes built from the repo's own app screenshots (21s loop -> mp4
480 KB, webm 609 KB, poster 83 KB).
WHY NOT A GIF - measured, six crossfaded scenes:
904x556 mp4 331 KB | webm 411 KB | GIF 2676 KB for HALF the length
1130x696 mp4 775 KB | webm 1196 KB | webp 2551 KB
A GIF is ~11x the mp4 for the same seconds and dithers to 256 colours on a dark UI.
website/assets/hero-laptop-frame.webp
The laptop render with its SCREEN CUT OUT to transparency, so a clip plays under the
bezel with the glass reflection over it. The reflection is PAINTED: lifting the
bright pixels out of the AI-drawn screen dragged a ghost of the drawn UI along.
Hole: left 11.041% top 12.345% width 79.817% height 64.305%, ratio 1.626:1. Two
pixels of slack - a tight rect showed the drawn sidebar's highlight, a loose one
showed page background at the top left; both were seen in the browser.
The page will load it as <video muted loop playsinline preload="none"> with the first
frame as poster, started only on scroll-into-view and never under
prefers-reduced-motion. First paint: frame 59 KB + poster ~80 KB against today's single
57 KB still; the ~330 KB clip comes after, or never if the visitor does not scroll
there. No "loading" graphic needed - the poster IS the loading state.
The recording brief is in E:\felhom-video\README.txt (outside the repo: the raw files
are large and the repo is public).
|
||
|
|
bb69a73330 |
website: four more notes - first person, the globe's well, the touching tables, the submenu label
gates / gates (push) Failing after 5m21s
1. THE HOME PAGE SPOKE ABOUT THE OPERATOR IN THE THIRD PERSON ("Ha irsz, o valaszol")
while the page it links to is in the first ("Ha irsz, en valaszolok"). Both home
pages now read "Nagyfenyvesi Viktor vagyok, a Felhom mogott en allok" / "I am Viktor
Nagyfenyvesi, and I am the one behind Felhom", and the link after it is "Rolam
bovebben" / "More about me" rather than repeating the question the sentence has just
answered. The legal pages keep the formal third-person name, which is their job.
2. 36px OF DEAD SPACE UNDER THE LANGUAGE GLOBE, and most of it was A LEAK GATE 22
COULD NOT SEE. The old chrome's
nav { position: fixed; top/left/right: 0; padding: 20px 0;
backdrop-filter: blur(12px); border-bottom: 1px solid var(--line);
z-index: 200 }
is a BARE ELEMENT selector, so it matched <nav class="sidebar"> too - and .sidebar
declares none of those, so all of them were in force on the sidebar. Scoped
body:not(.shell); the footer row's own padding went 16px -> ~8px.
Gate 22's first half compares selectors present in BOTH stylesheets, and `nav` is not
a selector shell.css ever writes, so this shape was outside its field of view. It now
has a SECOND HALF: an unscoped bare nav/header/main/aside rule in site.css is a
failure, because those elements ARE the shell (<nav class="sidebar">,
<header class="mobile-topbar">, <main class="content">). It convicted a second live
one on its first run: R-903's `@media (max-width:900px) and (scripting: none)
nav { position: static }` had been overriding the sidebar's own position on a phone
with scripting off. `footer` is deliberately NOT on the list, with the reason beside
it: the shell carries the website's own footer.
Decoy site/bare-element-rule-reaches-shell, seen to convict.
3. THE COMPARISON TABLE AND THE TWO CARDS under "Miert a sajatod?" were touching: .vs
ends on its own border and .band opens with a 2px blue rule, so they read as one
block. 2rem between them.
4. "MINDEN ALKALMAZAS" -> "AZ ALKALMAZASOKROL" / "About the apps" on all 22 pages. 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 tudnivalok" box are. The en-nav-drift decoy
was re-anchored on the new label.
Checked at 390px and 1440px on all 21 pages: no sideways scrolling, footer inside the
content column, the renamed item on every page. site.css?v=25.
|
||
|
|
0ef0b106f6 |
website: the operator's seven notes - a services page, the hero, and 100 dead links
gates / gates (push) Failing after 6m51s
Reported from his own screens. Five defects, two design.
1. THE CATEGORY ANCHORS WERE DEAD - all 100 of them. The sidebar's five app-category
links pointed at #fajlkezeles-irodai and friends; the ids are #fajlkezeles and
friends. 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 stays put.
New gate 23 resolves every in-site #fragment against the page it names (360 today).
It convicted two more on its first run: the home page's four hero tiles pointed at
/alkalmazasok#immich, which no page had ever carried, and the FAQ's contact button
pointed at a home-page section that had moved out. Every app card now carries its
slug as an id - taken from the card's own logo file, which gate 21 already ties to
the catalog, so the ids cannot drift from it silently.
Decoy site/dead-fragment puts the operator's own bug back and the gate convicts.
2. SZOLGALTATASOK IS A PAGE: /szolgaltatasok + /en/services, registered in TWINS, URL
and SHELL. The ten capability items moved VERBATIM out of the home page; the home
keeps the promise sentence, the three group names as links and a button, and is 345
Hungarian / 434 English words shorter. The .caps rules stopped being .page-index-
scoped, because the block now lives on a page with a different body class.
3. THE HOME HEADLINE is back in the hero column beside the picture, two lines with the
second in --blue-bright at clamp(2.1rem, 4.4vw, 3.2rem). M3 had moved it into
.page-header - the INNER pages' heading - so it shrank to 2.1rem and the domain
badge was stranded beside it.
4. THE HERO PICTURE is the real dashboard in a laptop. The frame is the operator's own
supplied render; the screen is dashboard-start-{hu,en}.webp composited into it, so a
visitor sees a real box's Launcher rather than a drawing of one - the supplied
screens are AI-drawn and misspell app names. 57 KB, named dashboard-laptop-<lang>
so gate 19 holds it to the page's language.
5. .page-lede HAD NO CSS AT ALL on 16 pages: a bare paragraph, full width of the
content column, hard against the box beneath it. 760px measure, centred over the
box, air beneath; left-aligned on /szolgaltatasok, which has no centred box.
6. THE SIDEBAR LOGO: the wordmark shipped at 0.67x the mark's width where the real
lockup (assets/logo.png, measured: mark 492px wide, wordmark 631px) has it at 1.28x.
Mark 112px, wordmark 25px tall, 28px less vertical padding.
7. SCROLLBARS are the page's own now. The first attempt missed the viewport's: it is
painted from <html>, and a `body.shell ::-webkit-...` rule only reaches scrollers
inside the page.
Also: the two Latin font subsets are preloaded. With font-display: swap the page
reflowed after first paint - measured at 1339px on /alkalmazasok#media.
Checked at 390px and 1440px on all 21 pages: no sideways scrolling, footer inside the
content column everywhere, drawer opens with all 13 items. site.css?v=24.
|
||
|
|
a7480172ab |
gates: site gate 22 - the media-aware CSS leak check the phone bug needed
gates / gates (push) Failing after 12m29s
The two defects the operator found on his own phone are fixed and live since
5aeb36b5; this is what pins them so they cannot come back silently.
site_gates.py gate 22 parses site.css and shell.css into
(media context, selector, declarations) and fails on any property site.css
declares on a selector shell.css also styles that nothing overrides - neither
shell.css itself nor a `.shell ...`-scoped reset. site.css loads first, so
"later wins" is per PROPERTY, not per rule. Today: 689 site rules vs 119 shell
rules, 9 shared selectors, 0 leaks. .hamburger-box / .hamburger-line are an
explicit allow-list with the reason beside them.
It is media-aware precisely because the check it replaces was not. The STOP-1
leak diff excluded @media blocks and reported "exactly six" leaking
declarations; the real number is forty, and the worst of them
(@media (max-width: 900px) .nav-links { position: fixed; right: -100% })
parked the drawer's menu off-canvas and shipped.
Two decoys in test_gate_decoys.py, both the exact shape that went live, both
seen to convict:
site/shell-css-leak-in-media the body:not(.shell) scope taken back off that
one rule - the gate names the media query, the
selector and `right: -280px`
site/footer-outside-main <main> closed early on gyik.html - gate 3b's line
They plant and restore BYTES, with the anchor translated to the file's own line
ending: these files are CRLF in a Windows worktree and LF in a Linux one, and
replace_in's text-mode round trip would have rewritten a whole file on one side.
Also: CHANGELOG entries for both areas, the M3 report corrected where it quoted
its own wrong "exactly six", and one plain-language STATUS line.
|
||
|
|
5aeb36b5bd |
website: fix the phone menu and the footer column - both live defects
gates / gates (push) Successful in 6m42s
Reported from a real phone. Both were mine, both shipped in the switch. 1. THE PHONE MENU WAS EMPTY. The drawer slid open correctly but had no items in it. site.css's OLD mobile nav was still reaching the shell's sidebar: under @media (max-width: 900px) it sets .nav-links to position:fixed; right:-100%, which parked the menu off-canvas INSIDE the drawer. Measured at 390px and 860px: position fixed, right -280px. The cause is a hole in my own check. At STOP 1 I diffed the two stylesheets' declaration sets and found "exactly six" leaking declarations - but that diff EXCLUDED @media blocks. Re-run media-aware, the real number is FORTY, and the worst of them only apply below 900px, which is why desktop looked right and a phone did not. A check that silently skips part of its subject is not a check; this one reported a confident, wrong number. Fixed at the source rather than per-property: 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 future non-shell page still works. .hamburger-box and .hamburger-line are deliberately left unscoped: the shell's burger uses them. Leaks after the fix: 40 -> 0. 2. THE FOOTER RENDERED AS A SECOND COLUMN at the top right on 16 pages. body is a flex row on a shell page, and my insert only moved the footer inside <main> when the page ENDED with </main>; pages with scripts after it fell through and left the footer as a direct child of body, i.e. a flex sibling of the sidebar. Moved inside <main> on all 16, each move asserted to have landed inside. Both are now gated: gate 3b requires every shell page's footer to be INSIDE <main class="content">, red-proofed by putting one outside and watching it convict. site.css?v=23 / shell.css?v=23. |
||
|
|
bd708b3593 |
report: M3 live - the changelog, the session report and the operator's screen
gates / gates (push) Failing after 3m58s
Records what shipped, the two operator decisions as answered, what the website and the controller now share and how a change flows between them, and the five faults that measurement caught before the switch rather than after. head-before.json / head-after.json are kept as the evidence that the switch changed no SEO-bearing tag: the only difference across 19 pages is the dash substitution inside the two FAQ pages' JSON-LD. |
||
|
|
6059505216 |
website: M3 goes live - the whole site switches to the controller's shell at once
gates / gates (push) Failing after 13m11s
Part D. Every public page now wears the controller's frame around the website's
own content. One commit, as asked: never half old, half new.
20 pages switched (12 Hungarian incl. the hidden prices page, 8 English)
website/preview/ deleted entirely - A, M1, M2 and M3 studies all gone
robots.txt: the Disallow: /preview/ line removed with them
site.css?v=22 / shell.css?v=22 on every page
PROVED before pushing, not after:
* HEAD TAGS: title, meta description, keywords, author, robots, canonical, every
hreflang, all seven Open Graph tags, all four Twitter tags and the JSON-LD
captured on all 19 pages before the switch and compared after. The ONLY
difference anywhere is the dash substitution inside the two FAQ pages'
FAQPage JSON-LD - verified by applying the same substitution to the "before"
copy and getting an exact match. Nothing else moved.
* VISIBLE TEXT: identical to the live pages word for word, legal texts identical
with no substitution permitted at all.
* No page is left noindex (the two download pages' noindex,follow is their own,
pre-existing and unchanged), no page mentions /preview/, every page has a
footer, no page overflows at 390px.
THE HEAD-TAG DIFF EARNED ITS PLACE. 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.
The diff caught it; nothing on the rendered page would have. The generator now
uses the live head for EVERY page including the home one.
szolgaltatasok-nonpublic.html was converted too. It is in no menu and was not in
the brief's list, but leaving one page on the old chrome would have left the site
half-switched - which is the one thing part D was not allowed to do.
scripts/site_gates.py: SHELL is now the real page set; MOCKUPS is empty; gate 3's
old nav/footer loop keeps working for any page added later WITHOUT the shell, and
skips the ones that have it.
|
||
|
|
58e308352f |
website: the shell keeps the footer - it is the only route to the legal pages
gates / gates (push) Failing after 11m54s
Caught BEFORE the switch, not after. Stripping the website's chrome also stripped <footer>, and the shell has none of its own. Every one of the 19 pages had lost: the link to the Adatkezelesi tajekoztato and the Feltetelek, the operator's name, info@felhom.eu, and the copyright line. The legal pages are in no menu, so they would have become unreachable from navigation entirely. The footer is now carried VERBATIM from each live page into the bottom of the content column. Verified on all 19: footer present, legal link present, e-mail present, and the footer sits INSIDE <main class=content> rather than becoming a flex sibling of the sidebar. Gate 3b now checks the footer as well as the sidebar across the shell set, so the guarantee gate 3 used to give is not lost in the move. Red-proofed: removing one page's footer convicts. |
||
|
|
d5199ca634 |
website: the English home page is now a true twin of the Hungarian one
gates / gates (push) Failing after 14m13s
Operator's decision at STOP 2: mirror it first, then switch. It was the old design reframed - 10 786px tall against the Hungarian home's 4 186px - because the /preview/ round never produced an English twin. Every string is either lifted VERBATIM from the live English home (the ten capability cards, the four dashboard captions, the five steps, both sides of the cloud comparison, the three closed-test cards, the apps count line) or is one of twelve entries in a TRANSLATED table - faithful translations of Hungarian sentences the /preview/ round introduced, which therefore have no English original. Nothing is invented, and the English promises nothing the Hungarian does not. The generator ASSERTS that each string it lifts is still present upstream, so if the live English page changes shape the build fails rather than silently shipping a page with holes in it. Its <head> is still the live page's, so title, description, canonical, hreflang, Open Graph and JSON-LD survive untouched. 35.8 KB -> 25.4 KB. Gate 16 (no Hungarian on an English page) passes, which matters here because this is the one page where I wrote English prose rather than moving it. |
||
|
|
91ba50ea2c |
website: the sidebar button fits when the apps group is open
gates / gates (push) Failing after 13m42s
On /alkalmazasok the Alkalmazasok group renders expanded, which gives the sidebar a 16px scrollbar and narrows it from 239 to 224. At .95rem the Hungarian label wrapped to two lines there (the English one still fitted, which is why it showed on one page and not its twin). Sized to the narrow case, measured not guessed. |
||
|
|
9b90a02bb4 |
website: the contact pages' header no longer slides under the sidebar
gates / gates (push) Successful in 8m20s
kapcsolat.html and en/contact.html keep their page header OUTSIDE <main>. Left there, the converted header became a FLEX SIBLING of the sidebar: measured, it took 401px and pushed .content from x=240 to x=642, so the header sat behind the sidebar and the form rendered at two thirds width. Anything before <main> now moves inside it. Checked structurally across all 19 pages rather than by looking at two: no page has stray top-level content, and every .content starts at x=240 with the full 1185px column. Found by measuring where elements actually sit, after a screenshot looked wrong - the same check also confirmed the two elements at x=-9999 on those pages are the form's intentional spam honeypot, not a layout fault. |
||
|
|
f6044dc0a7 |
website: long checksums and URLs no longer scroll a phone sideways
gates / gates (push) Successful in 8m15s
Measured at 390px on the LIVE pages, so this is pre-existing and not something the shell introduced: /letoltes scrollWidth 609 - the 64-character SHA-256 inside <code> /adatkezeles scrollWidth 478 - a long facebook.com legal URL used as link text and the same on their English twins. overflow-wrap: anywhere changes only where the line breaks; selecting and copying still yields the whole unbroken string, which matters for a checksum. The legal pages' words are untouched - this is CSS. Small enough to fix in the session rather than file. |
||
|
|
0b34be8449 |
website: M3 part C - all 18 remaining pages moved into the shell
gates / gates (push) Successful in 8m50s
Staged under /preview/m3/. Nothing live. 19 shell pages in total with the home.
Each page keeps its own <head> byte-for-byte apart from two additions (shell.css
and the no-js/js hook), so title, meta description, canonical, hreflang, Open Graph
and JSON-LD all survive the move untouched. The body loses the website's
<nav>/<footer> and the old hamburger script, and gains the shell.
PROVED, not assumed - a word-level diff of every page's visible text, live vs
shell, with the nav and footer removed from both:
* 18 of 18 pages: visible text IDENTICAL after the one allowed substitution
* adatkezeles and feltetelek: identical with NO substitution permitted at all.
The legal texts are reviewed documents; the frame changed, the words did not.
That check earned itself immediately. The first version of the page-header
transform rebuilt the block from its <h1> and first <p> and SILENTLY DROPPED the
rest: the "Fontos tudnivalok" / "Good to know" disclaimer banner on both apps
pages and the 404's English line - 168 words across three pages. Nothing looked
wrong on the page. The diff found it.
Em dashes: 318 replaced with the Hungarian gondolatjel across 16 pages (gyik and
en/faq 104 each). The FAQ pages' JSON-LD is swept with the SAME substitution, so
gate 17's equality with the visible answers still holds - it does, on both.
scripts/site_gates.py:
* SHELL now holds all 19 pages.
* is_en(): a page is English if it is a TWINS value OR lives under an en/
directory. Without the second half the dash-language, <html lang> and
no-Hungarian gates all judged preview/m3/en/* as Hungarian - 30 false fails.
* norm_block() also drops `is-open` and `aria-expanded`, because the shell
renders the nav group containing the active page open, exactly as the
controller does, and that legitimately differs per page.
The last change LOOSENS a check, so it was red-proofed BOTH ways: a one-character
difference in one menu label still convicts, and a state-only difference (the
active marker moving to another item) correctly does not.
One generator now owns the shell. The home page's content comes from m3.py and its
shell from the same function every other page uses, so the two cannot drift - which
they already had, and gate 3b caught it.
|
||
|
|
11242c5110 |
website: AA on the shell's copied button and group label
gates / gates (push) Successful in 6m58s
Measured on the deployed M3 page: .btn-primary 4.01:1 (white on --blue, 13.6px/600) and .nav-group-label 3.14:1 (--text-3), both under the 4.5 floor. This is R-930 arriving a second time by a different route: fixing .cta-button on the website did not fix the CONTROLLER's button, and the shell imports it. Same remedy the operator already chose - 1.2rem/700 puts the label in WCAG's large-text band where 3:1 applies - so --blue stays untouched. The sidebar's own CTA becomes an OUTLINE button rather than a filled one: blue on transparent passes comfortably, and a 19.2px filled button does not fit a 240px sidebar without wrapping. Measured both ways rather than guessed. The controller has both defects on its own surface. Not fixed here - that repo is read-only this session - so it is going to the register. |
||
|
|
cada79e990 |
website: M3 home page has one heading, not two
gates / gates (push) Successful in 7m21s
The page header and the hero both carried a title, which read as two headings stacked. The brief's shape is one: .page-header holds the h1 - and it holds today's indexed headline, 'Sajat felhod, sajat szabalyaid', unchanged - and the hero row below is the lede sentence plus the button beside the dashboard window. |
||
|
|
71df90f9fc |
website: neutralise the six declarations that leak into the shell
gates / gates (push) Successful in 7m3s
shell.css loads after site.css, but later-wins is per PROPERTY, not per rule.
Where site.css declares something the controller's rule does not, the website's
value survives inside the shell. Measured: exactly six declarations, three
selectors, and the first one was visibly broken on the deployed page -
.nav-links display:flex + gap:32px -> the sidebar menu rendered as a
HORIZONTAL row spilling across the content column
.lang-globe-menu top + right -> fought the controller's bottom/left
.page-header padding + text-align -> the website's centred subpage header
fought the controller's left-aligned flex row
Reset in site.css, the website's own file, so shell.css stays a verbatim copy.
Found by diffing the two files' declaration sets per selector rather than by
spotting the one that happened to be visible.
|
||
|
|
80659232bc |
website: M3 part A - the controller's shell, and the home page inside it
gates / gates (push) Successful in 6m58s
The direction the operator chose: the controller's FRAME around the website's own
content. Staged at /preview/m3/, noindex, nothing live.
website/assets/shell.css - 117 rules COPIED VERBATIM from felhom-controller
style.css @ dcd89364a4 (sidebar, mobile top bar, off-canvas drawer, and the
component atoms the restyled pages use: btn, alert, app-info-card, launch-*,
stack-detail-card, form-*). Exactly ONE rule is not verbatim and says so:
body.shell { display:flex; min-height:100vh }, which lives in the controller's
base rather than in a component, scoped to .shell so other pages are untouched.
The generator NAMES every rule it copies and REFUSES to write the file if one has
disappeared upstream. That is not ceremony: it already caught two things this
session. It refused because .sidebar::-webkit-scrollbar does not exist (only the
-track override does), and because prefers-reduced-motion is split across FIVE
separate blocks in the controller - reading only the first would have silently
lost four rules. The M1 round lost a rule exactly this way.
The bare `body { flex-direction: column }` that broke M1's phone layout is copied
this time, by name, as are body.nav-open and the no-js/js pair.
Load order is deliberate: shell.css AFTER site.css. Thirteen selectors exist in
both files with different meanings (.nav-links, .page-header, .lang-globe*, .ico)
- a horizontal site nav there, a vertical sidebar here. Later wins, and a page
that does not load shell.css is completely unaffected.
website/preview/m3/index.html - the home page in the shell. Content is /preview/'s
cleaned text; body carries `shell page-index` so the existing .page-index content
rules (caps, flow, vs, band, who-mini) are reused rather than duplicated. Six
sections, left-aligned headers, the controller's cards. Head tags (title, meta
description, canonical, hreflang) are already the FINAL values, so the switch in
part D needs no head edit.
Four changes from the operator's mockup, each with its reason in the generator:
1. the active item follows the page (the mockups show Inditopult active on all)
2. Teszteles is ALSO a primary button at the top of the lower group - it is the
one action we want and the mockup buries it at the bottom
3. the Alkalmazasok categories are anchors on /alkalmazasok: real URLs, no
JS-only state
4. ADDED GYIK. It is in today's nav; dropping it silently would take a page out
of navigation, which is not a change a restyle gets to make.
scripts/site_gates.py - gate 3 extended rather than duplicated, as asked: a SHELL
set whose pages must carry an IDENTICAL <nav class="sidebar"> after the active
marker is normalised. RED-PROOFED: a one-character change to one menu label on a
second shell page convicts. It also prints "DIFFER" rather than a reassuring
"identical" count when it fails - a false reassurance printed beside a conviction
is the exact defect this repo files rows about.
documentation/design/design-system.md - new "Shell" section: what is shared (tokens
+ shell + atoms), what each side owns, how a change flows (controller first, the
website's copy the same week), and that the cross-repo gate is deliberately NOT
built yet.
|
||
|
|
3129d99b04 |
website: M2's top-bar button no longer wraps on a phone
gates / gates (push) Failing after 7m7s
It broke to two lines at 390px. Hidden below 900px; the hero carries the same call to action three lines lower, so nothing is lost. |
||
|
|
4dc1631570 |
website: the mockup stacks on a phone (the controller's bare body rule)
gates / gates (push) Failing after 6m51s
The controller's mobile layout depends on '@media(max-width:768px){ body {
flex-direction: column } }'. My extractor keys on CLASS names, so it copied every
.sidebar/.content/.mobile-topbar rule and silently dropped that one - and a bare
element rule is invisible to that kind of copy.
The symptom was not subtle once measured: the sticky topbar stayed a ROW flex item,
pushed .content 135px right, and the launcher grid fell to ONE column, making the
front page 15 597px tall on a phone and overflowing mentesek/kapcsolat to a
scrollWidth of 467 in a 375 viewport.
This is a real data point for the shared-design question, not just a mockup bug: a
component-level copy between the two repos misses the element-level rules the
components silently depend on.
|
||
|
|
dd89e1bf99 |
website: the mockup shell flips no-js -> js like the controller does
gates / gates (push) Failing after 6m48s
Measured at 390px: the sidebar stayed an in-flow flex child and squeezed the content column to ~208px, so the launcher grid collapsed to ONE column and the front page became 15 597px tall on a phone; the contact page overflowed horizontally (scrollWidth 467 in a 375 viewport). The cause was not missing CSS - the controller's off-canvas rules were all copied. They are gated on a 'js' class that layout.html sets in an inline head script and the mockup shell did not. Copied that hook verbatim, so the drawer engages only where the drawer script can open it, and the no-js path (sidebar static and full width, burger hidden) is the controller's own. |
||
|
|
8eb321213b |
website: the mockups substitute DOMAIN like the controller does
gates / gates (push) Failing after 7m11s
The catalog writes the customer's domain as the literal DOMAIN and the controller replaces it at render time, so the panels were showing 'photos.DOMAIN'. The mockup now substitutes the same sample domain the rest of the page already uses. |
||
|
|
063ba83e41 |
website: two hidden mockups - M1 "the site is the dashboard", M2 hybrid
gates / gates (push) Failing after 7m1s
Design studies only. Nothing live changes, nothing is linked from a live page, both
carry noindex and /preview/ is already Disallow-ed in robots.txt. felhom-controller
was read ONLY (baseline dcd89364a4); nothing in it was touched.
M1 website/preview/m1/ - the website wearing the controller's shell
index (Indítópult) welcome card + all 58 launcher tiles
alkalmazasok the catalog in the site's own five buckets, vanilla search
mentesek the three backup levels, every number marked "minta"
hogyan / teszteles / kapcsolat today's copy inside the dashboard shell
M2 website/preview/m2/ - short hero beside a window holding a clickable launcher
Real data, not invented:
* 58 apps from app-catalog-felhom.eu @ 8ea72aa: real names, logos, Hungarian
taglines, use cases and first steps out of each .felhom.yml app_info.
* Tile colours reproduce the controller's OWN tileColor (funcmap.go): FNV-1a 32
of the slug -> hue, 45% 38%. No brand_color exists in the catalog, so every
tile here is the colour a real launcher would paint.
* Page copy is today's live website only.
* Category labels are the five buckets alkalmazasok.html already uses. None invented.
The 58 is now measured, not quoted: 60 templates minus plant-it (abandoned) and
wger (hidden) = 58 offered, which is exactly what the site's prose says. See the
R-929 note in the audit folder.
Mockup rules honoured:
* No value pretends to be live - every sample wears a "minta" badge.
* No control does nothing: the disabled sidebar entries (Tárhely, Megosztás,
Rendszermonitor, Beállítások) say "a saját dobozodon működik" rather than
404-ing, and the contact form's submit is disabled with the same kind of hint.
The consent text is the live one, unchanged.
* App panels open with :target, so they work with JavaScript switched OFF and
their text is real HTML a crawler can read - not JS-built content.
* No login form anywhere. No external request, no AI or stock image.
CSS: website/preview/mockup.css is three labelled blocks so the shared-design
report can count them - adapted base (font URLs repointed /static -> /assets),
188 rules copied VERBATIM from the controller, and the mockup-only rules. The
burger is the website's own three-span control, copied rather than hand-rolling an
SVG: the shared sprite carries no i-menu.
scripts/site_gates.py gains a MOCKUPS set, with the reasoning in a comment. The
mockups keep every correctness check (BOM, emoji, banned strings and CDN hosts, no
<style>, cache-busting, <html lang>, clean tail, dashboard-picture language, the
picture-viewer rules) and are excluded from exactly the three chrome-consistency
checks a dashboard-shell study must fail by construction: nav/footer identical to
index.html, the NO_TWIN language globe, and analytics - the last deliberately, so a
hidden mockup cannot pollute the real stats. Delete the set with the directories.
site_gates.py green.
|
||
|
|
0c86e698b0 |
docs: record the placement change and re-measure after it
gates / gates (push) Failing after 5m58s
Every document that described the biography as a home-page section would now be
wrong, so each is corrected rather than left:
ki-all-mogotte.md gains 'Where it ended up' with the operator's reasoning, the
rejected /rolam option, and why the home page keeps a trace
AUDIT.md lever 2 carries a dated revision note (the audit itself is a
record of what was found, so it is annotated, not rewritten)
PREFLIGHT.md re-measured on the deployed page after the move:
1440: 6 780 -> 6 385 px (42% shorter than the old page)
390: 10 865 -> 10 145 px (49% shorter, 23.6 -> 12.0 screens)
sections 10 -> 9, layout families 10 -> 9, still no repeat
eyebrow allowance 4 -> 3, still 0 used
website/CHANGELOG the live change, with the layout bug that the deployed page
revealed and the markup did not
REPORT + STATUS what is live vs what is still waiting on the operator
The numbers moved because a whole section left the page; leaving the old ones in
place would have been a quiet overclaim in the other direction.
|
||
|
|
bb88e73f9e |
website: the home page's who-mini row sits under the button, not beside it
gates / gates (push) Failing after 6m44s
.close-cta is text-align:center, so an inline-flex row flowed onto the same line as the CTA button and pushed the whole group off-centre. flex + max-width 34rem + margin auto puts it under the button as a centred block, with the hairline above it spanning the row rather than the section. Caught by looking at the deployed page rather than trusting the markup. site.css?v= -> 14. |
||
|
|
fb9fe0808d |
website: "Ki all mogotte" moves to the contact pages; the home page keeps a trace
Operator's call after seeing the preview: the biography sat between the dashboard
gallery and "Hogyan mukodik?", interrupting "what it does" -> "how you get it"
with a life story. And its last sentence, "Ha irsz, en valaszolok", is a contact-
page sentence - it belongs next to "Valaszido", not mid-product-story.
/kapcsolat + /en/contact gain the full block (photo + the five approved
sentences). These are LIVE pages, so the bio and the photograph are public
from this commit. Both halves of the twin move together, as the twin rule
requires; the English promises nothing the Hungarian does not, and uses the
site's established "the box" rather than a new term.
/preview/ loses the section and gains a compact row in the closing call to
action: a 56x70 portrait, one line, and a link to the full block. This is
deliberate, not a compromise - the audit's R-11 finding was "nobody is
behind it" on the HOME page, and deleting every human trace from it would
re-open exactly that. The trace now sits where someone decides to write.
A dedicated /rolam page was considered and rejected: five sentences cannot
carry a page, and the alternative was inventing biography to fill one.
The .who* rules are now UNSCOPED (were .page-index .who*), because the block
lives on two pages and will live on the home page's twin later. Following
69035f4af5's lesson: a genuinely shared pattern goes site-wide rather than being
duplicated per page scope. No existing page uses .who, so nothing else moves.
assets/operator-portrait-small.webp - 160x200, 8.4 KB, cropped from the same
original outside the repo, metadata stripped and verified by read-back (0 EXIF
tags, 0 GPS entries, none of the phone's byte sequences present).
site.css?v= -> 13 on all 21 files.
The preview builder asserted a hardcoded "site.css?v=10" and broke the moment the
site moved to 12. It now follows whatever index.html pins and prints it.
site_gates.py green.
|
||
|
|
56c357c074 |
report + plan: the redesign session's record, and the order for the other pages
gates / gates (push) Successful in 6m31s
REPORT-redesign-2026-10-10.md (not REPORT.md: that file belongs to the kernel
night session
|
||
|
|
43b67283c3 |
website: the footer dash swept site-wide, and the primary CTA meets WCAG AA
gates / gates (push) Failing after 14m58s
Two operator decisions from STOP 3, both independent of the home-page switch, which was NOT approved and has NOT happened. index.html still serves the old design; only the footer line and the button change on it. 1. The footer em dash, on all 21 page files (12 HU + 8 EN + the preview). "(c) 2026 felhom.eu - Sajat felhod..." now uses the spaced en dash, which is the correct Hungarian gondolatjel. Done as one sweep because site_gates.py gate 3 requires every page in a language set to carry an IDENTICAL footer, so this could never have been a one-page edit. Gate green: all 14 still match. Scope, stated honestly: 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, testing 24, teszteles 23, index 17/19, ...). The preview page is the only page at zero. The rest is NEXT.md work, page by page. 2. R-930, the operator's choice of the three offered: white on --blue measures 4.01:1, under WCAG AA's 4.5:1 for body text. .cta-button goes to 1.2rem/700, which is >=18.66px at >=700 weight, so WCAG counts it as LARGE text and the floor becomes 3:1 - which 4.01 clears without touching --blue. Darkening the token was rejected because --blue is shared with the hub and controller UIs. Horizontal padding trimmed 32->26px to protect the one-line rule for the longest label; verified in the browser at 390px, not assumed. .cta-button-secondary is unchanged: it already measures 7.17:1. This reaches the primary button on 16 pages, which is the point - the defect was never the home page's. site.css?v= bumped to 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. site_gates.py green. |
||
|
|
6f58c00fe7 |
website: the comparison column and the hero caption meet WCAG AA
gates / gates (push) Failing after 11m58s
Measured on the live preview, not assumed. --text-3 gave 3.14:1 (comparison header), 3.57:1 (comparison rows) and 3.88:1 (hero caption) against their own backgrounds, all under the 4.5:1 floor for body text. The audit's own rule was that the existing 7.56:1 body contrast is an accessibility win to protect, so dimming a column below AA to make it read as 'the quieter half' is a regression, not a style. All three move to --text-2; the two halves of the comparison are still told apart by the accent colour and the bold lead on the right. |
||
|
|
a818b9c576 |
website: the redesigned home page, staged at /preview/ (noindex)
gates / gates (push) Failing after 14m33s
Part C. The live home page is NOT touched: every CSS rule added is a new class
under .page-index, so index.html renders byte-for-byte as before.
website/preview/index.html (BOM + CRLF, noindex, Disallow: /preview/)
Ten sections, ten different layout families. The three repeats the audit found
are gone: why-grid ran 3x and apps-showcase 2x.
- hero: a real dashboard screenshot instead of the logo, sized by its content
instead of a forced 100vh band, no infinite float animation, and a sentence
made of four facts instead of "Professzionalis ... telepites es uzemeltetes".
- the ten capability cards become three labelled clusters. Their TEXT is
verbatim: the audit's own finding was that the writing is right and the
layout is wrong, so only the layout moved. Every hedge ("ha van") survives.
- NEW "Ki all mogotte" with the operator's photo and five approved sentences.
- the 3 cloud-problem cards + the 4 own-server cards merge into ONE two-column
comparison. No new claim about any competitor: all four left-hand sentences
already existed on the page.
- the two tile walls (10 + 7 tiles duplicating pages that already exist) shrink
to a two-item band that keeps the app names and the links.
- section headers are left-aligned and varied, not 11x centred-two-words-plus-
one-blue-word.
Em dashes in the page's own copy: 18 -> 0. Deliberately kept: the 6 in <title>,
meta description, OG, Twitter and JSON-LD (operator decision at STOP 1 - indexed
strings deserve their own pass), and 1 in the shared footer, which gate 3 requires
to be identical across all 14 pages. Both stated, neither swept silently.
JetBrains Mono is no longer fetched. Exactly 13 characters were loading 31 KB:
the 1..5 process badges, the 01..05 service numbers, and - the audit missed this
at first and it is corrected in the file - the 3/2/1 of the backup rule.
assets/operator-portrait.webp 720x900, 93 KB
Cropped from an original that stays OUTSIDE this public repo. All metadata
stripped and VERIFIED BY READ-BACK: 0 EXIF tags, 0 GPS IFD entries, and none of
EXIF/XMP/ICCP/samsung/SM-A705FN/2023:10:18 appear anywhere in the bytes. Built by
re-writing the pixels into a fresh image, so the source info dict cannot travel.
Honest correction to the brief's premise: this photo had NO GPS tag to begin with.
scripts/site_gates.py
preview/index.html registered in NO_TWIN, with the reason. It cannot go in TWINS:
gate 3 wants its nav identical to index.html's (globe -> / and /en/) while the
twin check wants a pair's globe pointing at the pair's own URLs. The English twin
is written in the same commit as the switch, as a real twin. Everything else still
runs on the preview - BOM, emoji, nav/footer, globe, analytics, CDN, tokens,
cache-busting, dash-language, viewer, tail.
site_gates.py green. The builder (kept in the session scratchpad) writes BOM + CRLF
and asserts both: it first wrote LF and turned the nav/footer gate red for the
preview, which is exactly the trap this CHANGELOG's morning entry records.
|
||
|
|
88200cffd7 |
website: the waiting-list sentence follows from 'all 5 places are open'
gates / gates (push) Successful in 6m22s
'Ha most nincs szabad hely' read oddly directly after saying every place is free. It now talks about what happens when the test fills up, which is the case the sentence is actually for. |
||
|
|
69035f4af5 |
website: the tester pages get the design system, and content links stop turning purple
gates / gates (push) Successful in 6m34s
Root cause of "no formatting for the points": .info-card and .highlight-box are
scoped per page (.page-technologiak / .page-biztonsagimentes) and the new pages
carry .page-teszteles, so NONE of the card chrome applied - the sections were
unstyled text runs. The tester pages now join the technologiak scope, whose h3
is a flex row (these headings carry an icon).
Three more gaps the new pages exposed, all fixed site-wide rather than patched:
- There was no base `a` rule at all, so an inline link in body copy fell back
to the browser default and changed colour once visited. .legal was the only
place this had been fixed. /gyik, /technologiak and /biztonsagimentes each
carry such links and had the same bug.
- `code` was styled only under .legal.
- A <ul> inside an info-card was unstyled: wrong colour, wrong indent.
Justified body copy on the tester pages, as asked. NOTE: no other page
justifies today, so this is deliberately scoped to .page-teszteles and can be
rolled out site-wide or dropped in one edit. hyphens:auto, because Hungarian
sets badly when justified without it.
site.css -> v=10 on all 20 pages.
sitemap.xml: BOM removed. Search Console shows the freshly submitted clean
sitemap as "Sikertelen lekeres" with an empty last-read, and a BOM before the
XML declaration is a known irritant for its parser. The file is otherwise valid
(18 <url>, parses, served 200 as application/xml). No gate covers sitemap.xml
and the BOM rule is for website/*.html only.
Facts corrected - there are NO testers (operator, this evening): "Tester 1" is a
disposable virtual box and "Tester 2" is a friend whose machine is unassembled
and switched off. The page said "Nehany hely mar betoltve", which was untrue; it
now says the test is starting and all 5 places are open. Same correction in
OUTREACH.md (five people needed, not three), CONTEXT.md, and the terms-1.1 mail,
which in practice has one recipient, not two. No scheduled post claimed a
filled place, so none needed editing.
|
||
|
|
5bea5f2ebf |
marketing + seo: the three-week tester campaign, schedule-post --link, the not-indexed audit
gates / gates (push) Successful in 6m15s
COPY.md section 7: five Hungarian posts for Tue/Thu 19:00 over three weeks, each with a source comment per claim and one link. The Monday post (2026-10-12, 6.2) is untouched and no slot shares its day. fb_probe.py gains --link (default unchanged). Every scheduled post used to attach the home page's preview card whatever its text said, so a post about /teszteles would have sent the people who clicked its card to the home page. build_parser() split out of main() so a test can parse argv. Red-proved: both new tests fail with "Namespace object has no attribute link" without the flag. Search Console audit (seo-2026-10-10/not-indexed.md): all seven not-indexed URLs with a verdict each - four expected by design, two waiting on Google's crawl queue, one fault on our side. That one is /api/contact, the contact form's POST endpoint crawled as a page; robots.txt now disallows /api/. The performance baseline (0 clicks, 47 impressions, position 73, nine queries) is recorded there to compare against in a month. |
||
|
|
92dc41638a |
website: a tester recruitment page, and test terms 1.1 (the domain)
gates / gates (push) Failing after 13m28s
New page pair /teszteles + /en/testing: who the closed test is for, what a
tester needs (machine + internet quoted verbatim from the FAQ, plus a domain),
what they get (terms section 3, nothing new), what we ask for, and how many
places there are. Every "Jelentkezem tesztelonek" button now goes there.
Operator rulings 2026-10-10, recorded in CONTEXT.md:
D1 - the tester's domain is 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.
D2 - the closed test runs with at most 5 households.
Terms 1.1 adds section 4 (the domain) with the D1 text; old sections 4-11 are
renumbered 5-12 and nothing else changed. Section 11 promises the testers an
e-mail before a change, so one is drafted for the operator to send.
Registered in site_gates.py TWINS/URL and listed in sitemap.xml.
|
||
|
|
ec5605d42c |
register shrink 2026-10-10: 13 rows closed with live evidence (138 -> 125); R-903 phone menu without JS; R-910 pictures; R-912 site gate 21
gates / gates (push) Successful in 6m4s
Closed: R-906 R-907 R-909 R-910 R-911 R-815 R-756 R-570 R-896 R-912 R-903 R-338 R-916. Updated: R-899 (press set up, dated check 2026-10-11), R-243 (the mail is due 2026-10-11 ~16:06Z, dated check), R-782 (homepage live; glance question to the operator), R-904 (the TLS sentence is in 01 s7). Website: site.css v=9 (scripting:none menu), eight dashboard pictures retaken. Evidence: audits/register-shrink-2026-10-10/. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS |
||
|
|
970616b72b |
New apps 2026-10-10: Grocy and LubeLogger on the website; Monica stopped
gates / gates (push) Failing after 11m41s
The catalogue side is app-catalog-felhom.eu b7f0f7c. Here: the evidence, the website, the register and the operator's view. Website - Two cards in the Otthon & Eletmod / Home & Lifestyle section of BOTH apps pages, with assets: grocy-logo.svg is grocy's own icon 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 rule SparkyFitness's PNG follows), and six screenshots of each app's own UI with a household's own data, taken headless on the bench from the published template. - The app count moved 56 -> 58 in 15 places per language set, both languages, and the open-source tile 49 -> 51. Checked by asking the same patterns for the new number afterwards. marketing/facebook/COPY.md still says 56 and is NOT changed: the post it carries is already scheduled. Evidence - documentation/audits/new-apps-2026-10-10/ — FIT.md (checklist group 0 for all three, with the Hungarian-UI column), the bench and box transcripts, the memory samples, the screenshots and the gate runs. Register: 137 -> 139 rows, 2 opened, 0 closed. - R-926 after a remove-keeping-backups and restore, nobody has checked what the app page shows for an after_install app's generated password. Measured here: LubeLogger is safe (its login is derived from the environment at every start, the new password signs in, the data is back); grocy's install password still signs in from the restored database but the deployed environment no longer carries ADMIN_PASSWORD at all. Seven apps are in the class. - R-927 Monica, stopped at checklist 0.2 with the measurements, waiting on the operator. Gate scripts: the same console trap in nineteen of them and in repo_gates.py itself, where it ABORTED THE WHOLE RUNNER at the first gate — printing a non-ASCII character on this workstation's cp1250 console raised UnicodeEncodeError before the gate had decided anything, and reuse_refs_check.py died while printing a NOTE. All now reconfigure their own streams. Red-proof that the remaining script-test failures are not mine: test_due_checks_gate.py fails the same 5 of 42 with the change reverted. |
||
|
|
fe80548144 |
website: the header mark had no white fill — wrong source file (and R-916 corrected)
gates / gates (push) Successful in 5m36s
I used assets/logo_notext.svg for the header mark. That file is the LIGHT-BACKGROUND variant: it has SEVEN #00408d fills and ZERO #ffffff, so on the dark nav the cloud rendered as a hollow outline. The operator caught it. logo_notext_white.svg is not the answer either -- it is a white OUTLINE version, also unfilled. Rendered all four candidates side by side on the real nav background to see it rather than infer it: only logo.svg (and logo.png) carry the real artwork -- white cloud, #051343 house and servers, #008ddf swoosh. FIX: assets/logo-mark.svg, cut from logo.svg -- keep <defs>, path6 and g2; drop the five wordmark paths and the two empty <text> elements; viewBox cropped to the mark (70 0 505 295). Vector, correct fills, no text. All 18 pages point at it; site.css cache-bust v7 -> v8. The CSS comment now says which file NOT to swap back in, and why. AND A CORRECTION THAT REMOVES AN OPERATOR TASK (R-916). That row says the project has no usable vector master because logo.svg "sets felhom.eu as live text" in 'M+ 2c'/'Vremena Grotesk', and it waits on "the machine with the fonts". MEASURED today, while cutting the mark out of that very file: - all five wordmark elements are <path> with real d= geometry - NO <text> element has any content; the two present are empty leftovers - the font-family strings the row cites are Inkscape METADATA left on CONVERTED paths (-inkscape-font-specification). A grep for font-family finds them and reads as live text -- the likeliest way the original diagnosis went wrong. - proof from a renderer that lacks both fonts: Chrome draws logo.svg's lettering identical to logo.png's, side by side. NOT re-tested: librsvg specifically -- DooPlex has no rsvg-convert, inkscape or cairosvg installed today, so the original librsvg/DejaVu observation could not be reproduced either way. It does not change the structural fact: there is no font left to substitute. Consequence: the 645x408 PNG is not the only faithful copy and does not cap picture size. R-916 state -> READY with "re-check before doing any work: this may need nothing from the operator at all", rather than closed on my say-so. |
||
|
|
625d38645c |
website: one brand lockup in the header, and footer links that look like links
gates / gates (push) Successful in 5m54s
HEADER. logo.png carries its OWN "felhom.eu" lettering under the mark, so
putting it next to a typed <span class="logo-text"> said the name twice and
squeezed the mark down to 40px to make room. Now:
- the mark alone, bigger: assets/logo_notext.svg at 54px (44px under 600px).
Vector, so it stays crisp. Its two <text> elements are EMPTY, so R-916's
missing-font problem does not apply to this file -- checked, not assumed.
- the name beside it is the brand's OWN lettering, cropped from logo.png to
the new assets/logo-wordmark.png (632x108, tight bbox).
Why an image and not text: the wordmark's face is "M+ 2c"/"Vremena Grotesk"
(R-916). Nothing here has it, and the site deliberately loads NO external
font -- the privacy notice published this morning states exactly that, so
pulling in Google Fonts to match a logo would have made a published claim
false. Using the artwork is also what the Facebook covers already do. The
white/blue split the operator asked for is in the artwork itself.
Accessibility kept: the mark is alt="" aria-hidden (decorative), the wordmark
carries alt="felhom.eu", so the link still has its accessible name.
FOOTER. The legal links were unstyled, so the browser painted them default
blue and PURPLE once visited. They now follow the site's own convention
(.page-kapcsolat .sidebar-card a): --blue-bright, no underline, underline on
hover. :visited is pinned to the same colour deliberately -- a legal link
that changes colour after one read looks like it stopped working. The same
fix applied to .legal a on the two new legal pages, which had --blue instead
of --blue-bright.
18 of 18 pages carry the new lockup; the English pages keep their /en/ logo
href. site.css cache-bust v6 -> v7 on all 18, per the website rules. Verified
rendered in a browser on both a Hungarian and an English page: both images
load, no .logo-text left anywhere, footer links computed rgb(46,168,245).
site_gates OK (nav/footer per language, BOM, cache-busting, twins).
|
||
|
|
30b932bb10 |
website: publish the closed-test legal set (R-813 narrowed)
gates / gates (push) Successful in 5m34s
Two new Hungarian pages, live on push: /adatkezeles (privacy notice) and /feltetelek (what the free closed test is, and is not). Operator rulings of 2026-10-09: no company exists yet, so the operator is named as a PRIVATE PERSON with no postal address and no phone; publish before the lawyer has seen it, because the site was collecting data with no notice at all; the full ASZF, the impresszum and the review wait for the company (R-802, R-809). - All 18 pages carry the operator, info@felhom.eu and both links in the footer. Counted, not assumed: 18 pages found = 18 with both links = 18 structurally valid. English footers say the legal texts are Hungarian. - The contact form stopped claiming something untrue. The old consent said "az adatokat harmadik felnek nem adjuk ki" while Resend, Cloudflare and Google carry the message. Both languages replaced; the link opens in a new tab so a filled form is not lost. - site_gates.py NO_TWIN gains the two pages ON PURPOSE, with the reason in a comment: an unreviewed English legal text would be worse than an honest pointer from the English footer. - documentation/legal/{adatkezelesi-tajekoztato,feltetelek}-1.0.md are the text of record, DERIVED from the published HTML so they cannot drift. The drafts are kept and marked superseded for the closed test. FOUR LOAD-BEARING CLAIMS WERE MEASURED, not copied from a vendor or a README: cookies zero, and no local storage - checked in the browser WITH A POSITIVE CONTROL (a probe cookie WAS visible to the same method) after the tracker fired; no Set-Cookie on any response beacon the exact Umami payload: site id, screen, language, title, url, referrer - no visitor identifier Cloudflare DNS only: the public A record 37.191.56.193 is not a Cloudflare address, so site traffic cannot be proxied fsn1 Falkenstein, Germany (Hetzner's own location list) Also measured: felhom-ep0-copy-gc.timer is installed and RAN SUCCESSFULLY (2026-10-09 08:00, exit 0), so "deleted within 30 days" is true today where on 2026-10-08 it was written but not switched on. Three retentions are stated as having NO deadline, deliberately and with the operator's word: website statistics, web server logs and contact messages have no automatic deletion, and the pages say so instead of promising a date nothing enforces. Every other period is enforced by configuration and cited. No placeholder survived onto either page (0 of "[[", control: the draft still has 36). The impresszum and the full ASZF are NOT published. R-813 -> NARROWED. R-915 unblocked: the operator enters the two URLs in the Meta app's Basic settings; the Live switch stays a separate decision. R-917 and R-920 -> DEFERRED on the operator's (c): park, publish as posts once posting starts. |
||
|
|
a350776105 |
Logos: seven coloured app logos made white like the rest; five logo/picture sets renamed to the catalog slug
gates / gates (push) Failing after 4m35s
Mealie, Homebox, Dawarich, Komga, Radicale, Recipe Importer (SVG) and SparkyFitness (PNG) are white now (operator request), checked rendered in headless Chrome. crafty/grampsweb/homeassistant/plantit/uptimekuma -> crafty-controller/gramps-web/home-assistant/plant-it/uptime-kuma, so the dashboard finds them (it asks for <slug>-logo.*); both apps pages updated. R-912 filed (no gate checks this). Register 134 -> 135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb |
||
|
|
42519a776a |
gallery.js v2: when the last 'next' turns off, focus moves to the close button instead of the page behind (seen in the live check)
gates / gates (push) Successful in 4m29s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb |
||
|
|
79c53b5f1a |
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 |
||
|
|
aaac24b05c |
website: the dashboard shown — 4 real screenshots per language on the home page, 2 on the technology page (controller 0.303.0, demo-hp household guest, privacy-scanned); site gate 19 (pictures in the page's language) + decoy; R-906, R-907 (dashboard defects seen); 129 -> 131
gates / gates (push) Successful in 4m12s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb |