Skip to content

fix(layout): resolve viewport units against the real viewport and run the cascade - #156

Merged
LeadcodeDev merged 1 commit into
chantier/audit-remediationfrom
fix/layout-viewport-cascade-aspect-ratio
Aug 9, 2026
Merged

fix(layout): resolve viewport units against the real viewport and run the cascade#156
LeadcodeDev merged 1 commit into
chantier/audit-remediationfrom
fix/layout-viewport-cascade-aspect-ratio

Conversation

@LeadcodeDev

Copy link
Copy Markdown
Owner

Round 4, vague A — lot layout, 5 constats vérifiés.

Trois des 8 constats d'origine de ce lot (intrinsic.rs:74, legacy_dispatch.rs:134, paint_pass.rs:222) avaient déjà été corrigés au round 3, par les PR #153 et #154. Il en restait 5.

Constat Sévérité Symptôme
Unités de viewport High vw/vh résolus contre un 1920×1080 codé en dur, em/rem contre 16 px. Sur une vidéo verticale 1080×1920 — un format courant ici — 50vw valait 960 px au lieu de 540, soit 78 % d'erreur.
Cascade CSS High Jamais exécutée. cascade::inherit_from était correct et testé, mais personne ne l'appelait : color et font-* posés sur un conteneur n'atteignaient aucun enfant.
Propriétés non traduites Medium box-sizing, justify-items, justify-self, order acceptés par le schéma, jamais traduits vers taffy, sans un mot.
aspect-ratio écrasé Medium width: 400 + aspect-ratio: 16/9 donnait une hauteur de 80 px au lieu de 225.
Doc margin-top Medium La règle enseignait une syntaxe que le schéma rejette, supprimant le composant entier.

Détails

Unités de viewport. Les deux sites de layout de production passaient ConversionContext::default() alors que les dimensions réelles étaient dans la portée, une ligne plus haut. Un viewport_conversion_context partagé construit désormais le contexte depuis le viewport réel. À 1920×1080 il est bit-à-bit identique à l'ancien défaut : le cas le plus fréquent ne bouge pas.

Cascade. Appliquée dans build_child après la position et avant les états de timeline et les animations — une valeur propre continue donc de battre une valeur héritée.

order. taffy n'a aucune primitive de réordonnancement au niveau du style (son order est l'ordre source, assigné pendant le layout) : le traduire est structurellement impossible. Il avertit donc au lieu de disparaître — une fois par processus, pas une fois par nœud et par frame. to_taffy_style tourne à chaque frame ; un eprintln! non gardé aurait imprimé la même ligne un millier de fois par rendu.

Documentation. CssStyle porte deny_unknown_fields et n'expose que margin: Edges. Les formes margin-top et padding: [32, 48] que la règle montrait font échouer la désérialisation et retirent le composant de la vidéo. C'est un document lu par les LLM qui génèrent les scénarios : il leur apprenait activement à produire du JSON qui supprime des composants. Vérifié en exécutant la CLI, pas en lisant la struct.

Risque de régression sur l'existant

La cascade et l'aspect-ratio changent tous deux le rendu possible de scénarios existants. Les deux ont été confrontés à tous les exemples livrés : aucun nœud n'hérite d'une propriété qui lui manquait, aucun exemple n'utilise aspect-ratio, box-sizing, justify-items, justify-self ni order.

Hors périmètre — constaté, non causé ici

examples/ferriskey-presentation.json échoue rustmotion validate (gradient_text, largeur naturelle 404 px pour 400 px disponibles). J'ai vérifié : le chemin de mesure, le validateur et le fichier d'exemple sont identiques à main, et l'échec se reproduit à c229ec0 avec le même chiffre. Il précède tout le chantier. Suivi séparément.

Vérification

cargo test --workspace sur cette branche seule : intégralement vert.

… the cascade

Five confirmed audit findings on CSS→taffy translation and intrinsic sizing.

- `vw`/`vh` were resolved against a hardcoded 1920x1080 and `em`/`rem`
  against a hardcoded 16px, because both production layout sites passed
  `ConversionContext::default()` while the real dimensions sat in scope one
  line away. On a 1080x1920 vertical video — a routine format here — `50vw`
  came out 960px instead of 540px, a 78% error. A shared
  `viewport_conversion_context` now builds the context from the real
  viewport; at 1920x1080 it is bit-identical to the old default, so the
  common case does not move.
- The CSS cascade was never executed. `cascade::inherit_from` was correct
  and tested, but nothing called it: `color` and `font-*` set on a
  container reached no child. It is now applied in `build_child` after
  position and before timeline states and animations, so an own value still
  beats an inherited one.
- `box-sizing`, `justify-items` and `justify-self` were declared by the
  schema and never translated. They are now. `order` cannot be — taffy has
  no style-level reordering primitive, its `order` is source order assigned
  during layout — so it warns instead of vanishing, once per process rather
  than once per node per frame.
- The default-size guard for components with no intrinsic measurer wrote a
  hardcoded width *and* height, each gated only by `is_none()` on its own
  axis, so an explicit `aspect-ratio` was overwritten: `width: 400` with
  `aspect-ratio: 16/9` produced height 80 instead of 225. The other axis is
  now derived from the ratio when one axis is explicit.
- `rules/html-css-mental-model.md` taught `margin-top` / `margin-left` and
  `padding: [32, 48]`. `CssStyle` has `deny_unknown_fields` and only
  `margin: Edges`, so those forms fail deserialization and drop the whole
  component from the video. This is a rule read by the LLMs that generate
  scenarios: it was actively teaching them to write JSON that deletes
  components. Verified by running the CLI, not by reading the struct.

Cascade and aspect-ratio both change how existing scenarios could render,
so both were checked against every shipped example: no node inherits a
property it was missing, and no example uses `aspect-ratio`.

Tests: full workspace green on this branch alone.
@LeadcodeDev LeadcodeDev added bug Something isn't working documentation Improvements or additions to documentation labels Aug 9, 2026
@LeadcodeDev LeadcodeDev self-assigned this Aug 9, 2026
@LeadcodeDev
LeadcodeDev merged commit 49ccc02 into chantier/audit-remediation Aug 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant