diff --git a/plugins/aem/edge-delivery-services/skills/snowflake/SKILL.md b/plugins/aem/edge-delivery-services/skills/snowflake/SKILL.md index 6ceeed90..d6a9a65c 100644 --- a/plugins/aem/edge-delivery-services/skills/snowflake/SKILL.md +++ b/plugins/aem/edge-delivery-services/skills/snowflake/SKILL.md @@ -254,7 +254,13 @@ proceeds. Reruns are safe — phases skip work already done. standard block tables. - **`hybrid`**: block-level for passing sections, page-level fragments for failing sections. - See [phases/3-generate.md](./phases/3-generate.md). + Both `page` and `block` are supported under **either substrate + flavor** (`eds` or `milo`). All Milo-specific deltas — chrome + metadata, page-level/block-level generation, the `--pa-*` animation + sidecars, and wiring — live in + [assets/substrate-milo/FLAVOR.md](./assets/substrate-milo/FLAVOR.md); + the phase docs carry a gated pointer to it. The core skill stays + substrate-neutral. See [phases/3-generate.md](./phases/3-generate.md). 4. **Wire** — copy artifacts to EDS-served paths, build the local-test drafts file, run lint. diff --git a/plugins/aem/edge-delivery-services/skills/snowflake/assets/substrate-milo/FLAVOR.md b/plugins/aem/edge-delivery-services/skills/snowflake/assets/substrate-milo/FLAVOR.md new file mode 100644 index 00000000..af2cfe7b --- /dev/null +++ b/plugins/aem/edge-delivery-services/skills/snowflake/assets/substrate-milo/FLAVOR.md @@ -0,0 +1,381 @@ +# Milo flavor — `substrate-milo` + +The snowflake skill core is substrate-neutral; this file holds **all** the +Milo-specific generation deltas so the shared phase docs carry only a gated +pointer here. Applies when `.snowflake/config.json` `substrateFlavor` is `milo` +(auto-detected when the target repo boots milolibs — see `phases/0-prereq.md`). +Milo owns the runtime and chrome; this flavor only adds project-local blocks Milo +auto-loads. The files it installs are listed in `MANIFEST.json`; the `--pa-*` +scroll-animation vocabulary is in [animation-sidecars.md](./animation-sidecars.md). + +Each section below is referenced by a pointer from the matching phase: + +- [#capture](#capture) — Phase 1 (`phases/1-capture.md`): chrome metadata +- [#generate-page](#generate-page) — Phase 3 page-level (overlay) deltas +- [#generate-block](#generate-block) — Phase 3 block-level (editable `forge-*`) deltas +- [#wire](#wire) — Phase 4 wire deltas + +--- + + + +## §capture — Phase 1: capture the chrome metadata (not the chrome DOM) + +If `.snowflake/config.json` `substrateFlavor` is `milo`, the deployed page +does **not** ship a captured header/footer — Milo renders the live +`global-navigation` + footer from page metadata. Capture that metadata from +the source's `
` into `state.json.chromeMeta` so Generate can re-emit it +onto the DA page. These are the keys that drive Milo's chrome: + +```bash +# From the saved source HTML +for name in foundation gnav-source footer-source unav universal-nav \ + gnav-promo-source skin mobile-gnav-v2; do + val=$(grep -oE " + +## §generate-page — Phase 3 page-level (overlay) deltas + +When `.snowflake/config.json` `substrateFlavor` is `milo`, the page is hosted +by Milo (which owns the chrome) and the bespoke body is drawn by the +`blocks/snowflake` overlay block. Apply these deltas to the page-level steps +below; everything else (template build, slot markers, per-template CSS, +animations, asset rewriting, self-checks) is unchanged: + +- **Skip 3.3 (header fragment) and 3.4 (footer fragment) entirely.** Do not + emit `fragments//*`. Milo renders the live gnav/footer from + metadata. (Capturing them is the bug the Milo flavor fixes.) +- **3.1 head links — KEEP all body/block stylesheets.** This is load-bearing. + The overlay block injects the captured, **pre-decorated** DOM and Milo does + **not** re-decorate it, so per-block CSS will NOT auto-load. `foundation: c2` + only pulls the C2 **base** `styles.css`, not each block's stylesheet. Lift + **every** source `` into the template's top level + (the overlay block lifts them into `` at runtime) **EXCEPT** + `global-navigation*.css` and any footer-chrome CSS — Milo's own gnav/footer + blocks load those. Concretely, keep e.g. `router-marquee.css`, + `rich-content.css`, `base-card.css`, `elastic-carousel.css`, + `carousel-c2.css`, `visually-hidden.css`, `section-metadata.css`, + `modal.css`, `merch.css`, `video.css`, typekit, lenis. **Dropping these is + what makes the overlaid body render as unstyled, stacked content** — only the + two chrome stylesheets come out. +- **3.1b interactive content — prototype interaction contract.** The overlay + injects *frozen, pre-decorated* DOM, so any widget whose motion came from JS + (carousel/slider, auto-rotating marquee, tabs, accordion) renders but does not + move. The `snowflake` block ships a tiny dependency-free activator that revives + them **only** when they use the contract below. So when the source body has such + a widget AND the captured markup actually holds every state (all carousel + slides, all tab panels — true for URL/HTML captures, which serialize the full + rendered DOM), rewrite that widget to the contract, keeping each slide/panel's + inner content and block CSS classes 1:1 (you only swap the outer wrapper): + - carousel: `