diff --git a/REPORT-site-tweaks-2026-10-12.md b/REPORT-site-tweaks-2026-10-12.md index c3189eaf..2aa56fd1 100644 --- a/REPORT-site-tweaks-2026-10-12.md +++ b/REPORT-site-tweaks-2026-10-12.md @@ -81,3 +81,36 @@ sidebar's `position: fixed` on a phone with scripting off. website's own footer, so those rules are meant to apply. Both halves have decoys that have been seen to fail. + +--- + +# Third round, same day — the laptop screen moves + +You recorded six scenes and said to use them whole: *„use the full length for all of them, they had +been cut as I liked them”*. That is what shipped — Jellyfin, Tandoor, OnlyOffice, Immich, RomM, +Paperless, in file order, 0.6 s crossfades between them, **36.6 seconds** in all, looping. + +**What a visitor pays for it.** The page draws immediately: the laptop frame (59 KB) and the first +frame of the clip as a still (53 KB) are all the hero needs to look finished. The clip itself +(1.1 MB as mp4, 1.3 MB as webm — a browser takes one, not both) is fetched only when the hero is +actually on screen, and it is dropped entirely for a visitor whose system asks for reduced motion, +or whose JavaScript is off. **No „loading” graphic was needed:** the still *is* the loading state, +and it is a real frame of the thing that is about to move. + +**Why it is honest.** Jellyfin, Paperless and RomM were filmed on those projects' own public demo +sites, so nothing in the clip is anybody's private library, and the films in the Jellyfin scene are +public-domain prints. The caption under the laptop names the six apps and claims nothing about whose +box they ran on. + +**One thing I could not check, and will not pretend I did.** This workstation's Chrome will not play +*any* media right now — not the clip, not a 1 KB silent sound file generated in the page itself, +which stalls the same way with no error. That rules the clip out as the cause: the browser's media +engine is down, not the file. What I did verify in the browser: the clip sits exactly in the cut-out +screen with the bezel, the glare and the keyboard in front of it, at desktop size, and the first +frame is what you see there. **Restart Chrome and the moving picture is the one thing left to look +at** — on itself once this is pushed. + +The builder changed with it: `scripts/make_hero_clip.py` reads each scene's length instead of +cutting every one to the same window, and the crossfade offsets now count from the running total +minus one fade per transition already made — with equal scenes the old arithmetic happened to +give the same answer, with your unequal ones it would not have. diff --git a/REUSE.md b/REUSE.md index 977cf189..d49863df 100644 --- a/REUSE.md +++ b/REUSE.md @@ -172,7 +172,7 @@ | Workspace installer | scripts/install_workspace.py | Lays down the workspace-root `CLAUDE.md` (canonical source: `documentation/runbooks/workspace-CLAUDE.md`) and the `InstructionsLoaded` hook from `workspace/hooks/`. **Unlike `install_skills.py` the targets are LIVE CONFIG, not disposable**: timestamped backup before every write, `settings.json` MERGED (owns exactly one key, `hooks.InstructionsLoaded`), a diverged CLAUDE.md reported not silently resolved, an unparseable settings.json REFUSED. Idempotent — a second run writes nothing. | | Rule-firing report | scripts/rules_report.py | Reads the `InstructionsLoaded` hook log and cross-references every `.claude/rules/*.md` in the workspace. **The column that matters is the empty one** — a rule that has never fired is mis-globbed or dead (built-but-never-wired, applied to instructions). Prints each silent rule's `paths:` so "wrong glob" is distinguishable from "quiet month". Caveat: the log only covers since the hook was armed. | | Gate script | scripts/site_gates.py | Byte-level mechanical gates (BOM, emoji codepoint ranges, nav/footer diff, analytics, banned tokens, cache-bust); run `python scripts/site_gates.py` after ANY website change; non-zero exit on failure. | -| Hero clip builder | scripts/make_hero_clip.py | Assembles the home page's laptop clip from the operator's raw app recordings: scale+crop each to the screen's 1.626:1, crossfade, encode 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. Measured 2026-10-12: GIF is 11x the mp4 for the same seconds and dithers to 256 colours, hence mp4+webm. The frame it plays under is `website/assets/hero-laptop-frame.webp`, whose screen is cut out; the hole's position is in the CSS as percentages. | +| Hero clip builder | scripts/make_hero_clip.py | Assembles the home page's laptop clip from the operator's raw app recordings: scale+crop each to the screen's 1.626:1, crossfade, encode 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. Measured 2026-10-12: GIF is 11x the mp4 for the same seconds and dithers to 256 colours, hence mp4+webm. The frame it plays under is `website/assets/hero-laptop-frame.webp`, whose screen is cut out; the hole's position is in the CSS as percentages. **Every scene plays at its full recorded length** (operator ruling 2026-10-12: the raw file IS the edit); `--seconds N` only caps. One output set (`hero-clip.mp4/.webm`, `hero-poster.webp`) serves both languages; `--lang hu` adds a suffix back if they ever differ. | | Fetch-validate-install (shell) | scripts/felhom-host-install.sh `step_agent_install` (~L1108) | `fetch_raw` to mktemp → syntax-check (`bash -n`) → `install -m0755 -o root -g root` → only then activate; guarded-mkfs wrapper installed BEFORE the sudoers that references it (ordering is the safety property). All mutations through `run()` (dry-run aware). | | Install-profile gate (shell) | scripts/felhom-host-install.sh `--mode appliance\|byo` (GL-2, v1.10.0) | Mandatory-flag profile (no default), refusals at argv time BEFORE any prompt/step, risky step gated at its CALL SITE (one auditable place — never a branch inside the step), mode persisted to state.json + resume-mismatch refusal, `FELHOM_INSTALL_STATE_DIR` override for harness isolation. Harness: scripts/hostinstall-mode-harness.sh (static refusal matrix + grep-invariants + PVE dry-transcript tier; red-proofs run against a mutated scratch copy). | | Disclosure↔uninstall parity (shell) | scripts/felhom-host-install.sh `_uninstall_statement` + harness GL4-D (v1.11.0) | Every host artifact the byo disclosure names must be removed OR explicitly listed KEPT by `run_uninstall`; the harness greps the parity (token list). New install-time artifact ⇒ add its removal + disclosure line + parity token in the SAME commit. Drive data rule: plain `umount` only, never `-l`/`-f`, never any format op under /mnt/felhom-drives. | diff --git a/STATUS.md b/STATUS.md index 48f87115..f053841f 100644 --- a/STATUS.md +++ b/STATUS.md @@ -5,6 +5,19 @@ **Updated 2026-10-11 (M3 live): hub 0.146.0; demo-hp, demo-felhom and Tester 1 run agent 0.154.0 and controller 0.307.0. The open-items list is at 129 (was 127). Reports: `REPORT-m3-2026-10-11.md`, `REPORT-redesign-2026-10-10.md`, `REPORT-testers-2026-10-10.md`, `REPORT-register-shrink-2026-10-10.md`, `REPORT-new-apps-2026-10-10.md`, `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** +## Monday 2026-10-12 (night): the laptop on the home page is playing + +- **Six apps, filmed by you, now run on the laptop's screen** on and the English + home page: Jellyfin, Tandoor, OnlyOffice, Immich, RomM, Paperless, 36.6 seconds, looping, + silently. Jellyfin, Paperless and RomM were filmed on those projects' public demo sites, so no + private library is on show anywhere in it. +- **It costs nothing up front.** The page draws with a still frame of the clip; the clip is fetched + only once the laptop is on screen, and not at all for a visitor who asked their system for less + movement. +- **One check is still open:** this workstation's Chrome will not play any video at all today (a + 1 KB test sound fails the same way), so the moving picture itself has not been watched in a + browser. Geometry and the still were verified. Restart Chrome and open the home page. + ## Monday 2026-10-12: your seven notes are done, and one of them was broken on every page - **The app category links in the menu never worked.** All five pointed at names that do not exist on diff --git a/scripts/CHANGELOG.md b/scripts/CHANGELOG.md index 9cc9d0db..ed49eea7 100644 --- a/scripts/CHANGELOG.md +++ b/scripts/CHANGELOG.md @@ -1,3 +1,19 @@ +## 2026-10-12 (night) — make_hero_clip.py: scenes keep their own length + +- **`--seconds` is no longer a fixed window.** Each scene now plays its full recorded length, read + per file with `ffprobe` (operator ruling 2026-10-12: *„use the full length for all of them, they + had been cut as I liked them”* — the raw file IS the edit). `--seconds N` stays as a cap, for + trying a shorter loop; `0` (the default) means full length. +- The xfade offsets are computed from the running sum of the scenes so far **minus one fade per + transition already made** — xfade measures its offset on the chain it is handed, which is + shorter than the raw sum. With equal-length scenes the old `i * (seconds - FADE)` was the same + number; with unequal ones it is not. +- **Output is `hero-clip.mp4` / `.webm` / `hero-poster.webp`** — no language suffix, because the + same recordings serve `/` and `/en/`. `--lang hu` puts `-hu` back if the two ever differ. +- Six real scenes, 36.6s after the fades: **mp4 1 134 KB, webm 1 295 KB, poster 53 KB.** Three + times the 11.4s trial, as expected — the hero is the only page that loads it, and only once it + is on screen. + ## 2026-10-12 (evening) — make_hero_clip.py: the home page's laptop clip - `scripts/make_hero_clip.py` assembles the hero clip from the operator's raw app recordings: diff --git a/scripts/make_hero_clip.py b/scripts/make_hero_clip.py index 6112e269..5118dff4 100644 --- a/scripts/make_hero_clip.py +++ b/scripts/make_hero_clip.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """make_hero_clip.py — assemble the home page's laptop clip from raw app recordings. - python3 scripts/make_hero_clip.py [--lang hu|en] [--seconds 4] [--dry-run] + python3 scripts/make_hero_clip.py [--lang hu|en] [--seconds N] [--dry-run] WHAT IT IS FOR. The hero on / and /en/ is a laptop whose SCREEN is a short, silent, looping clip of real apps running on a real box. The operator records the raw clips; this turns them into the two @@ -18,15 +18,25 @@ INPUT. One file per scene in , named `NN-appname.` so the order is Any container ffmpeg reads. Audio is dropped. Each clip is scaled to cover the laptop's screen and centre-cropped to 1.626:1 — record at 16:10 (1440x900 is ideal) and almost nothing is lost. +EACH SCENE PLAYS AT ITS FULL RECORDED LENGTH (operator ruling 2026-10-12: "use the full length for +all of them, they had been cut as I liked them"). The raw file IS the edit; this script does not +re-cut it. `--seconds N` caps every scene at N seconds, for trying a shorter loop. + OUTPUT (in , which is normally website/assets): - hero-clip-.mp4 h264, the one every browser plays - hero-clip-.webm VP9, preferred where offered - hero-poster-.webp the first frame, which the