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.
9.6 KiB
Pre-flight — taste-skill §14 plus the Felhom additions
Run against the deployed preview at https://felhom.eu/preview/, 2026-10-10, not against the
file on disk. Every measurement came from the browser.
Headline numbers
| Old home page | New preview | ||
|---|---|---|---|
| Page height, 1440 px | 10 922 px | 6 780 px | 38% shorter |
| Page height, 390 px | 19 913 px | 10 865 px | 45% shorter, 23.6 → 12.9 phone screens |
| Initial load (same conditions) | 13 requests, 308 KB | 11 requests, 260 KB | |
| Fully loaded (all assets) | 16 requests, ~540 KB | 15 requests, ~545 KB | essentially unchanged |
| Third-party hosts | 0 | 0 | |
| Em dashes in the page's own copy | 18 | 0 | |
| Layout families for 11 / 10 sections | 8 (3 repeats) | 10 (no repeat) | |
| JetBrains Mono fetched | yes, 31 KB, for 13 characters | no |
Honest reading of the weight. The initial load is 48 KB lighter. The fully scrolled page is
about the same: the new 93 KB portrait is paid for by dropping the 49 KB decorative logo.png and
the 31 KB mono font. The redesign is not a weight win once you scroll; it is a weight win for the
first screen, which is the one most visitors see. R-931 (no gzip anywhere on the site) is worth far
more than anything on this page.
taste-skill §14
| Check | Verdict |
|---|---|
| Brief inference declared (§0.B) | Pass — AUDIT.md §A |
| Dial values explicit and reasoned | Pass — 6 / 3 / 4, AUDIT.md §I |
| Design system chosen or aesthetic labelled honestly | Pass — Felhom design system v2, no new system |
| Redesign mode detected, audit performed (§11) | Pass — preserve; AUDIT.md |
| ZERO em dashes | Pass with two stated exceptions — 0 in the page's own copy. 6 remain in <title>/description/OG/Twitter/JSON-LD by operator decision at STOP 1 (indexed strings), 1 in the shared footer, which gate 3 forces to be identical on 14 pages. Neither swept silently |
| Page Theme Lock — one theme | Pass — dark throughout, no section inverts |
| Color Consistency Lock — one accent | Pass — --blue / --blue-bright only |
| Shape Consistency Lock — one radius | Pass — --radius: 2px everywhere |
| Button Contrast Check | FAIL, pre-existing, filed — .cta-button is 4.01:1 (white on #0083D8, 16px/600) against a 4.5 floor. Identical on the live page, so not a regression. R-930, needs a brand decision |
| CTA Button Wrap — no 2-line label at desktop | Pass |
| Form Contrast Check | n/a — no form on this page |
| Serif discipline | n/a — no serif |
| Premium-consumer palette ban | n/a — not that brief |
| Italic descender clearance | n/a — no italic display type |
| Hero fits viewport, ≤2-line headline, ≤20-word subtext | Pass — headline 2 lines, subtext 20 words, CTA and a real screenshot both above the fold at 1440 and at 390 |
Hero top padding ≤ pt-24 |
Pass — 128 px, and the hero is sized by its content; the old one was a forced 100vh band with the content floating in the middle |
| Hero stack ≤ 4 text elements | Pass — headline, subtext, CTA, figure caption. No eyebrow, no tagline under the CTA, no trust strip |
| Eyebrow count ≤ ceil(sections/3) | Pass — 0 of an allowed 4. The cluster headings are not eyebrows (no uppercase, no tracking, they head real groups), and the comparison's column headers were deliberately de-capitalised for this rule |
| Split-Header Ban | Pass — every section header stacks headline over body |
| Zigzag Alternation Cap | Pass — the two image+text splits (hero, portrait) are separated by two other families |
| No Duplicate CTA Intent | Pass — one label, „Jelentkezem tesztelőnek", used for the one intent in both places |
| Logo wall = logos only | n/a — no logo wall |
| Bento Background Diversity | n/a — no bento |
| „Used by" wall under the hero | n/a |
| Copy Self-Audit | Pass — every visible string re-read. The ten capability texts are verbatim from the live page on purpose: the audit's finding was that the writing is right and the layout is wrong, so no hedge („ha van", „szinte mind") was rewritten away |
| Motion motivated | Pass — there is no motion. The old hero's infinite float is gone |
| Marquee max one | n/a — none |
| Navigation one line, ≤80 px | Pass — unchanged from the live nav, spliced verbatim |
| Section-Layout-Repetition | Pass — 10 sections, 10 families. Was 11 sections over 8 families, why-grid ×3 and apps-showcase ×2 |
| Bento rhythm and exact cell count | n/a |
| Long lists use the right component | Pass — the ten-card grid became three labelled clusters (§4.9 „grouped chunks") |
| Real images, no fake screenshots | Pass — one real dashboard screenshot in the hero, four in the gallery, one real photograph of the operator. No AI image, no stock, no picsum, no div-built preview. The decorative logo is gone from the hero |
| No pills over images | Pass |
| No photo-credit decoration | Pass |
| No version footers | Pass |
| No micro-meta sentences under eyebrows | Pass |
| No hero-bottom decoration strip | Pass |
| No floating top-right sub-text | Pass |
| No filled progress-bar comparisons | Pass — the comparison is text in two columns |
| No locale / weather strips | Pass |
| No scroll cues | Pass |
| No version labels in the hero | Pass |
| No section-numbering eyebrows / generic step labels | Pass — 1..5 and 01..05 are gone; the steps are named by their verb-noun and ordered by layout |
| No decorative dots | Pass |
No border-t+border-b on every row |
Pass — the comparison uses one divider between rows, not a box per row |
| Content density sane | Pass with a stated deviation — the ten capability paragraphs run past §4.9's 25-word guide. Deliberate: see Copy Self-Audit |
| Quotes ≤3 lines | n/a — no testimonials |
| Motion claimed = motion shown | Pass — MOTION_INTENSITY: 3 claims none and ships none |
| GSAP skeletons | n/a |
No window.addEventListener('scroll') |
Pass — the only JS is the existing nav toggle and gallery.js |
| Reduced motion honoured | Pass — the global prefers-reduced-motion block is present, and there is no animation to suppress |
| Dark mode tested | Pass — single locked dark theme, by brand decision |
| Mobile collapse explicit | Pass — every new multi-column rule has its <900px and <600px fallback written in the same block |
Viewport stability, no h-screen |
Pass — the new hero uses no viewport-height sizing at all; the old .hero used 100vh |
useEffect cleanup |
n/a — no framework |
| Empty / loading / error states | n/a — static marketing page |
| Cards omitted in favour of spacing | Pass — the ten cards became three clustered lists; the comparison is a divided table, not eight boxes |
| Icons from an allowed library | Pass, by the Felhom override — the self-hosted icons.svg sprite is the library; no npm icon package |
| Motion isolated in client leaves | n/a |
| No AI tells from §9 | Pass |
| Core Web Vitals plausible | Partly — the hero image is fetchpriority="high" with width/height set, so LCP and CLS are in hand; but nothing is compressed on the wire (R-931), which is the real limiter |
| One design system | Pass |
The Felhom additions (felhom-web-design §9)
| Check | Verdict |
|---|---|
| UTF-8 BOM on every page file | Pass — asserted by the builder and by site_gates.py gate 1 |
| Zero emoji | Pass — gate 2 |
Zero — including meta |
Pass with the two stated exceptions above |
No <style> block; site.css ?v= bumped |
Pass — ?v=11 |
Every request to felhom.eu or stats.felhom.eu, listed from the browser |
Pass — 11 requests: felhom.eu 8, stats.felhom.eu 2, third-party 0. Full list in the session report |
| Page weight compared and said out loud | Pass — table above, including the part that did not improve |
| Body contrast at or above baseline | Pass after a fix. Three new styles measured 3.88 / 3.14 / 3.57 on first pass, all under AA. Moved to --text-2 and re-measured on the deployed file: 7.56 / 6.12 / 6.96. One pre-existing failure remains and is filed (R-930) |
| Focus visible | Pass — :focus-visible { outline: 2px solid var(--blue-bright) } applies |
| Reduced motion honoured | Pass |
| No horizontal scroll at 390 px | Pass — clientWidth == scrollWidth == 375 at 390, and == 1425 at 1440 |
| English twin in the same commit | Deferred to Part D by design — a preview URL cannot be a TWINS pair (AUDIT.md §K.6). The twin is written in the switch commit, as a real twin |
repo_gates.py green, new page registered |
Pass — site_gates.py green; preview/index.html registered in NO_TWIN with its reason |
A measurement that was wrong, and how it was caught
The first contrast pass reported .limits p at 1.17:1, which would have been a severe failure.
It was an error in the measuring script, not in the page: the helper walked up for the first
non-transparent background and found --warn-dim, which is rgba(224,169,62,.12), then treated that
translucent colour as if it were opaque. Compositing the whole ancestor stack over the page
background gives the true value, 5.67:1, which passes. The three real failures in the same run
were real and were fixed.
The lesson is the project's own: an instrument that can report a wrong number silently is not a measurement. The corrected helper is in the session transcript and composites every layer.