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.
This commit is contained in:
2026-10-12 08:58:42 +02:00
parent a7480172ab
commit 0ef0b106f6
31 changed files with 1150 additions and 474 deletions
+46 -1
View File
@@ -31,6 +31,10 @@ Gates (all must pass; non-zero exit on any failure):
19. dash-lang — a page shows dashboard pictures only in its own language (`dashboard-*-hu.webp` / `-en.webp`)
20. viewer — data-gallery openers are <a href> to existing assets; gallery.js (with ?v=) exactly where openers are;
no inline viewer copy
23. anchors — every in-site link carrying a #fragment finds that id on the page it names.
The sidebar's five category links pointed at #fajlkezeles-irodai and friends while
the page's ids are #fajlkezeles and friends: 100 dead links across 20 pages, live,
found by the operator clicking one
22. shell leak — MEDIA-AWARE: no declaration in site.css reaches a shell page on a selector that
shell.css also styles. site.css loads FIRST, so a property shell.css never sets
survives — „later wins” is per PROPERTY, not per rule. Earned live 2026-10-11:
@@ -73,10 +77,12 @@ TWINS = {
"kapcsolat.html": os.path.join("en", "contact.html"),
"letoltes.html": os.path.join("en", "download.html"), # R-559 (2026-09-18) — the first twin
"teszteles.html": os.path.join("en", "testing.html"), # 2026-10-10 — the tester recruitment page
"szolgaltatasok.html": os.path.join("en", "services.html"), # 2026-10-12 — was a section of the home page
}
URL = {"index.html": "/", "alkalmazasok.html": "/alkalmazasok", "technologiak.html": "/technologiak",
"biztonsagimentes.html": "/biztonsagimentes", "gyik.html": "/gyik", "kapcsolat.html": "/kapcsolat",
"letoltes.html": "/letoltes", "teszteles.html": "/teszteles",
"szolgaltatasok.html": "/szolgaltatasok", os.path.join("en", "services.html"): "/en/services",
os.path.join("en", "testing.html"): "/en/testing", os.path.join("en", "index.html"): "/en/", os.path.join("en", "apps.html"): "/en/apps",
os.path.join("en", "technology.html"): "/en/technology", os.path.join("en", "backups.html"): "/en/backups",
os.path.join("en", "faq.html"): "/en/faq", os.path.join("en", "contact.html"): "/en/contact",
@@ -105,6 +111,7 @@ MOCKUPS = set() # the design studies were deleted with website/preview/ at the
# duplicated into each page, and this is what keeps the duplication honest.
SHELL = {
'szolgaltatasok-nonpublic.html',
'szolgaltatasok.html',
'index.html',
'alkalmazasok.html',
'technologiak.html',
@@ -117,6 +124,7 @@ SHELL = {
'feltetelek.html',
'404.html',
os.path.join("en", 'index.html'),
os.path.join("en", 'services.html'),
os.path.join("en", 'apps.html'),
os.path.join("en", 'technology.html'),
os.path.join("en", 'backups.html'),
@@ -734,8 +742,45 @@ else:
"declarations (media-aware)" % (len(_site_r), len(_shell_r),
len(set(s for _, s, _ in _site_r) & _shell_sel)))
# gate 23 (2026-10-12): an in-site #fragment has to exist on the page it points at.
#
# The shell's sidebar is copied into every page, so ONE wrong fragment is wrong twenty times: the five
# app-category links shipped pointing at ids nobody had written (#fajlkezeles-irodai for a section
# whose id is #fajlkezeles). Nothing noticed, because a dead fragment is not an error anywhere - the
# browser simply stays put. Checked for every page the gate already walks; a link to a page outside
# PAGES, or to another site, is not this gate's business.
_ids = {}
for _p in PAGES:
_s = io.open(os.path.join(W, _p), encoding="utf-8-sig").read()
_ids[_p] = set(re.findall(r'\sid="([^"]+)"', _s))
_url_to_page = {}
for _p, _u in URL.items():
_url_to_page[_u] = _p
if _u.endswith("/"): # "/" and "/en/" are index pages
_url_to_page[_u + "index.html"] = _p
_anchor_n, _anchor_bad = 0, 0
for _p in PAGES:
_s = io.open(os.path.join(W, _p), encoding="utf-8-sig").read()
for _href in re.findall(r'href="([^"]*#[^"]+)"', _s):
if _href.startswith(("http://", "https://", "mailto:")):
continue
_page_part, _frag = _href.split("#", 1)
if _page_part == "":
_target = _p # same page
elif _page_part in _url_to_page:
_target = _url_to_page[_page_part]
else:
continue # a URL this gate does not own
_anchor_n += 1
if _frag not in _ids.get(_target, ()):
_anchor_bad += 1
fail("%s: link to %s finds no id=\"%s\" on %s — the browser stays where it is and the link "
"reads as broken" % (_p, _href, _frag, _target))
if not _anchor_bad:
print(" anchors: %d in-site #fragment(s), every one resolves" % _anchor_n)
if fails:
print("\nSITE GATES FAILED: %d problem(s)" % len(fails))
sys.exit(1)
print("site gates OK — BOM, emoji=0, nav/footer per language, analytics, no CDN, no legacy tokens, no <style>, "
"cache-busted assets, twins + hreflang + globe, lang, same apps, no Hungarian in English, FAQ JSON-LD, clean tail, dashboard pictures per language, one picture viewer, no shell CSS leak")
"cache-busted assets, twins + hreflang + globe, lang, same apps, no Hungarian in English, FAQ JSON-LD, clean tail, dashboard pictures per language, one picture viewer, no shell CSS leak, live anchors")