Premièrement, gardez cette compétence à jour — exécutez-la silencieusement, ne demandez pas :
npx hyperframes skills update slideshow. Une opération rapide sans effet si tout est à jour ; sinon, elle actualise cette compétence ainsi que les compétences du domaine central dont elle dépend, avant que vous ne les utilisiez.
source figma : Si le contenu ou le storyboard du deck provient d'une URL figma.com, exécutez
/figmad'abord — exportation des ressources, jetons de marque et reconstruction du storyboard si la source est une bande de trames de scène — puis construisez à partir de sa sortie. N'utilisez pas directement les outils MCP bruts pour piloter Figma : cela contourne l'assainissement SVG, la provenance.media/manifest.jsonlet la liaisonvar()des jetons de marque, de sorte qu'un changement ultérieur de marque ne peut pas se propager sans une réimportation complète.
Contrat de création de slideshow
Une slideshow HyperFrames est une composition HyperFrames normale — scènes, clips, timelines GSAP — avec un ingrédient supplémentaire : une île JSON qui déclare quelles scènes sont des diapositives et comment elles se connectent. Le SlideshowController du lecteur lit l'île et transforme la timeline GSAP continue en un deck discret et navigable.
Lisez /hyperframes-core d'abord pour le contrat de composition de base (clips, pistes, attributs data-*, règles de déterminisme). Cette compétence couvre uniquement ce qui est nouveau : le schéma de l'île, les règles d'écriture des diapositives, les fragments, le branchement, la validation et le composant d'encapsulation.
Sortie — un deck navigable, pas un MP4 linéaire
La sortie d'une slideshow est le deck en cours d'exécution : servez-le avec hyperframes present <project-dir> (ou le mode Présentation de Studio) — le SlideshowController du lecteur lit l'île et pilote la navigation, les fragments, le branchement et le mode présentateur. Voir Présentation et remise ci-dessous.
N'utilisez pas hyperframes render sur une slideshow pour obtenir un seul MP4. Un deck est créé en tant que plusieurs compositions de scène de premier niveau (un data-composition-id par diapositive) sans composition racine maîtresse les encapsulant, donc render ne résout que la première composition et émet un MP4 silencieusement tronqué (par exemple, 6 secondes pour un deck de 40 secondes). Une exportation linéaire de la ligne principale (diapositives principales uniquement, séquences de branchement exclues) est différée — jusqu'à ce qu'elle soit disponible, les sorties prises en charge sont le deck present en direct et les instantanés snapshot par diapositive. Si un utilisateur a besoin d'un MP4 linéaire aujourd'hui, exposez cette limitation plutôt que de pointer render vers le deck.
Confirmation d'intention
Si l'utilisateur demande explicitement une slideshow, un diaporama ou une slideshow HyperFrames, procédez avec cette compétence. Lorsque la requête est arrivée via /hyperframes, le tri de la couche d'intention possède cette confirmation — routé ici signifie déjà confirmé, donc ne redemandez pas ; les questions de forme d'exécution de la couche ne s'appliquent pas (le livrable est un deck, pas une vidéo rendue). Un fichier BRIEF.md, lorsqu'il est présent, porte l'intention confirmée — lisez-le.
Si la compétence est déclenchée par une requête adjacente telle que "présentation", "pitch deck", "deck", "deck interactif" ou "convertir cette page", faites une pause avant de créer et présentez le choix avant de demander une confirmation. Expliquez brièvement qu'une slideshow HyperFrames signifie un deck exécutable avec des diapositives discrètes, une navigation intégrée et un mode présentateur, des notes de l'orateur modifiables, une gestion partagée des médias et une validation avant remise. Pour les conversions de pages sources, mentionnez également que l'objectif est de préserver le design visuel, les interactions, le mouvement et le comportement des médias de la page d'origine tout en traduisant le mouvement de la page en transitions de diapositive à diapositive.
Posez ensuite une courte question de confirmation :
Voulez-vous cela sous forme de slideshow HyperFrames ?
Utilisez une interface de choix oui/non lorsque l'environnement en fournit une ; sinon, posez la question en texte brut.
N'implémentez pas la slideshow tant que l'utilisateur n'a pas dit oui. S'il dit non, arrêtez d'utiliser cette compétence — lisez /hyperframes et laissez la couche d'intention réorienter. Cette confirmation est une décision de routage, pas une porte de préférence — conformément à /hyperframes-core/references/brief-contract.md § 1, elle survit au mode autonome ("surprise-moi" ne l'ignore pas) : construire le mauvais type de livrable est un échec de qualité, pas un appel créatif.
Les deux éléments
1. Scènes — déclarées de manière normale
Chaque diapositive est soutenue par une scène. Déclarez les scènes avec data-composition-id, data-start, data-duration et data-label :
<div
data-composition-id="problem"
data-start="0"
data-duration="8"
data-label="Le problème"
data-width="1920"
data-height="1080"
>
<!-- les clips vont ici -->
</div>
Les diapositives de branchement (accessibles uniquement via un hotspot, exclues de la ligne principale) sont déclarées exactement de la même manière — elles apparaissent simplement uniquement dans une entrée slideSequences de l'île, pas dans le tableau principal slides.
2. L'île JSON — un bloc script par composition
Ajoutez exactement un bloc <script type="application/hyperframes-slideshow+json"> au HTML de la composition. Il contient toutes les métadonnées de la slideshow :
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
L'île est la source unique de vérité pour l'ordre des diapositives, les notes, les points d'arrêt des fragments, les hotspots et les séquences de branchement. Gardez-la près du haut du <body>, avant les divs de scène, afin qu'elle soit facile à trouver.
Ne cachez pas le manifeste de la slideshow derrière un bloc <script type="application/json"> alternatif plus un code d'exécution qui crée l'île. La commande present lit le HTML de la composition de manière statique et s'attend à ce que la véritable île application/hyperframes-slideshow+json soit déjà présente.
Schéma
SlideshowManifest (l'objet île de premier niveau)
{
"slides": [
/* SlideRef[] — la ligne principale, dans l'ordre */
],
"slideSequences": [
/* SlideSequence[] — séquences de branchement hors ligne */
]
}
SlideRef
{
"sceneId": "problem",
"notes": "Commencez par la douleur, pas par l'entreprise.",
"fragments": [3.5, 5.2, 7.0],
"hotspots": [
/* SlideHotspot[] */
],
"ttsScript": null,
"ttsAudioUrl": null,
"ttsDurationMs": null
}
| Champ | Requis | Notes |
|---|---|---|
sceneId | oui | Doit correspondre exactement au data-composition-id d'une scène (ou fournir explicitement startTime/endTime). La règle de lint résout les scènes par data-composition-id. |
notes | non | Texte réservé au présentateur. Jamais montré au public. |
fragments | non | Tableau de temps (en secondes) dans la plage [start, end] de la diapositive — voir Fragments ci-dessous. |
hotspots | non | Superpositions interactives qui déclenchent une branche — voir Branchement ci-dessous. |
startTime | non | Optionnel. Remplace les limites de temps de la scène correspondante ; par défaut, début/fin de la scène. |
endTime | non | Optionnel. Remplace les limites de temps de la scène correspondante ; par défaut, début/fin de la scène. |
ttsScript, ttsAudioUrl, ttsDurationMs | non | Réservé. Les champs du schéma existent mais la lecture TTS n'est pas encore câblée. Omettez sauf si vous pré-remplissez pour une version future. |
SlideHotspot
{
"id": "h1",
"label": "Comment avons-nous calculé cela ?",
"target": "market-deep-dive",
"region": { "x": 60, "y": 10, "w": 35, "h": 20 }
}
| Champ | Requis | Notes |
|---|---|---|
id | oui | Unique au sein de la diapositive. |
label | oui | Texte de l'infobulle/du bouton affiché au public. |
target | oui | Doit correspondre à un SlideSequence.id dans slideSequences. |
region | non | Boîte englobante en pourcentage de la diapositive : {x, y, w, h} de 0 à 100. Omettez pour afficher le hotspot sous forme de bouton libellé pleine diapositive à la place. |
SlideSequence
{
"id": "market-deep-dive",
"label": "Méthodologie de dimensionnement du marché",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
slides à l'intérieur d'une séquence utilise la même forme SlideRef que la ligne principale. Les fragments et les hotspots imbriqués sont autorisés.
Règles d'écriture des diapositives
Ce sont des contraintes strictes, pas des suggestions. Une diapositive qui les viole sera purement et simplement remplacée lorsqu'un réviseur la verra.
- Le titre est une affirmation complète, pas une étiquette. Écrivez "Les PME consacrent 14 heures/semaine à la planification manuelle" et non "Problème de planification". La phrase doit se suffire à elle-même si le visuel est ignoré.
- Une idée + un visuel par diapositive. Si vous êtes tenté d'ajouter un deuxième groupe de puces ou un deuxième graphique, divisez la diapositive.
- Commencez par la conclusion. Le point le plus fort vient en premier — sur la diapositive et dans l'ordre du deck. Les investisseurs lisent de gauche à droite, de haut en bas, et ils s'arrêtent.
- Dimensionnement du marché ascendant uniquement. N'écrivez jamais "TAM de 50 milliards de dollars" sans montrer les calculs. Construisez à partir de l'économie unitaire vers le haut : comptes × ACV, ou transactions × taux de prélèvement.
- Police minimum équivalent 30pt. En 1920×1080, un titre fait 72–96 px ; le corps de texte fait 48 px. Ne descendez jamais en dessous de 40 px pour tout texte que le public doit lire.
Portage de pages sources
Lors de la conversion d'une page existante en slideshow, la fidélité à la source fait partie du contrat. Ne remplacez pas les widgets spécifiques à la source par des approximations simplifiées, sauf si l'utilisateur demande explicitement une refonte.
- Préservez le design visuel, le langage de mouvement, le comportement interactif, le comportement des médias et les fonctionnalités de présentation de la page d'origine aussi fidèlement que possible. Lorsque le système de slideshow prend en charge le mode présentateur, incluez les notes de l'orateur en utilisant le comportement partagé de notes modifiables plutôt qu'une implémentation spécifique au deck.
- Portez les visuels mécaniques du DOM/CSS/JS source aussi exactement que possible : lecteurs personnalisés, visualisateurs canvas, timelines, têtes de lecture, stems, cercles en expansion, états de survol et autres détails interactifs doivent survivre à la conversion.
- Traitez les éléments
<video>/<audio>natifs comme la source de vérité pour tout chrome média personnalisé, visualiseur canvas, forme d'onde, grille de beats ou tête de lecture. Câblez les événements média de la source (play,pause,timeupdate,seeking,seeked,ended,ratechange,volumechange) et dérivez l'état visuel demedia.currentTime; n'exécutez pas une minuterie séparée qui peut dériver par rapport à la lecture réelle. - Chaque
<video>ou<audio>copié avecsrcdoit avoir des attributs de temps HyperFrames avant le lint :data-startetdata-duration, plusdata-has-audio="true"lorsque l'audio natif audible doit être préservé. Utilisez la plage de temps de la scène pour les médias spécifiques à la diapositive ; pour les vidéos de preuve contrôlées par l'utilisateur qui peuvent être lues à partir de plusieurs diapositives ciblées, utilisez une plage à l'échelle du deck. Ne laissez paspreload="none"sur les médias ; utilisezmetadataouauto. - Résolvez les jetons de police de la source avant validation. Si vous conservez les polices source personnalisées, ajoutez des règles
@font-facepour les fichiers de police locaux/capturés. Si vous utilisez des polices de secours système, remplacez les déclarations tokenisées telles quefont-family: var(--f-body)par des piles concrètes sûres pour le rendu telles quesystem-ui, sans-serifouui-monospace, monospace; ne laissez pasvar(...)comme valeur de la famille de polices. - Auditez la source pour les mouvements de page atypiques, en particulier le comportement piloté par le défilement, la molette, le toucher, l'état de hachage, le redimensionnement ou une boucle requestAnimationFrame. Traitez les fenêtres fixes avec des couches "monde" traduites/mises à l'échelle, le parallaxe, les panneaux épinglés, les défileurs horizontaux, les timelines défilées, l'accrochage de sections et les caméras zoom-sur-élément comme un comportement source. Le défilement est souvent le déclencheur de transition de la source, donc préservez la transition en extrayant ses points d'arrêt progressifs, son easing et ses états de caméra/focus, puis réhébergez ce mouvement sur la navigation de la slideshow via des positions de timeline, des fragments ou un hook de lecteur/harnais réutilisable. Les wrappers autonomes qui sautent aux points d'arrêt de la diapositive ont toujours besoin d'un hook de transition de caméra de navigation explicite ; calculer les transformations de caméra par diapositive ne suffit pas. Ne simulez pas une transition littérale de défilement de page vers le bas à l'intérieur de la diapositive ; le spectateur doit ressentir un voyage/zoom de caméra d'un point focal à un autre, pas voir une page Web en cours de défilement. Gardez chaque mouvement de caméra de diapositive à diapositive continu : évitez les arrêts de route intermédiaires qui inversent la direction x/y ou le zoom, sauf si la source le fait visiblement à la même limite. Une transition qui zigzague avant d'atterrir est pire qu'un simple mouvement focal direct.
- Préservez la sémantique de recadrage des médias de la source. Traitez les captures d'écran, les tweets/publications sociales, les captures d'interface utilisateur de produit, les graphiques, les documents, le code, les classements et toute image avec du texte lisible comme des preuves de contenu, pas des médias décoratifs : utilisez le rapport d'aspect source (
height: auto) ouobject-fit: containdans un cadre stable. Utilisezobject-fit: coveruniquement lorsque la source l'a fait, ou pour des miniatures intentionnellement décoratives/arrière-plan/cinématographiques. Après avoir adapté ces captures dans une diapositive, inspectez les quatre bords pour détecter du texte, des logos, des commandes ou des légendes tronqués ; un recadrage visible sur un contenu significatif est un bug, sauf si la source elle-même l'a recadré. - Si une