Avant tout, gardez cette compétence à jour — confirmez avec l'utilisateur avant d'exécuter :
npx hyperframes skills update slideshow. Une opération rapide sans effet si tout est à jour ; sinon, elle rafraîchit 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 — export 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. Ne pilotez pas Figma directement via des outils MCP bruts : cela ignore la désinfection SVG, la provenance de.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 diaporama
Un diaporama HyperFrames est une composition HyperFrames normale — scènes, clips, timelines GSAP — avec un ingrédient supplémentaire : un îlot JSON qui déclare quelles scènes sont des slides et comment elles se connectent. Le SlideshowController du lecteur lit l'îlot 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 ne couvre que ce qui est nouveau : le schéma de l'îlot, les règles d'écriture des slides, les fragments, les branches, la validation et le composant d'encapsulation.
Résultat — un deck navigable, pas un MP4 linéaire
Le résultat d'un diaporama est le deck en cours d'exécution : servez-le avec hyperframes present <répertoire-du-projet> (ou le mode Présentation de Studio) — le SlideshowController du lecteur lit l'îlot et pilote la navigation, les fragments, les branches et le mode présentateur. Voir Présentation et transfert ci-dessous.
N'utilisez pas hyperframes render sur un diaporama pour le transformer en un seul MP4. Un deck est créé comme plusieurs compositions de scène de premier niveau (un data-composition-id par slide) sans composition racine principale les encapsulant, donc render ne résout que la première composition et émet un MP4 silencieusement tronqué (par exemple 6s d'un deck de 40s). Un export linéaire de la ligne principale (slides principales uniquement, séquences de branches exclues) est reporté — jusqu'à ce qu'il soit disponible, les sorties prises en charge sont le deck present en direct et les images fixes snapshot par slide. Si un utilisateur a besoin d'un MP4 linéaire aujourd'hui, signalez cette limitation plutôt que de pointer render vers le deck.
Confirmation d'intention
Si l'utilisateur demande explicitement un diaporama, un slide show ou un diaporama HyperFrames, procédez avec cette compétence. Lorsque la demande est arrivée via /hyperframes, le tri de la couche d'intention gère cette confirmation — être 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 BRIEF.md, lorsqu'il est présent, porte l'intention confirmée — lisez-le.
Si la compétence est déclenchée par une demande 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'un diaporama HyperFrames signifie un deck exécutable avec des slides distincts, une navigation intégrée et un mode présentateur, des notes de l'orateur modifiables, une gestion des médias partagés et une validation avant le transfert. Pour les conversions de pages sources, mentionnez également que l'objectif est de préserver la conception visuelle, les interactions, le mouvement et le comportement multimédia de la page d'origine tout en traduisant le mouvement de la page en transitions de slide à slide.
Posez ensuite une courte question de confirmation :
Voulez-vous cela comme un diaporama 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 le diaporama tant que l'utilisateur n'a pas répondu oui. S'il répond non, cessez d'utiliser cette compétence — lisez /hyperframes et laissez la couche d'intention se réorienter. Cette confirmation est une décision de routage, pas une porte de préférence — conformément à ../hyperframes/references/brief-contract.md § 1, elle survit au mode autonome ("surprenez-moi" ne l'ignore pas) : construire le mauvais type de livrable est un échec de qualité, pas un choix créatif.
Les deux parties
1. Scènes — déclarées de manière normale
Chaque slide est soutenu 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 slides de branche (accessibles uniquement via un hotspot, exclus de la ligne principale) sont déclarés exactement de la même manière — ils apparaissent uniquement dans une entrée slideSequences de l'îlot, pas dans le tableau principal slides.
2. L'îlot JSON — un bloc de 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 du diaporama :
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
L'îlot est la source unique de vérité pour l'ordre des slides, les notes, les points d'arrêt des fragments, les hotspots et les séquences de branches. Gardez-le près du haut du <body>, avant les divs de scène, pour qu'il soit facile à trouver.
Ne cachez pas le manifeste du diaporama derrière un bloc <script type="application/json"> alternatif plus un code d'exécution qui crée l'îlot. La commande present lit le HTML de la composition de manière statique et s'attend à ce que le véritable îlot application/hyperframes-slideshow+json soit déjà présent.
Schéma
SlideshowManifest (l'objet îlot de premier niveau)
{
"slides": [
/* SlideRef[] — la ligne principale, dans l'ordre */
],
"slideSequences": [
/* SlideSequence[] — séquences de branches 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 startTime/endTime explicite). La règle de lint résout les scènes par data-composition-id. |
notes | non | Texte réservé au présentateur. Jamais affiché au public. |
fragments | non | Tableau de temps (en secondes) dans la plage [start, end] du slide — voir Fragments ci-dessous. |
hotspots | non | Superpositions interactives qui déclenchent une branche — voir Branches ci-dessous. |
startTime | non | Optionnel. Remplace les limites de temps de la scène correspondante ; par défaut, le début/fin de la scène. |
endTime | non | Optionnel. Remplace les limites de temps de la scène correspondante ; par défaut, le 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 dans le slide. |
label | oui | Texte de l'infobulle / bouton affiché au public. |
target | oui | Doit correspondre à un SlideSequence.id dans slideSequences. |
region | non | Boîte englobante en pourcentage du slide : {x, y, w, h} dans 0–100. Omettez pour rendre le hotspot comme un bouton étiqueté sur tout le slide à la place. |
SlideSequence
{
"id": "market-deep-dive",
"label": "Méthodologie de dimensionnement du marché",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
Les slides à l'intérieur d'une séquence utilisent la même forme SlideRef que la ligne principale. Les fragments et les hotspots imbriqués sont autorisés.
Règles d'écriture des slides
Ce sont des contraintes strictes, pas des suggestions. Un slide qui les viole sera purement et simplement remplacé lorsqu'un relecteur le verra.
- Le titre est une affirmation sous forme de phrase complète, pas une étiquette. Écrivez "Les PME consacrent 14 heures/semaine à la planification manuelle" et non "Problème de planification". La phrase doit pouvoir tenir seule si l'élément visuel est ignoré.
- Une idée + un visuel par slide. Si vous êtes tenté d'ajouter un deuxième groupe de puces ou un deuxième graphique, divisez le slide.
- Commencez par la conclusion. Le point le plus fort vient en premier — sur le slide et dans l'ordre du deck. Les investisseurs lisent de gauche à droite, de haut en bas, et ils s'arrêtent.
- Dimensionnement du marché uniquement ascendant. N'écrivez jamais "50 Mrds $ de TAM" sans montrer le calcul. Construisez à partir de l'économie unitaire : comptes × ACV, ou transactions × taux de prélèvement.
- Taille de police minimale équivalente à 30pt. En 1920×1080, un titre fait 72–96 px ; le corps du texte fait 48 px. Ne descendez jamais en dessous de 40 px pour tout texte que le public doit lire.
- Recherchez dans le catalogue en direct avant de construire manuellement un visuel nommé. Pour chaque aspect, effet, graphique, traitement ou transition dont un slide a besoin — "lignes de balayage CRT", "glitch", "course de graphiques à barres", "balayage chatoyant", "fenêtre de terminal" — exécutez
npx hyperframes catalog --query "<le visuel, en anglais courant>" --jsonet lisez les meilleurs résultats avant de créer les clips du slide. La recherche n'a besoin d'aucune installation : pas de projet, pas d'addpréalable, pas de compte. Elle classe l'ensemble du registre hébergé (~400 blocs et composants) depuis n'importe quel répertoire.npx hyperframes add <nom>place la source du bloc dans le deck, où vous le personnalisez sur place. Cela s'applique avec une force particulière lors du portage d'une page source : un véritable bloc est préférable à l'approximation simplifiée que les règles de portage ci-dessous interdisent.
Portage de pages sources
Lors de la conversion d'une page existante en diaporama, 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 la conception visuelle, le langage de mouvement, le comportement interactif, le comportement multimédia et les capacités de présentation de la page d'origine aussi fidèlement que possible. Lorsque le système de diaporama prend en charge le mode présentateur, incluez des notes de l'orateur en utilisant le comportement de notes modifiables partagées plutôt qu'une implémentation propre au deck.
- Portez les visuels mécaniques du DOM/CSS/JS source aussi exactement que possible : lecteurs personnalisés, visualiseurs canvas, timelines, têtes de lecture, tiges, 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 multimédia personnalisé, visualiseur canvas, forme d'onde, grille de rythme ou tête de lecture. Câblez les événements multimé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 pourrait dériver par rapport à la lecture réelle. - Chaque
<video>ou<audio>copié avecsrcdoit avoir des attributs de synchronisation 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 au slide ; pour les vidéos de preuve contrôlées par l'utilisateur qui peuvent être lues à partir de plusieurs slides ciblés, utilisez une plage à l'échelle du deck. Ne laissez paspreload="none"sur les médias ; utilisezmetadataouauto. - Résolvez les jetons de police source avant la validation. Si vous conservez des 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 et 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 d'affichage fixes avec des couches "monde" traduites/mises à l'échelle, le parallaxe, les panneaux épinglés, les défileurs horizontaux, les timelines nettoyées par défilement, l'ancrage 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 de progression, son easing et ses états de caméra/focalisation, puis réhébergez ce mouvement sur la navigation du diaporama via des positions de timeline, des fragments ou un crochet de lecteur/harnais réutilisable. Les encapsulateurs autonomes qui sautent aux points d'arrêt du slide ont toujours besoin d'un crochet de transition navigation-caméra explicite ; calculer les transformations de caméra par slide ne suffit pas. Ne simulez pas une transition littérale de défilement de page vers le bas à l'intérieur du slide ; le spectateur doit ressentir un voyage/dézoom de la 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 slide à slide continu : évitez les arrêts de route intermédiaires qui inversent la direction x/y ou le zoom d'une manière disproportionnée par rapport à la sensibilité naturelle du spectateur.
[La compétence se termine ici — les sections restantes sont tronquées dans l'entrée originale.]