Supprime le type d'écran "document" et recentre le produit sur le jeu 2D
Le document de cadrage produit cible des formateurs non techniques créant des serious games/quiz gamifiés — l'éditeur générique "document" (blocs de logique en nœuds, timeline d'animation, définitions d'objets/relations, templates réutilisables) est une complexité hors cible que l'effort d'ingénierie récent avait déjà abandonnée au profit du jeu_2d. - Onboarding : ne garde que le parcours "RPG" (jeu_2d), retire Quiz/Embranchement/Créer mon jeu de A à Z (tous document-only) - Suppression en bloc des modules exclusifs au document : routes/elements, routes/element_types, routes/objects, routes/legacy_actions, screens/elements, screens/element_types, screens/widgets, screens/legacy_actions, le rendu render_element_html.py et son cluster, templates/screen_edit.html, templates/game_dashboard.html, flow-editor.js/tabs-and-blocks.js/animation-timeline.js - Dashboard toujours simplifié (un seul mode possible désormais) - Tests document-only supprimés, tests de logique partagée (flow, événements personnalisés, animations) retargetés sur des écrans jeu_2d - Aucune régression jeu_2d : 299 tests passent Carte d'onboarding retravaillée : argumentaire RH non technique (liste à coche, badge "Compatible LMS"), taille et interaction de retournement ajustées.
This commit is contained in:
+119
-13
@@ -219,10 +219,21 @@ input[type=checkbox]{ width:auto; margin-top:6px; }
|
||||
les différents éditeurs d'un même jeu, en ligne (contrairement à
|
||||
.navList/.navRow ci-dessous, empilés verticalement dans le panneau
|
||||
"Créer" du tableau de bord). */
|
||||
.gameNavBar{ display:flex; flex-wrap:wrap; justify-content:center; gap:6px; padding:8px 20px; background:transparent; border-bottom:1px solid var(--border); }
|
||||
/* space-between (jamais center, voir le commentaire d'en-tête plus haut) :
|
||||
"Mes écrans" (page de gestion) reste à gauche, "Jouer"/"Exporter"
|
||||
(.gameNavRight, des ACTIONS) groupés à droite — demande explicite. */
|
||||
.gameNavBar{ display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:6px; padding:8px 20px; background:transparent; border-bottom:1px solid var(--border); }
|
||||
.gameNavRight{ display:flex; flex-wrap:wrap; gap:6px; margin-left:auto; }
|
||||
.gameNavLink{ display:inline-flex; align-items:center; gap:6px; padding:6px 10px; border:1px solid var(--border); border-radius:6px; background:var(--panel); text-decoration:none; color:var(--text); font-size:12.5px; }
|
||||
.gameNavLink:hover{ background:var(--panel2); border-color:var(--accent); }
|
||||
.gameNavLink.active{ background:var(--panel2); border-color:var(--accent); color:var(--accent); }
|
||||
/* "Jouer" (orange, --accent) / "Exporter" (vert, --status-success) —
|
||||
couleur pleine plutôt qu'un simple contour, pour ressortir comme des
|
||||
actions parmi les liens de gestion neutres. */
|
||||
.gameNavLink--play{ background:var(--accent); border-color:var(--accent); color:#fff; font-weight:600; }
|
||||
.gameNavLink--play:hover{ background:var(--accent); filter:brightness(1.1); border-color:var(--accent); }
|
||||
.gameNavLink--export{ background:var(--status-success); border-color:var(--status-success); color:#fff; font-weight:600; }
|
||||
.gameNavLink--export:hover{ background:var(--status-success); filter:brightness(1.1); border-color:var(--status-success); }
|
||||
.content{ max-width:760px; margin:0 auto; padding:28px 20px; }
|
||||
|
||||
.card{ border:1px solid var(--border); border-radius:10px; padding:16px; background:var(--panel); margin:12px 0; }
|
||||
@@ -246,14 +257,26 @@ input[type=checkbox]{ width:auto; margin-top:6px; }
|
||||
.onboardingStep{ flex:0 0 50%; width:50%; box-sizing:border-box; padding:12px 24px; }
|
||||
|
||||
/* ---------- Étape 1 : cartes de type, grandes, retournables ---------- */
|
||||
.onboardingGrid{ display:flex; gap:18px; height:66vh; min-height:420px; max-height:640px; }
|
||||
/* Un seul choix aujourd'hui (RPG, voir db/games/game_type_catalog.py) :
|
||||
pleine hauteur (comme avant), mais LARGEUR d'1/4 (comme s'il y avait
|
||||
toujours 4 cartes côte à côte) et centrée — demande explicite, plutôt
|
||||
que de repenser toute la mise en page pour un seul choix. */
|
||||
.onboardingGrid{ display:flex; gap:18px; height:66vh; min-height:420px; max-height:640px; max-width:25%; margin:0 auto; transition:max-width .35s ease; }
|
||||
/* Élargit la carte (jamais un scale() : demande explicite, "s'élargir sur
|
||||
sa width", pas grossir dans les deux sens) au survol/à la sélection —
|
||||
pour lire confortablement le dos retourné (titre + liste + badge, voir
|
||||
.onboardingPitch*) sans reprendre toute la mise en page à 4 cartes. Le
|
||||
sélecteur :has() cible le PARENT depuis l'état d'un enfant (support
|
||||
navigateurs modernes déjà requis ailleurs, voir container queries
|
||||
"cqw" plus bas). */
|
||||
.onboardingGrid:has(.onboardingCard:hover), .onboardingGrid:has(.onboardingCard.is-selected){ max-width:42%; }
|
||||
.onboardingCard{
|
||||
flex:1; position:relative; cursor:pointer; padding:0; margin:0; border:none; background:none;
|
||||
border-radius:20px; perspective:1400px;
|
||||
opacity:0; animation:forgeOnboardCardIn .5s ease both;
|
||||
transition:flex-grow .3s ease;
|
||||
}
|
||||
.onboardingCard:hover{ flex-grow:1.25; }
|
||||
.onboardingCard:hover{ flex-grow:1.25; z-index:1; }
|
||||
.onboardingCardInner{
|
||||
position:relative; display:block; width:100%; height:100%;
|
||||
transform-style:preserve-3d; transition:transform .6s cubic-bezier(.4,.2,.2,1);
|
||||
@@ -269,9 +292,30 @@ input[type=checkbox]{ width:auto; margin-top:6px; }
|
||||
.onboardingCardIcon{ font-size:3.4em; line-height:1; filter:drop-shadow(0 4px 10px rgba(0,0,0,.35)); }
|
||||
.onboardingCardLabel{ font-weight:800; font-size:1.3em; letter-spacing:.01em; }
|
||||
.onboardingCardBack{
|
||||
transform:rotateY(180deg); background:var(--panel); border:2px solid var(--accent);
|
||||
transform:rotateY(180deg); background:linear-gradient(165deg, var(--panel), var(--panel2));
|
||||
border:2px solid var(--accent); justify-content:flex-start; padding:26px 22px;
|
||||
}
|
||||
/* Argumentaire de vente (voir db/games/game_type_catalog.py::ONBOARDING_TYPES,
|
||||
"description" contient du HTML de confiance — jamais de saisie
|
||||
utilisateur — d'où |safe dans le template) : un titre accrocheur, une
|
||||
liste à coche plutôt qu'un bloc de texte brut, un badge LMS mis en
|
||||
avant en bas — pensé pour convaincre un public RH non technique en un
|
||||
coup d'œil, pas juste informer. */
|
||||
.onboardingCardDesc{ display:flex; flex-direction:column; gap:16px; width:100%; text-align:left; }
|
||||
.onboardingPitchTitle{ font-size:1.15em; font-weight:800; line-height:1.3; color:var(--text); }
|
||||
.onboardingPitchList{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:12px; }
|
||||
.onboardingPitchList li{ display:flex; align-items:flex-start; gap:10px; font-size:.93em; line-height:1.45; color:var(--text-dim); }
|
||||
.onboardingPitchCheck{
|
||||
flex:0 0 auto; width:20px; height:20px; border-radius:50%; background:var(--gradient);
|
||||
color:#fff; display:flex; align-items:center; justify-content:center; font-size:.7em; font-weight:900;
|
||||
box-shadow:0 2px 8px var(--glow); margin-top:1px;
|
||||
}
|
||||
.onboardingPitchList strong{ color:var(--text); }
|
||||
.onboardingPitchBadge{
|
||||
display:flex; align-items:center; gap:8px; font-size:.85em; font-weight:700;
|
||||
color:var(--accent); background:rgba(255,95,46,.12); border:1px solid rgba(255,95,46,.35);
|
||||
border-radius:999px; padding:8px 14px; align-self:flex-start;
|
||||
}
|
||||
.onboardingCardDesc{ color:var(--text); font-size:1em; line-height:1.5; }
|
||||
|
||||
/* Une couleur de dégradé par type — voir data-type dans le template,
|
||||
généré depuis db.ONBOARDING_TYPES (mêmes clés que ci-dessous). */
|
||||
@@ -513,10 +557,14 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
|
||||
}
|
||||
.floatPanelHeader .floatPanelTitle{ font-size:11px; color:var(--text-dim); text-transform:uppercase; letter-spacing:.05em; }
|
||||
.floatPanelBody{ padding:12px; overflow-y:auto; min-height:0; flex:1 1 auto; }
|
||||
.floatPanelReopenBtn{ position:fixed; top:90px; z-index:60; display:none; }
|
||||
/* Posés dans la barre d'outils de la scène (templates/scene_edit.html),
|
||||
plus en position:fixed flottant au-dessus de toute la page — ils
|
||||
chevauchaient "Mes écrans"/"Jouer"/"Exporter" (voir base.html) une fois
|
||||
les panneaux fermés. display:none/.visible (JS : openFloatPanel/
|
||||
closeFloatPanel, static/js/screen_edit/tree-panels.js) reste la même
|
||||
logique : visible seulement quand le panneau correspondant est fermé. */
|
||||
.floatPanelReopenBtn{ display:none; }
|
||||
.floatPanelReopenBtn.visible{ display:inline-flex; }
|
||||
#panelLeftReopenBtn{ left:24px; }
|
||||
#propsPanelReopenBtn{ right:24px; }
|
||||
|
||||
.widgetGrid{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }
|
||||
|
||||
@@ -615,6 +663,29 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
|
||||
.canvasElement:hover{ border-color:rgba(91,140,255,.5); }
|
||||
.canvasElement.selected{ border:2px solid var(--accent); }
|
||||
.canvasElementInner{ width:100%; height:100%; pointer-events:none; }
|
||||
/* render_scene_object.py positionne son <img> en absolu (left/top/width/
|
||||
height en px) pour s'afficher correctement en enfant DIRECT de
|
||||
.playScreen.playScene (voir templates/play.html) — dans le canevas de
|
||||
l'éditeur de scène (templates/scene_edit.html), cette même balise est
|
||||
nichée dans .canvasElementInner, lui-même déjà positionné/dimensionné
|
||||
par .canvasElement ci-dessus : sans ce correctif, l'image se
|
||||
positionnait EN PLUS depuis #canvas (son ancêtre positionné le plus
|
||||
proche), en double du décalage déjà appliqué par .canvasElement.
|
||||
Posé ici (feuille de style globale, chargée par TOUTES les pages) et
|
||||
non plus dans un <style> inline propre à scene_edit.html : la
|
||||
navigation "Mes écrans" -> scène se fait en pjax (voir static/pjax.js),
|
||||
qui ne fusionne dans <head> que les <link rel="stylesheet"> manquants,
|
||||
JAMAIS un <style> inline — arriver sur une scène par un clic (plutôt
|
||||
qu'un vrai chargement de page) laissait donc cette règle absente, et
|
||||
les personnages/décors se retrouvaient mal positionnés (invisibles)
|
||||
tant qu'aucun rechargement complet n'avait eu lieu. */
|
||||
.canvasElementInner > img{ position:static !important; left:auto !important; top:auto !important; width:100% !important; height:100% !important; z-index:auto !important; }
|
||||
/* Même correctif que ci-dessus, pour les widgets d'interface ("💬 Boîte
|
||||
de dialogue"/"❓ Boîte à quiz"/"🏆 Score", screens/scenes/
|
||||
render_scene_object.py) — des <div>, pas des <img>. */
|
||||
.canvasElementInner > .dialogueBoxWidget, .canvasElementInner > .quizBoxWidget, .canvasElementInner > .scoreWidget{
|
||||
position:static !important; left:auto !important; top:auto !important; width:100% !important; height:100% !important; z-index:auto !important;
|
||||
}
|
||||
/* Objet de scène (screens/scenes/render_scene_object.py, éditeur ET jeu
|
||||
jouable) : object-fit:contain — les frames CraftPix (screens/labels/
|
||||
animal_sprite_library.py) sont de grands canevas très paddés, très
|
||||
@@ -808,19 +879,31 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
|
||||
border:1px solid var(--border); border-radius:12px; padding:8px 10px;
|
||||
}
|
||||
.collisionRuleChainLinks{ display:flex; align-items:center; flex-wrap:wrap; row-gap:6px; }
|
||||
/* Pointe/encoche en PIXELS FIXES (calc(100% - 14px), jamais un pourcentage
|
||||
de la largeur du maillon) — un maillon plus court ("PNJ") ou plus long
|
||||
("Déclencher une quête « ... »") a alors TOUJOURS la même profondeur de
|
||||
pointe, qui s'emboîte exactement dans l'encoche du suivant (même 14px
|
||||
que la marge négative ci-dessous) : avec un pourcentage, la profondeur
|
||||
de la pointe variait avec la largeur du texte, sans jamais coïncider
|
||||
avec l'encoche du voisin — les pièces flottaient les unes par rapport
|
||||
aux autres au lieu de s'emboîter. */
|
||||
.collisionRuleLink{
|
||||
--link-color:var(--accent);
|
||||
position:relative; display:inline-flex; align-items:center; gap:4px;
|
||||
background:linear-gradient(135deg, var(--link-color), color-mix(in srgb, var(--link-color) 70%, #000 30%));
|
||||
color:#fff; padding:7px 16px 7px 20px; font-size:12.5px; font-weight:600; white-space:nowrap;
|
||||
clip-path:polygon(0% 0%, 90% 0%, 100% 50%, 90% 100%, 0% 100%, 10% 50%);
|
||||
margin-left:-12px; z-index:1; animation:collisionLinkIn .3s ease backwards;
|
||||
clip-path:polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%, 14px 50%);
|
||||
margin-left:-14px; z-index:1; animation:collisionLinkIn .3s ease backwards;
|
||||
transition:transform .15s ease, filter .15s ease;
|
||||
}
|
||||
.collisionRuleLink:first-child{ margin-left:0; clip-path:polygon(0% 0%, 90% 0%, 100% 50%, 90% 100%, 0% 100%); padding-left:14px; border-radius:8px 0 0 8px; }
|
||||
.collisionRuleLink:first-child{ margin-left:0; clip-path:polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%); padding-left:14px; border-radius:8px 0 0 8px; }
|
||||
.collisionRuleLink:hover{ transform:translateY(-2px) scale(1.04); filter:brightness(1.12); z-index:2; }
|
||||
.collisionRuleLink[data-kind="trigger"]{ --link-color:#f2994a; }
|
||||
.collisionRuleLink[data-kind="quete"]{ --link-color:#9b59b6; }
|
||||
/* "quete" est le seul type de maillon cliquable (voir collision-rules-
|
||||
editor.js — un onclick posé directement sur le <span>, jamais un
|
||||
<button> : son style natif grignotait la pointe en clip-path même
|
||||
après reset), d'où le curseur en plus ici. */
|
||||
.collisionRuleLink[data-kind="quete"]{ --link-color:#9b59b6; cursor:pointer; }
|
||||
.collisionRuleLink[data-kind="attaque"]{ --link-color:#e0524d; }
|
||||
.collisionRuleLink[data-kind="evenement"]{ --link-color:#17a2b8; }
|
||||
.collisionRuleLink[data-kind="interagir"]{ --link-color:#d4a72c; }
|
||||
@@ -884,6 +967,13 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
|
||||
(distincte de la modale de fiche ci-dessus) : couvre tout le viewport
|
||||
plutôt qu'une boîte centrée, pour laisser toute la place aux 3
|
||||
colonnes de répliques. */
|
||||
/* z-index:61 (au-dessus de .floatPanel, à 60, voir plus haut) : sans ça,
|
||||
les panneaux flottants "Objets"/"Propriétés" restaient peints par-
|
||||
dessus cette modale PLEIN ÉCRAN. Les boutons "Objets"/"Propriétés"
|
||||
eux-mêmes (.floatPanelReopenBtn) vivent maintenant dans la barre
|
||||
d'outils de la scène, plus en position:fixed — ce n'est donc plus qu'un
|
||||
souci entre CETTE modale et les panneaux flottants encore ouverts. */
|
||||
.questDialogueModal{ z-index:61; }
|
||||
.questDialogueModal .modal-content{ width:100vw; height:100vh; max-width:100vw; max-height:100vh; margin:0; }
|
||||
/* La modale entière est une colonne flex (jamais un scroll global, voir
|
||||
overflow:hidden ici) : le header/la fiche restent fixes en haut, les 3
|
||||
@@ -1097,7 +1187,12 @@ code{ background:var(--panel2); border:1px solid var(--border); border-radius:4p
|
||||
.builderTabBtn:hover{ color:var(--text); }
|
||||
.builderTabBtn.active{ color:var(--accent); border-bottom-color:var(--accent); font-weight:600; }
|
||||
|
||||
.builderTabPanel{ flex:1 1 auto; min-height:0; display:none; flex-direction:column; }
|
||||
/* overflow-y:auto : contrairement à "screen" (voir .canvasFrame plus haut,
|
||||
qui défile LUI-MÊME), "collision-rules"/"quests"/"events" n'ont pas de
|
||||
sous-conteneur dédié au défilement — sans ça, une liste plus haute que
|
||||
l'espace disponible restait simplement coupée par .builderCanvasArea
|
||||
(overflow:hidden), au lieu de défiler. */
|
||||
.builderTabPanel{ flex:1 1 auto; min-height:0; display:none; flex-direction:column; overflow-y:auto; }
|
||||
.builderTabPanel.active{ display:flex; }
|
||||
|
||||
/* Sous-onglets Champs/Données À L'INTÉRIEUR d'un panneau "Modifier un
|
||||
@@ -1223,6 +1318,17 @@ code{ background:var(--panel2); border:1px solid var(--border); border-radius:4p
|
||||
position:absolute; top:0; left:0; transform-origin:top left;
|
||||
transform:scale(calc(100cqw / var(--scene-w)));
|
||||
}
|
||||
/* obj.rendered_html (screens/scenes/render_scene_object.py) porte un
|
||||
z-index PENSÉ POUR L'ÉDITEUR DE SCÈNE (souvent très négatif — un "fond"
|
||||
à -1000, un personnage juste au-dessus — pour rester sous les cadres/
|
||||
poignées de sélection de CET éditeur, voir templates/scene_edit.html) :
|
||||
réutilisé tel quel ici, ce z-index très négatif faisait passer l'objet
|
||||
SOUS le fond de la carte (.screenPreviewBox, background:#0b0d12),
|
||||
invisible. L'ordre d'empilement voulu ici (fond, puis personnages/décor
|
||||
par-dessus) est déjà garanti par l'ORDRE dans lequel screen_preview()
|
||||
(game_dashboard_simple.html) les liste — z-index:auto (l'ordre du DOM)
|
||||
suffit donc, sans dépendre de leurs valeurs numériques d'origine. */
|
||||
.screenPreviewScene > *{ z-index:auto !important; }
|
||||
.screenPreviewEmpty{
|
||||
position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
|
||||
color:var(--forge-text-muted, #8b95a7); font-size:.85em;
|
||||
|
||||
Reference in New Issue
Block a user