0fbba61030b692efdc0c8e77a5a940307a78ee1d
1917 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0fbba61030 |
manifests: hub 0.147.0 (the operator's answers S4, S6, S10, S29, S30, S32, S33)
gates / gates (push) Successful in 6m14s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS |
||
|
|
655f5f66f8 |
hub v0.147.0 (code): the operator's answers S4, S6, S10, S29, S30, S32, S33
gates / gates (push) Successful in 6m0s
- S4 / R-242: GoldenVouchChecker - a published golden unvouched for 2 h raises golden_not_vouched (operator only) - S6 / R-244: the delete cascade de-references app_log_issues; one-time sweep flag -sweep-app-log-residue=count|apply - S10 / R-266: read_failed storage entry shows "read failed", not 0 % - S29 / R-250: host-key scan IPv4 first, ~2 min ladder, "safe to press Save again" error - S30 / R-246: stale_at retired (reader, setter, badge) - S32 / R-521: storage_reconnected ends the storage_disconnected cooldown on both channels - S33 / R-402: host page "Last full check (off-site)" line; two wire-gate allowlist entries removed Each with a test seen failing first. Not built or deployed yet (operator-attended deploy). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS |
||
|
|
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. |
||
|
|
e2b09f25ea |
answers 2026-10-12 Part B: the four DooPlex changes live and read back; R-886 + R-211 closed (112 -> 110)
gates / gates (push) Successful in 6m7s
- S21 / R-887: runner fetch_timeout 30s, Gitea Ingress 2 rps per address (homelab-manifests ad8618f); WATCHING to 2026-10-19
- S22 / R-886: Alertmanager fsGroup 65534; a test silence survived a pod restart (4168451) - closed
- S23 / R-211: Prometheus config-reloader; two automatic reloads, no manual POST (ab40c7b, test e70e0f1/78d4be4) - closed
- S20 / R-231: backup scripts in homelab-ansible/roles/dooplex_backup, installed from git (fdd324b); VERIFY 2026-10-13
- evidence: documentation/audits/answers-2026-10-12/s2{0,1,2,3}-*.txt
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
|
||
|
|
ee43929040 |
report: the reviewer's round - the three answers, each fix with its check, the film licence
gates / gates (push) Successful in 6m17s
|
||
|
|
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.
|
||
|
|
1b45bb4d9b |
answers 2026-10-12 Part A: the 38 rulings recorded (09 §3 196-233), 17 rows closed (128 -> 112), R-933 filed
gates / gates (push) Successful in 6m41s
- 09 §3: the decision sheet S1-S38, the operator's words quoted where they differ (S1, S2, S8, S32, S37) - closed: R-831 R-870 R-698 R-327 R-230 R-719 R-352 R-526 R-770 R-771 R-913 R-290 R-209a R-769 R-616 R-884, and R-243 (dated check: the mail fired 2026-10-11 16:13:51Z, hub log agrees) - R-698: the known limit written in 07 §6.6; new row R-933 (mirror supported catalog images, P3) - R-327: capability-map row BUILT; stands claim re-titled and moved to built; page re-rendered - R-913: the customer Cloudflare token recipe in day0-install A.1; 01 §7 points at it - R-884: read only - ArgoCD Synced, live Deployment equals git - R-887 dated check NOT met (4 lost jobs 10-10/11); re-dated 2026-10-19 after the S21 change - 22 open rows carry their ruling; STATUS: the sheet is ANSWERED Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS |
||
|
|
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).
|
||
|
|
42c2d84c7c |
gates: re-anchor the ascii-hungarian-text decoy on the renamed link label
gates / gates (push) Failing after 7m19s
Its anchor was "Who is behind it" in en/index.html, which became "More about me" when the home line went first person. The suite refused to build the decoy rather than skip it, which is the behaviour that makes an anchor change visible. |
||
|
|
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. |
||
|
|
f92e81ee14 |
gates: re-anchor four site decoys to the shell markup
gates / gates (push) Successful in 6m33s
The decoys plant a known defect and assert the gate convicts, so when the markup
they anchor on changes they must be rebuilt rather than deleted - which is exactly
what test_gate_decoys.py refused to let pass ('the decoy's anchor is gone or
ambiguous').
en-nav-drift drifts a SIDEBAR entry now, and expects gate 3b's message
rather than gate 3's - the website's <nav> is gone
leftover-text-switch anchors on <details class=lang-globe>; the old nav's
<li class=lang-globe-li> wrapper no longer exists
lang-attr <html lang=en class=no-js>, the progressive-enhancement hook
ascii-hungarian-text anchors on the new English home's own link text; its old
'Contact form' link went when the page became a real twin
The other decoys in that section still anchor correctly and were left alone -
checked each one against the new files rather than rewriting the lot.
|
||
|
|
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. |
||
|
|
7b6bcd2416 |
audit: M3 STOP 2 - the page table and what was checked on all 19
gates / gates (push) Failing after 13m34s
Records the three faults that measurement found and looking would not have: 168 words silently deleted by the first page-header transform, the contact pages' header sliding under the sidebar (content column at x=642 instead of 240), and two pages that already scrolled sideways on a phone BEFORE M3. Also raises the one thing needing an operator decision: the English home page is the old design in the new frame, because the /preview/ round never produced an English twin. 4 186px tall in Hungarian, 10 786px in English. |
||
|
|
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.
|
||
|
|
698ec9b561 |
audit: M3 STOP 1 - the shell, the home page, and the six leaking declarations
gates / gates (push) Successful in 6m30s
Measured on the deployed page: 21 requests / 285 KB, 4 181 px at 1440 and 7 530 px
at 390 - less than half the live home page's height - zero third-party hosts, no
overflow, and no contrast failures after two fixes.
Records three things worth keeping beyond this session:
* the six declarations that leak from site.css into the shell, because later-wins
is per PROPERTY not per rule. Only one was visible; the rest were found by
diffing declaration sets.
* R-930 arriving a second time by another route: fixing the website's .cta-button
did not fix the controller's .btn-primary, which the shell imports.
* a measurement trap: a background tab freezes CSS transitions AND rAF, so the
drawer read as permanently shut when it was fine. Setting transition:none
before measuring gives the real end state; an rAF await froze a probe for 45s.
|
||
|
|
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.
|
||
|
|
d5f00b7115 |
context: operator ruling 2026-10-11 - none of the three directions; M3 follows
gates / gates (push) Successful in 7m2s
Recorded in CONTEXT.md as a dated ruling and at the top of the comparison. Nothing deleted: /preview/, /preview/m1/ and /preview/m2/ all stay up, hidden, so the next direction can be compared against them. Nothing built: SHARED-DESIGN.md recommended the canonical-stylesheet-plus-gate mechanism only once a direction exists, and none does, so it stays unbuilt. The measured case for a mechanism rather than a convention survives the ruling and is kept in the audit folder: a component copy between the repos silently dropped a bare body rule and broke the phone layout in four measurable ways. |
||
|
|
e2b9e7d9e9 |
R-899 closed: the night after a daytime press still took its whole-guest backup (Tester 1, 2026-10-11 04:33)
gates / gates (push) Successful in 7m9s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS |
||
|
|
7413e0dfab |
audit: the mockup comparison, the shared-design answer, and two register moves
gates / gates (push) Failing after 11m45s
documentation/audits/mockups-2026-10-11/
COMPARE.md the three directions side by side, measured the same way:
A current preview 12 req / 270 KB
M1 dashboard 68 req / 1012 KB (front page 1 660 px)
M2 hybrid 16 req / 150 KB (phone 3 057 px, the shortest)
plus three sentences each (good / risk / cost) and the risk I
think is real: a non-technical visitor may read M1 as somebody
else's account and look for a login.
SHARED-DESIGN.md REPORT ONLY, nothing built. M1 needed 260 CSS rules: 188 (72%)
copied from the controller UNCHANGED, 8 adapted, 64 new. It used
188 of the controller's 826 rules (23%). The 18 tokens are
already identical - verified by parsing both :root blocks, zero
differing values.
Recommends (a) a canonical felhom-ui.css plus a copy-drift gate,
over (b) serving the controller's stylesheet to the website -
and recommends NOT building it until a direction is chosen.
shots/ desktop and phone captures of all three, from the deployed pages
The finding that outranks the percentage, and the reason for the recommendation: a
component-level copy silently drops the element-level rules those components depend
on. The extractor copied every .sidebar/.content/.mobile-topbar rule and missed
"@media(max-width:768px){ body { flex-direction: column } }". Everything LOOKED
copied; the phone layout was broken in four measurable ways. Invisible to a diff,
invisible to review. A second instance the same evening: the drawer is gated on a
'js' class set by an inline script that was not copied either.
Register 129 -> 129 (one closed, one opened):
R-929 CLOSED - NOT A DEFECT. Measured from the catalog: 60 templates, minus
plant-it (abandoned) and wger (hidden) = 58 offered, exactly what the prose
says; the page's 59th card is FileBrowser carrying the single "Beepitett"
badge. Set difference both ways is empty. The premise was wrong on BOTH
halves. Rule kept: before filing a count disagreement, check whether the
counts are counting the same set.
R-932 OPEN - 8 catalog strings across 5 apps carry an em dash, and they render in
the controller's app page on every real box. Found because the mockups are
the first thing to show catalog copy on a website page. Lives in a repo this
session did not have in scope, so it is a row, not a fix.
|
||
|
|
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. |
||
|
|
3b3a926b39 |
audit: the preview's source body, matching fb9fe080
gates / gates (push) Failing after 6m24s
The preview page is generated from this file, so
|
||
|
|
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. |
||
|
|
94ac6afbe8 |
audit: the preview's pre-flight, before/after shots, and two filed rows
gates / gates (push) Failing after 12m59s
PREFLIGHT.md - taste-skill §14 plus the Felhom additions, run in writing against
the DEPLOYED preview, Pass/Fail per line. Measured, not assumed:
page height 1440: 10 922 -> 6 780 px (38% shorter)
page height 390: 19 913 -> 10 865 px (45%, 23.6 -> 12.9 phone screens)
initial load: 13 req / 308 KB -> 11 req / 260 KB (same conditions)
fully loaded: 16 req / ~540 KB -> 15 req / ~545 KB (ESSENTIALLY UNCHANGED -
the 93 KB portrait is paid for by dropping the 49 KB hero logo
and the 31 KB mono font; stated rather than spun)
third-party hosts: 0 -> 0
em dashes in our copy: 18 -> 0
layout families: 8 for 11 sections (3 repeats) -> 10 for 10 (none)
no horizontal scroll: clientWidth == scrollWidth at 390 and at 1440
Contrast: three NEW styles measured 3.88 / 3.14 / 3.57 on the first pass, all under
WCAG AA. Fixed to --text-2 and re-measured on the deployed file: 7.56 / 6.12 / 6.96.
A measurement that lied, recorded because it nearly shipped a false verdict: the
first helper reported .limits p at 1.17:1 by treating the translucent --warn-dim
as opaque. Compositing the whole ancestor stack gives the true 5.67:1, a pass. The
three real failures in the same run were real. An instrument that can report a
wrong number silently is not a measurement.
Two rows filed, both needing something this session may not do alone:
R-930 (Business & legal, P3) the primary CTA is 4.01:1, under AA. MEASURED
IDENTICAL ON THE LIVE PAGE, so pre-existing and site-wide, not a regression
of this redesign. Three fixes offered, each touching brand, so it goes to
the operator rather than being changed unilaterally.
R-931 (Process & tooling, P4) felhom.eu serves NO compression at all - site.css
goes over the wire as 94 310 raw bytes with no Content-Encoding even when
gzip is offered. An nginx setting in manifests/, not a website change.
Worth more than anything on this page.
Register: 127 -> 129 rows, 2 opened, 0 closed. register_shape_gate.py OK.
|
||
|
|
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.
|
||
|
|
fc52e3865e |
skills + audit: vendor taste-skill, add the Felhom override, audit the home page
gates / gates (push) Successful in 6m30s
Part 0 and Part A of the home-page redesign. Nothing under website/ is touched.
skills/
- design-taste-frontend installed to ~/.claude/skills/ as a VERBATIM copy of
github.com/Leonxlnx/taste-skill @ 717446e07a (2026-10-09, MIT). Body verified
byte-identical line by line; the only addition is a provenance block. The repo
holds scripts (skill.sh, scripts/*.mjs) but the SKILL FOLDER holds only SKILL.md,
so no script was copied and none was run. Not installed via npx or skill.sh.
- skills/felhom-web-design/SKILL.md is the override layer and names every conflict:
the static-HTML stack fence (no React/Tailwind/Motion/npm), nothing fetched from
another server (kills taste-skill's picsum/Unsplash/SimpleIcons ladder and its
npm icon libraries, since we have a self-hosted sprite), real images only, the
Hungarian gondolatjel surviving the en-dash ban, the claim rule, and the SEO-keep
list. 137 lines, check_skills.py PASS.
- SOURCES.md records the provenance and the kept/overridden table.
documentation/audits/redesign-2026-10-10/AUDIT.md
Measured against the LIVE site, not the file. 12 patterns to retire (R1-R12), each
naming the taste-skill rule it breaks; 7 to keep; dial reading 3/2/4 -> 6/3/4;
8 levers in priority order for the operator to approve at STOP 1.
Headline measurements: 10 922 px tall at 1440 and 19 913 px at 390 (23.6 phone
screens); 11 sections but only 8 layout families, why-grid used 3x and
apps-showcase 2x; 18 em dashes; 16 requests / 533 KB from exactly two hosts.
Contrast measures 7.56:1 body and 16.67:1 headings - AAA, and an accessibility win
to preserve rather than a thing to fix.
Method note: resize_window does not move window.innerWidth on this workstation and
DevTools device mode could not be driven, so the page was rendered in a same-origin
iframe at each width. Faithful, with two positive observables: the hamburger
computes to display:block at 390, and clientWidth == scrollWidth == 375.
Gates: site, hostinstall, hub-confirm, register and the rest green. instructions and
script-tests fail on this Windows workstation for environment reasons that predate
this change (E:\git\CLAUDE.md is the deliberate Windows adaptation the gate wants
identical; fcntl missing; relpath across C:/E:; the cp1250 console trap). Re-run on
DooPlex follows.
|