# One state. Two surfaces.

Independent article case study. Domain: website consumer / Design Engineering presentation.

One application state owns caption, accent and effect. Both a semantic HTML card and an independently drawn Canvas2D cover consume the same snapshot. Pixelated mode paints that cover into a smaller detached canvas, then enlarges it with image smoothing disabled. Inputs and resize events redraw the current state without replacing native controls. This is manual drawing of known content, not automatic HTML rasterization.

## Attribution and evidence

Studied: [Exploring the HTML-in-Canvas Proposal](https://tympanus.net/codrops/2026/05/13/exploring-the-html-in-canvas-proposal/), Vittorio Retrivi. Article SHA-256: bbcd3d5a6b1b518988c4f5f67130c5c7dc17159278dafc7a57edcfd25a70b87f. Analysis SHA-256: 8f83d4ee6c2ef3e3087f05791568a0d76d6fc5d91844ca5e16ec0c0044196bc7. Source revision: 169917e07fce9566d6105807e474986a89de72f4ec1cd6f65e0c637fa8f6409c. The revision hashes the article/analysis hashes, the analyst principle and code-block evidence references, plus pinned original source/line hashes and the implementation contract, the exact original failure evidence, and pinned proposal context; it identifies studied evidence, not a claim that the original demo executes.

Original acquisition: acquired. Original license: MIT. originalSourceAcquired: true. Source code acquisition is complete. Original runtime remains failed-in-recorded-capability-environment: The exact compiled getting-started preview emits Uncaught TypeError: canvas.requestPaint is not a function; no ready event was received and the captured frame is white.

No original article prose, code, artwork, source project or screenshot is distributed here. The authored-code MIT notice applies only to the independent implementation. The acquired original failed in the recorded environment because requestPaint was not callable; its success was not verified. This example does not implement the HTML-in-Canvas proposal, copy arbitrary HTML/CSS, transform DOM hit testing, or reproduce the original Fluid/Rain shaders. The duplicate canvas is hidden from the accessibility tree; visible semantic content and native controls remain outside it. No assistive-technology conformance is claimed. Caption input is bounded to 28 code units by the native field. Empty captions keep the artwork visible. Long captions shrink to fit the painted line and wrap in the semantic card. Both presentation modes are stationary. A Canvas2D failure keeps the DOM representation usable and emits an error instead of readiness.

## Initial state and controls

Make a cover, then break it into pixels. The painted artwork and readable HTML share your caption and palette; the controls stay clear.

The page starts stationary. This cover owns caption, accent and effect in one state object. Input events update that object before redraw; reset restores all three inputs. Default uses a full-resolution Canvas2D buffer; Pixelated uses a smaller buffer enlarged without smoothing. Empty captions keep the geometry visible and show No caption set in the semantic card. Drawing failure retains editable DOM content and suppresses successful readiness. No continuous animation is scheduled. Play motion, where present, advances this study’s presentation until paused; text, bounce, portrait, orbit, strand and mascot motion loops, while the event composer stops at its endpoint. Scroll studies advance through ordinary document scroll or their chapter buttons. Static view stops time-based motion; manual controls still inspect values. The three scroll studies instead show every chapter in ordinary reading flow. Pointer parallax centers its decorative layers.

Initial control values:

| Control key | Value |
| --- | --- |
| caption | AFTERGLOW |
| accent | citrus |
| effect | Default |

## Running and editing

Open index.html directly. It contains all runtime code and visuals and needs no package install, account, network, remote asset or browser-origin storage. Edit its inline style and script to change the downloaded page. styles.css and script.js are reference copies of the inline source; changing those copies alone does not change the running page. Full repository regeneration overwrites index.html and all generated copies, including any manual edits. The --only=<baseline ID> option generates selected records while verifying and preserving existing records and downloads. Keep a separate copy when editing a download. The repository authoring modules in vendor/codrops-article-studies/scenes-*.mjs and runtime.mjs regenerate these copies through node scripts/build-codrops-article-studies.mjs. Repository regeneration also needs the private source evidence; downloaded-page execution does not.

## Verification boundary

This generation passed the captured article/analysis hash checks, article-code/paragraph pointer hashes, pinned source/line hashes, record/license/receipt hashes and original runtime snapshot hash, exact ID membership, local canonical Markdown anchor/hash checks, implementation-symbol checks, JavaScript parsing, semantic main/title counts, duplicate-ID checks and runtime URL/storage exclusion. The manifest codeFiles entries identify every emitted file by SHA-256. Each code symbol is a searchable named function, not a claimed executed call trace. Proposed checks are in KNOWLEDGE.json. runtime_verified: false. SG artifact capture proves only a recorded initial render; no interactive runtime, keyboard, accessibility, comfort or performance result is claimed.

Manual Chrome interaction is blocked by extension UI in this session. No alternate browser-control route was used. Preview sizing is native responsive width. Initial-render captures are tracked separately at site/artifacts/full-import/preview-posters/index.json and site/artifacts/full-import/preview-posters/visual-review.json in the repository. No capture receipt is bundled with this download. The bounded initial-render matrix requests all 22 studies at 320 pixels and three representative studies at 1280 pixels; the separate poster surface is 640 × 420. The authored CSS also adapts at 375 and 768 pixels, without claiming those widths were captured. A width request does not mean that capture exists or passed. Motion starts on explicit playback; system reduced motion and the Static view switch stop it.

consumer_reference: consumer-reference/agent-native/registry.json
