diff --git a/assets/data/competences.json b/assets/data/competences.json
new file mode 100644
index 0000000..95d7429
--- /dev/null
+++ b/assets/data/competences.json
@@ -0,0 +1,572 @@
+[
+ {
+ "name": "Affabulation",
+ "type": "commune",
+ "description": "Raconter un mensonge pour semer le doute, tromper un interlocuteur et gagner du temps.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Charme inquisiteur",
+ "type": "commune",
+ "description": "Jouer de son charme physique ou du sentiment amoureux pour convaincre.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Diffamation",
+ "type": "commune",
+ "description": "Ridiculiser ou propager des rumeurs pour nuire à un adversaire sans arguments tangibles.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Fin négociateur",
+ "type": "commune",
+ "description": "Convaincre patiemment un interlocuteur ou négocier un prix avec des arguments convaincants.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Fraternité de comptoir",
+ "type": "commune",
+ "description": "S'entourer d'amis occasionnels pour obtenir des rumeurs, des informations ou des services.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Impassibilité / Comédie",
+ "type": "commune",
+ "description": "Dissimuler ses sentiments réels ou simuler une émotion pour tromper son entourage.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Intimidation / Don d'apaisement",
+ "type": "commune",
+ "description": "Jouer sur la peur des autres pour les impressionner ou, inversement, utiliser sa voix pour les calmer.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Menaces voilées",
+ "type": "commune",
+ "description": "Convaincre un adversaire qu'une vengeance ou une armée invisible le menace pour le faire cesser une action.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Mimétisme social",
+ "type": "commune",
+ "description": "Savoir se comporter et se vêtir de manière appropriée dans n'importe quel milieu social.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Provocation",
+ "type": "commune",
+ "description": "Pousser un interlocuteur à bout pour lui faire perdre son sang-froid ou causer un scandale.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Adrénaline",
+ "type": "commune",
+ "description": "Mobiliser des ressources cachées en cas de stress pour obtenir un bonus temporaire aux actions physiques.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Escalade et autres acrobaties",
+ "type": "commune",
+ "description": "Capacité à grimper des façades, marcher sur une corde ou effectuer des sauts périlleux.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Guérison rapide",
+ "type": "commune",
+ "description": "Capacité physique à récupérer plus vite de blessures ou de traumatismes physiques.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Passe d’armes spectaculaire",
+ "type": "commune",
+ "description": "Utiliser des mouvements d'armes impressionnants pour intimider ou faire hésiter des opposants.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Pugilat",
+ "type": "commune",
+ "description": "Maîtrise des techniques de combat non létales à mains nues ou avec des objets hétéroclites.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Résistance à la fatigue",
+ "type": "commune",
+ "description": "Capacité à rester éveillé, marcher longtemps ou supporter des veilles prolongées sans craquer.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Résistance à la souffrance",
+ "type": "commune",
+ "description": "Supporter la douleur physique intense, comme courir avec une cheville cassée ou subir une torture.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Résistance aux poisons et maladies",
+ "type": "commune",
+ "description": "Capacité organique à mieux résister aux toxines et à récupérer plus vite d'une pathologie.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Stoïcisme",
+ "type": "commune",
+ "description": "Paraître en pleine forme et impénétrable malgré les coups, la maladie ou la fatigue.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Survie dans la nature",
+ "type": "commune",
+ "description": "Trouver de la nourriture, repérer des traces de prédateurs et s'abriter en milieu sauvage.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Artisanat (un au choix)",
+ "type": "commune",
+ "description": "Maîtrise d'un métier manuel ou artistique (forgeron, peintre, musicien, etc.).",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Camouflage d’objet",
+ "type": "commune",
+ "description": "Dissimuler des objets sur soi ou dans une pièce, ou repérer ceux cachés par autrui.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Cartographie / Orientation",
+ "type": "commune",
+ "description": "Comprendre et dessiner des cartes, utiliser des instruments de navigation et s'orienter sur terre comme en mer.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Don des affaires",
+ "type": "commune",
+ "description": "Comptabilité, logistique de caravane et gestion des stocks liés au commerce.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Espionnage",
+ "type": "commune",
+ "description": "Connaissance des techniques de renseignement (boîte aux lettres morte, filature, écoute clandestine).",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Falsification",
+ "type": "commune",
+ "description": "Imiter une écriture, fabriquer de faux sceaux et modifier des documents officiels.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Organisation militaire",
+ "type": "commune",
+ "description": "Gérer la cohésion d'une troupe et organiser des hommes, que ce soit une patrouille ou une armée.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Quidam lambda",
+ "type": "commune",
+ "description": "Se fondre dans la foule urbaine pour passer inaperçu ou prendre quelqu'un en filature.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Stratégie",
+ "type": "commune",
+ "description": "Établir des plans de bataille, estimer les forces ennemies et mener des campagnes militaires.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Symbiose animale",
+ "type": "commune",
+ "description": "Créer un rapport de confiance avec les bêtes pour éviter les attaques ou les apprivoiser.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Connaissance de l’Inframonde",
+ "type": "commune",
+ "description": "Savoir théorique sur la dimension de l'Inframonde, ses portails et ses créatures malveillantes.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Connaissance des Arcanes",
+ "type": "commune",
+ "description": "Comprendre le fonctionnement et les limites de la magie, ainsi que l'histoire de la thaumaturgie.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Corruption de bureaucrate",
+ "type": "commune",
+ "description": "Identifier les faiblesses des employés de l'administration pour obtenir des faveurs ou des informations.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Enquête / Investigation",
+ "type": "commune",
+ "description": "Repérer des détails inhabituels, résoudre des énigmes et comprendre les motivations cachées.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Herboristerie",
+ "type": "commune",
+ "description": "Trouver des plantes et confectionner des remèdes de base, des poisons simples ou des hallucinogènes.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Langage des runes",
+ "type": "commune",
+ "description": "Lire et déchiffrer les runes chargées de magie sur des parchemins ou des gravures.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Langue (parler, lire et écrire)",
+ "type": "commune",
+ "description": "Maîtrise orale et/ou écrite de langues étrangères ou anciennes.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Recherche en bibliothèque",
+ "type": "commune",
+ "description": "Méthodologie pour trouver des informations dans les archives et déchiffrer des textes anciens.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Savoir encyclopédique",
+ "type": "commune",
+ "description": "Posséder une grande culture générale sur de multiples sujets théoriques et historiques.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Soins basiques",
+ "type": "commune",
+ "description": "Donner les premiers secours (lavage, suture, bandages) pour stabiliser un blessé.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Excellent joueur",
+ "type": "peuple",
+ "peuple": "Centuplide",
+ "description": "Instinct du jeu, des paris et du bluff permettant de gagner même quand le hasard est seul facteur.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Violence caniculaire",
+ "type": "peuple",
+ "peuple": "Centuplide",
+ "description": "Utiliser sa force et son agilité reptilienne pour porter des coups d'une violence extrême.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Itinéraire",
+ "type": "peuple",
+ "peuple": "Centuplide",
+ "description": "Mémoire infaillible des routes et chemins parcourus, empêchant de se perdre en extérieur.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Conscience collective",
+ "type": "peuple",
+ "peuple": "Centuplide",
+ "description": "Percevoir l'état de santé, le moral et la position approximative des centuplides à proximité.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Diplomatie éowin",
+ "type": "peuple",
+ "peuple": "Éowin",
+ "description": "Talent naturel pour servir de médiateur et d'intermédiaire dans les accords ou traités de paix.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Esquive éowin",
+ "type": "peuple",
+ "peuple": "Éowin",
+ "description": "Agilité exceptionnelle permettant d'éviter les coups plutôt que de les bloquer.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Compréhension des mécanismes complexes",
+ "type": "peuple",
+ "peuple": "Éowin",
+ "description": "Don instinctif pour comprendre et réparer des mécanismes d'horlogerie, serrures ou moulins.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Perception empathique",
+ "type": "peuple",
+ "peuple": "Éowin",
+ "description": "Ressentir l'atmosphère générale et les sentiments qui animent une foule ou un groupe.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Langage des captifs",
+ "type": "peuple",
+ "peuple": "Cendrove",
+ "description": "Langage corporel sommaire permettant de communiquer des sentiments ou intentions sans parler.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Symbiose avec l'Entremonde",
+ "type": "peuple",
+ "peuple": "Cendrove",
+ "description": "Capacité spirituelle à entrer dans un état de fureur apportant des bonus aux actions d'Épée.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Cachette de fortune",
+ "type": "peuple",
+ "peuple": "Cendrove",
+ "description": "Savoir utiliser le terrain pour se cacher soi-même ou des objets de manière quasi indétectable.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Lecture des astres",
+ "type": "peuple",
+ "peuple": "Cendrove",
+ "description": "Interpréter le mouvement des étoiles pour obtenir des indices sur le futur ou une direction.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Expertise politique",
+ "type": "faction",
+ "faction": "Administrum",
+ "description": "Anticiper les bénéficiaires d'une action politique et déceler les ruses lors de signatures d'accords.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Profil bas",
+ "type": "faction",
+ "faction": "Administrum",
+ "description": "Paraître insignifiant ou laisser entendre que sa fonction garantit une rançon pour éviter les coups.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Application de la loi impériale",
+ "type": "faction",
+ "faction": "Administrum",
+ "description": "Connaître les lois pour les exécuter ou les contourner légalement avec un argumentaire solide.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Connaissance de la technologie hamalronienne",
+ "type": "faction",
+ "faction": "Administrum",
+ "description": "Savoir utiliser ou fabriquer des installations technologiques de l'âge d'or (vapeur, hydraulique).",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Vieilles amitiés",
+ "type": "faction",
+ "faction": "Bastion",
+ "description": "Activer des liens familiaux ou nobiliaires transmis sur plusieurs générations pour obtenir de l'aide.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Botte secrète",
+ "type": "faction",
+ "faction": "Bastion",
+ "description": "Utiliser une ruse d'escrime spécifique pour surprendre un adversaire et obtenir un bonus.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Mobilisation",
+ "type": "faction",
+ "faction": "Bastion",
+ "description": "Capacité à lever une troupe de fidèles dans une région donnée grâce à son influence nobiliaire.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Histoire de la noblesse",
+ "type": "faction",
+ "faction": "Bastion",
+ "description": "Connaissance approfondie de l'héraldique, des lignées, des exploits et des secrets des grandes familles.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Serment d’honneur",
+ "type": "faction", "faction": "Chevaliers de la Rose grise", "description": "Donner sa parole pour gagner en crédibilité, amadouer ou effrayer, au prix de l'obligation de la tenir.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Duel",
+ "type": "faction",
+ "faction": "Chevaliers de la Rose grise",
+ "description": "Expertise du combat à la loyale, en un contre un au corps à corps.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Entretien de l’armement",
+ "type": "faction", "faction": "Chevaliers de la Rose grise", "description": "Prendre soin de son matériel de guerre pour bénéficier de bonus lors des futurs combats.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Allié potentiel",
+ "type": "faction",
+ "faction": "Chevaliers de la Rose grise",
+ "description": "Instinct permettant de sentir si une personne rencontrée peut devenir un allié fiable.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Toujours à sa place",
+ "type": "faction",
+ "faction": "Confrérie des Servants",
+ "description": "Capacité à se fondre dans le décor et passer inaperçu quel que soit le milieu.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Attaque-surprise",
+ "type": "faction",
+ "faction": "Confrérie des Servants",
+ "description": "Usage d'armes cachées, dégainés rapides ou fauchages pour surprendre l'adversaire en combat.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Doigts agiles",
+ "type": "faction",
+ "faction": "Confrérie des Servants",
+ "description": "Techniques de crochetage, vol de clés ou de documents en toute discrétion.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Conseil politique",
+ "type": "faction",
+ "faction": "Confrérie des Servants",
+ "description": "Connaissance approfondie des forces en présence et du pouvoir des dignitaires pour conseiller les puissants.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Sermon",
+ "type": "faction",
+ "faction": "Ecclésiarchie",
+ "description": "Embraser les foules ou réconforter les âmes par la parole et les gestes religieux.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Foi inébranlable",
+ "type": "faction",
+ "faction": "Ecclésiarchie",
+ "description": "Utiliser sa conviction religieuse pour lutter ou résister à la peur dans des situations liées à la foi.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Simonie",
+ "type": "faction",
+ "faction": "Ecclésiarchie",
+ "description": "Maîtriser le commerce légal des biens religieux, reliques ou absolutions.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Théologie",
+ "type": "faction",
+ "faction": "Ecclésiarchie",
+ "description": "Connaissance des secrets, dogmes et débats religieux pour l'étude ou les procès ecclésiastiques.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Extorsion / Racket",
+ "type": "faction",
+ "faction": "Fraternité du Poing de fer",
+ "description": "Obtenir de l'argent ou des privilèges par l'usage de menaces typiques de la pègre.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Assassinat",
+ "type": "faction",
+ "faction": "Fraternité du Poing de fer",
+ "description": "Éliminer furtivement une cible humanoïde surprise avec des armes discrètes.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Arnaque",
+ "type": "faction",
+ "faction": "Fraternité du Poing de fer",
+ "description": "Maîtrise de la roublardise, des détournements et des stratagèmes complexes (comme les ruses de siège).",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Langage des signes",
+ "type": "faction",
+ "faction": "Fraternité du Poing de fer",
+ "description": "Système gestuel et écrit secret permettant aux membres de la pègre de communiquer discrètement.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Fibre commerçante",
+ "type": "faction",
+ "faction": "Guildes marchandes",
+ "description": "Art de susciter la compassion pour conclure un marché avantageux ou vendre des produits inutiles.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Instinct de survie",
+ "type": "faction",
+ "faction": "Guildes marchandes",
+ "description": "Utiliser l'environnement (objets, obstacles) pour se protéger d'une attaque au détriment de l'offensive.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Réseau marchand",
+ "type": "faction",
+ "faction": "Guildes marchandes",
+ "description": "Savoir mobiliser ses filières pour dénicher des objets rares ou organiser des échanges commerciaux.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Évaluation d’un produit",
+ "type": "faction", "faction": "Guildes marchandes", "description": "Déterminer le prix juste, la rareté et la fonction d'une marchandise.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Menace de sorcier",
+ "type": "faction",
+ "faction": "Sororité de la Sinistrose",
+ "description": "Laisser entendre que l'on dispose de pouvoirs pour effrayer un adversaire et le faire céder.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Magie de combat",
+ "type": "faction",
+ "faction": "Sororité de la Sinistrose",
+ "description": "Canaliser l'adrénaline du danger pour amplifier la puissance des arts magiques lors du lancement d'un sort.",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Alchimie",
+ "type": "faction",
+ "faction": "Sororité de la Sinistrose",
+ "description": "Art de concevoir des potions, onguents et objets magiques à partir de composants naturels.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Manipulation des Arcanes",
+ "type": "faction",
+ "faction": "Sororité de la Sinistrose",
+ "description": "Détecter les émanations magiques et identifier le type ou la puissance d'un sortilège environnant.",
+ "carteSymbole": "coupe"
+ },
+ {
+ "name": "Fraternité des trois",
+ "type": "faction",
+ "faction": "Triumvirat",
+ "description": "User de son charisme pour convaincre un autre non-humain de changer de camp ou de s'entraider.",
+ "carteSymbole": "denier"
+ },
+ {
+ "name": "Art de combat racial",
+ "type": "faction",
+ "faction": "Triumvirat",
+ "description": "Maîtrise d'une technique d'attaque spécifique à sa race (Cendrove, Centuplide ou Éowin).",
+ "carteSymbole": "epee"
+ },
+ {
+ "name": "Commerce réservé",
+ "type": "faction",
+ "faction": "Triumvirat",
+ "description": "Accéder à des produits rares ou inaccessibles par les réseaux de solidarité primogènes.",
+ "carteSymbole": "baton"
+ },
+ {
+ "name": "Savoir des races anciennes",
+ "type": "faction",
+ "faction": "Triumvirat",
+ "description": "Connaissance de l'histoire et des secrets des peuples primogènes avant l'arrivée des humains.",
+ "carteSymbole": "coupe"
+ }
+]
diff --git a/assets/data/factions.json b/assets/data/factions.json
new file mode 100644
index 0000000..9cd8232
--- /dev/null
+++ b/assets/data/factions.json
@@ -0,0 +1,38 @@
+[
+ {
+ "nom": "Administrum",
+ "description": "Faction composée de sages, d'érudits et de magisters au service de l'impératrice Minarquas. Prônant l'épistémocratie, ils gèrent l'administration, les impôts et les grands travaux pour assurer la stabilité et le progrès éclairé de l'Empire."
+ },
+ {
+ "nom": "Le Bastion",
+ "description": "Organisation clandestine regroupant les familles nobles les plus conservatrices, principalement en Malantise. Ils défendent farouchement leurs privilèges féodaux, s'opposent au Triumvirat et rêvent de restaurer un ordre social ancien basé sur la hiérarchie des races."
+ },
+ {
+ "nom": "Les Chevaliers de la Rose grise",
+ "description": "Ordre de guerriers impulsifs et honorables servant le roi du Chenara et l'impératrice. Bien que non exclusivement nobles, ils constituent une troupe d'élite dévouée aux valeurs chevaleresques et au passé glorieux, tout en méprisant les activités marchandes."
+ },
+ {
+ "nom": "La Confrérie des Servants",
+ "description": "Guilde secrète et neutre qui forme des espions, des assassins et des conseillers politiques de haut niveau. Infiltrés dans toutes les strates du pouvoir sous couvert de domesticité, ses membres sont liés par une loi du silence absolue sous peine de mort."
+ },
+ {
+ "nom": "L'Ecclésiarchie",
+ "description": "Institution religieuse officielle dédiée au culte d'Hamalron le Bâtisseur. Exclusivement masculine, elle exerce une influence morale et politique immense sur toutes les classes sociales, tout en luttant pour sa suprématie spirituelle et contre l'usage des arcanes."
+ },
+ {
+ "nom": "La Fraternité du Poing de fer",
+ "description": "Organisation criminelle clandestine contrôlant la pègre des grandes cités. Fondée à l'origine comme une force de résistance contre l'arbitraire des puissants, elle mêle idéalisme et banditisme, regroupant humains et non-humains dans un climat de paranoïa constante."
+ },
+ {
+ "nom": "Les Guildes marchandes",
+ "description": "Alliance puissante des corporations commerçantes de l'Empire. Motivées par le seul profit et dépourvues d'idéologie fixe, elles utilisent leur immense richesse pour influencer la politique et s'allient opportunistement avec n'importe quel camp selon leurs intérêts financiers."
+ },
+ {
+ "nom": "La Sororité de Sinistrose",
+ "description": "Culte féminin de magiciennes (Sœurs-Zélotes) dévouées à la matriarche Astasia. Détentrices du monopole de la magie, elles utilisent la séduction et le magnétisme pour influencer les puissants dans le but secret de restaurer la Gynarchie oubliée."
+ },
+ {
+ "nom": "Le Triumvirat",
+ "description": "Corps politique et armé défendant les intérêts des peuples primogènes (cendroves, centuplides et éowins). Ils luttent pour la justice, l'égalité des droits au sein de l'Empire et s'opposent radicalement à l'esclavage dont leurs races ont longtemps souffert."
+ }
+]
\ No newline at end of file
diff --git a/assets/data/peuples.json b/assets/data/peuples.json
new file mode 100644
index 0000000..15727b2
--- /dev/null
+++ b/assets/data/peuples.json
@@ -0,0 +1,34 @@
+[
+ {
+ "nom": "Hamalroniens",
+ "description": "Ensemble des peuples humains disséminés partout dans les Cinq Contrées et au-delà [1]. Bien qu'ils possèdent des traits physiques et des coutumes variant selon leur habitat (teint, taille), ils sont reliés par la religion et un système politique basé sur la féodalité [1, 2]."
+ },
+ {
+ "nom": "Centuplides",
+ "description": "Sous-race majoritaire des draconides, ce sont des hommes-lézards puissants et massifs (1m90 à 2m30) dotés d'une queue musclée [3, 4]. Ils sont célèbres pour leur extraordinaire pouvoir de régénération et leur capacité à s'acclimater physiquement à de nouveaux environnements en quelques années [5]."
+ },
+ {
+ "nom": "Éowins",
+ "description": "Surnommés le « peuple pacificateur », ce sont de petits êtres asexués (1m à 1m30) créés originellement par les Tharnes [6, 7]. Joyeux et hédonistes, ils sont des médiateurs nés et possèdent un don instinctif pour comprendre et réparer les mécanismes complexes [6, 8]."
+ },
+ {
+ "nom": "Cendroves",
+ "description": "Humanoïdes élancés aux longues oreilles pointues, ils sont les plus proches des humains par leur structure sociale [9, 10]. Ils se distinguent par une perception du temps fluctuante et la capacité d'entrer en « symbiose avec l’Entremonde », un état d'hyperactivité coordonnée déclenché par la colère ou le danger [9, 11]."
+ },
+ {
+ "nom": "Krinals",
+ "description": "Géants (2m à 2m30) à la peau pâle et au sang bleu vivant dans les steppes glacées du Svenhaagen [12]. Chasseurs et guerriers redoutables, ils méprisent les sciences théoriques, valorisent la puissance personnelle et excellent dans le dressage de créatures massives [13-15]."
+ },
+ {
+ "nom": "Dvärgs",
+ "description": "Petits humanoïdes difformes et solitaires vivant dans les montagnes [16, 17]. Ils possèdent des pouvoirs magiques liés à la terre, peuvent se fondre dans la roche et consacrent leur existence à sculpter les montagnes qu'ils perçoivent comme une œuvre d'art [17, 18]."
+ },
+ {
+ "nom": "Gnomes nomades",
+ "description": "Petits êtres souterrains (50 à 60 cm) fuyant le contact avec les autres peuples par peur maladive [19]. Ils ne mangent pas mais absorbent les effluves magiques, sont d'habiles terrassiers et possèdent le pouvoir de fusionner avec la pierre [19]."
+ },
+ {
+ "nom": "Tharnes (Drezaxilons)",
+ "description": "Ancien peuple d'humanoïdes ailés à la beauté divine et aux connaissances magiques immenses [20]. Autrefois maîtres du monde avant l'arrivée des hommes, ils ont disparu suite à une malédiction de stérilité et une guerre contre les centuplides [6, 21, 22]."
+ }
+]
\ No newline at end of file
diff --git a/assets/fonts/EagleLake-Regular.ttf b/assets/fonts/EagleLake-Regular.ttf
new file mode 100644
index 0000000..bd726f4
Binary files /dev/null and b/assets/fonts/EagleLake-Regular.ttf differ
diff --git a/assets/fonts/Times New Roman.ttf b/assets/fonts/Times New Roman.ttf
new file mode 100644
index 0000000..5cdac9c
Binary files /dev/null and b/assets/fonts/Times New Roman.ttf differ
diff --git a/assets/icons/arme.svg b/assets/icons/arme.svg
new file mode 100644
index 0000000..719df3e
--- /dev/null
+++ b/assets/icons/arme.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/armor.webp b/assets/icons/armor.webp
deleted file mode 100644
index 7fc4ddd..0000000
Binary files a/assets/icons/armor.webp and /dev/null differ
diff --git a/assets/icons/armure.svg b/assets/icons/armure.svg
new file mode 100644
index 0000000..20b43d5
--- /dev/null
+++ b/assets/icons/armure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/competence.svg b/assets/icons/competence.svg
new file mode 100644
index 0000000..7997747
--- /dev/null
+++ b/assets/icons/competence.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/deal.webp b/assets/icons/deal.webp
deleted file mode 100644
index 2902ab4..0000000
Binary files a/assets/icons/deal.webp and /dev/null differ
diff --git a/assets/icons/equipement.svg b/assets/icons/equipement.svg
new file mode 100644
index 0000000..1f9eb0a
--- /dev/null
+++ b/assets/icons/equipement.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/equipment.webp b/assets/icons/equipment.webp
deleted file mode 100644
index 01ba887..0000000
Binary files a/assets/icons/equipment.webp and /dev/null differ
diff --git a/assets/icons/faction.svg b/assets/icons/faction.svg
new file mode 100644
index 0000000..5501172
--- /dev/null
+++ b/assets/icons/faction.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/langue.svg b/assets/icons/langue.svg
new file mode 100644
index 0000000..87949c0
--- /dev/null
+++ b/assets/icons/langue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/malefica.webp b/assets/icons/malefica.webp
deleted file mode 100644
index fac08db..0000000
Binary files a/assets/icons/malefica.webp and /dev/null differ
diff --git a/assets/icons/perk.webp b/assets/icons/perk.webp
deleted file mode 100644
index 99d549d..0000000
Binary files a/assets/icons/perk.webp and /dev/null differ
diff --git a/assets/icons/peuple.svg b/assets/icons/peuple.svg
new file mode 100644
index 0000000..341ba7d
--- /dev/null
+++ b/assets/icons/peuple.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/region.svg b/assets/icons/region.svg
new file mode 100644
index 0000000..1069257
--- /dev/null
+++ b/assets/icons/region.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/ritual.webp b/assets/icons/ritual.webp
deleted file mode 100644
index 2649c66..0000000
Binary files a/assets/icons/ritual.webp and /dev/null differ
diff --git a/assets/icons/sortilege.svg b/assets/icons/sortilege.svg
new file mode 100644
index 0000000..fe39ed4
--- /dev/null
+++ b/assets/icons/sortilege.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/species-trait.webp b/assets/icons/species-trait.webp
deleted file mode 100644
index 9b2b6bc..0000000
Binary files a/assets/icons/species-trait.webp and /dev/null differ
diff --git a/assets/icons/tarot.svg b/assets/icons/tarot.svg
new file mode 100644
index 0000000..c6b1734
--- /dev/null
+++ b/assets/icons/tarot.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/tarot.webp b/assets/icons/tarot.webp
deleted file mode 100644
index 4c8078f..0000000
Binary files a/assets/icons/tarot.webp and /dev/null differ
diff --git a/assets/icons/weapon.webp b/assets/icons/weapon.webp
deleted file mode 100644
index 799c047..0000000
Binary files a/assets/icons/weapon.webp and /dev/null differ
diff --git a/css/fvtt-hamalron.css b/css/fvtt-hamalron.css
index 3913469..5d3e050 100644
--- a/css/fvtt-hamalron.css
+++ b/css/fvtt-hamalron.css
@@ -1,30 +1,33 @@
@font-face {
- font-family: "MinionProRegular";
- src: url("../assets/fonts/Minion Pro Regular.ttf") format("truetype");
+ font-family: "TimesNewRoman";
+ src: url("../assets/fonts/Times New Roman.ttf") format("truetype");
}
@font-face {
- font-family: "SupernaturalKnight";
- src: url("../assets/fonts/Supernatural_Knight.ttf") format("truetype");
+ font-family: "EagleLake";
+ src: url("../assets/fonts/EagleLake-Regular.ttf") format("truetype");
}
:root {
--font-size-standard: 0.9rem;
--font-size-result: 1.4rem;
--background-image-base: url("../assets/ui/sheet_background_01.webp");
- --font-primary: "MinionProRegular";
- --font-secondary: "MinionProRegular";
- --font-title: "SupernaturalKnight";
+ --font-primary: "TimesNewRoman";
+ --font-secondary: "TimesNewRoman";
+ --font-title: "EagleLake";
--logo-standard: url("../assets/ui/pentagram_logo.webp");
- --title-color: #c9a876;
+ --title-color: #dea60b;
--background-box: #e0dcdc;
--color-success: #0f7a0f;
--color-failure: #8b7355;
--color-warning: darkorange;
--color-critical-success: #1527cc;
--color-critical-failure: #8d20e7;
+ --color-sheet-nav: #120c04;
+ --input-height: 1.2rem;
}
body {
--color-light-1: rgba(182, 178, 178, 0.6);
--color-warm-1: #c9a876;
+ --input-height: 1.4rem;
}
#logo {
content: var(--logo-standard);
@@ -150,8 +153,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .character-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -161,10 +164,15 @@ i.fvtt-hamalron {
}
.fvtt-hamalron .sheet-tabs {
background-color: var(--color-light-1);
+ font-family: var(--font-title);
+}
+.fvtt-hamalron .sheet-tabs a {
+ color: var(--color-sheet-nav);
+ font-size: 0.9rem;
}
.fvtt-hamalron .character-main {
- /*background-color: var(--color-light-1);*/
display: flex;
+ justify-content: center;
}
.fvtt-hamalron .character-main .character-pc {
display: flex;
@@ -172,7 +180,7 @@ i.fvtt-hamalron {
flex: 1;
}
.fvtt-hamalron .character-main .character-pc .character-left {
- min-width: 180px;
+ min-width: 220px;
display: flex;
flex-direction: column;
}
@@ -210,11 +218,7 @@ i.fvtt-hamalron {
.fvtt-hamalron .character-main .character-pc .character-right {
display: flex;
flex-direction: column;
- gap: 5px;
-}
-.fvtt-hamalron .character-main .character-pc .character-right .character-definition .character-definition-pronouns input {
- min-width: 21.2rem;
- max-width: 21.2rem;
+ gap: 2px;
}
.fvtt-hamalron .character-main .character-pc .character-right .character-definition .form-group {
display: flex;
@@ -242,6 +246,28 @@ i.fvtt-hamalron {
margin-right: 1rem;
margin-bottom: auto;
}
+.fvtt-hamalron .character-main .character-pc .character-right .character-definition .item-controls {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ flex: 1;
+}
+.fvtt-hamalron .character-main .character-pc .character-right .character-definition .item-controls .item-name {
+ flex: 1;
+ min-width: 0;
+}
+.fvtt-hamalron .character-main .character-pc .character-right .character-definition .item-controls .control {
+ flex-shrink: 0;
+ cursor: pointer;
+ opacity: 0.7;
+ transition: opacity 0.2s;
+}
+.fvtt-hamalron .character-main .character-pc .character-right .character-definition .item-controls .control:hover {
+ opacity: 1;
+}
+.fvtt-hamalron .character-main .character-pc .character-right .character-definition .item-controls .control i {
+ font-size: 0.9rem;
+}
.fvtt-hamalron .character-main .character-pc .character-right .character-name {
display: flex;
}
@@ -254,39 +280,125 @@ i.fvtt-hamalron {
min-width: 120px;
}
.fvtt-hamalron .character-main .character-pc-play {
- min-width: 500px;
+ min-width: 660px;
}
.fvtt-hamalron .character-main .character-pc-edit {
- min-width: 500px;
+ min-width: 660px;
}
.fvtt-hamalron .character-main .character-stats {
/*background-color: var(--color-light-1);*/
display: flex;
flex-direction: column;
- gap: 5px;
+ gap: 2px;
flex: 1;
}
+.fvtt-hamalron .character-main .character-stats .stats-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.2rem;
+}
.fvtt-hamalron .character-main .character-stats .character-stat {
display: flex;
align-items: center;
+ justify-content: space-between;
+ gap: 0.2rem;
+ padding: 0.1rem 0.2rem;
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
}
-.fvtt-hamalron .character-main .character-stats .character-stat .icon-stat {
- width: 24px;
- height: 24px;
- margin-right: 4px;
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-label {
+ flex: 1;
+ min-width: 0;
}
-.fvtt-hamalron .character-main .character-stats .character-stat .rollable:hover,
-.fvtt-hamalron .character-main .character-stats .character-stat .rollable:focus {
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-label.rollable:hover,
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-label.rollable:focus {
text-shadow: 0 0 8px var(--color-shadow-primary);
cursor: pointer;
}
-.fvtt-hamalron .character-main .character-stats .character-stat .rollable {
- min-width: 3.5rem;
- max-width: 3.5rem;
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-label i {
+ margin-right: 0.25rem;
}
-.fvtt-hamalron .character-main .character-stats .character-stat input {
- min-width: 2.5rem;
- max-width: 2.5rem;
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-values {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ flex-shrink: 0;
+}
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-values input {
+ width: 3rem;
+ text-align: center;
+}
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-values .stat-value {
+ width: 3rem;
+ text-align: center;
+ display: inline-block;
+}
+.fvtt-hamalron .character-main .character-stats .character-stat .stat-values .separator {
+ font-weight: bold;
+ color: var(--color-text-dark-secondary);
+}
+.fvtt-hamalron .character-main .character-resistances {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ flex: 1;
+}
+.fvtt-hamalron .character-main .character-resistances .resistances-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.2rem;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.2rem;
+ padding: 0.1rem 0.2rem;
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-label {
+ flex: 1;
+ min-width: 0;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values {
+ display: flex;
+ align-items: center;
+ gap: 0.2rem;
+ flex-shrink: 0;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values input {
+ width: 3rem;
+ text-align: center;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values .stat-value {
+ width: 3rem;
+ text-align: center;
+ display: inline-block;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values .resistance-control {
+ cursor: pointer;
+ opacity: 0.8;
+ transition: all 0.2s ease;
+ padding: 0.15rem 0.35rem;
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 3px;
+ color: var(--color-text-dark-primary);
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values .resistance-control:hover {
+ opacity: 1;
+ background: rgba(0, 100, 200, 0.2);
+ transform: scale(1.1);
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values .resistance-control:active {
+ transform: scale(0.95);
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values .resistance-control i {
+ font-size: 0.7rem;
+}
+.fvtt-hamalron .character-main .character-resistances .resistance-stat .stat-values .separator {
+ font-weight: bold;
+ color: var(--color-text-dark-secondary);
}
.fvtt-hamalron .character-main .character-stats-play {
min-width: 120px;
@@ -294,16 +406,126 @@ i.fvtt-hamalron {
.fvtt-hamalron .character-main .character-stats-edit {
min-width: 120px;
}
-.fvtt-hamalron .tab.character-status .main-div {
+.fvtt-hamalron .tab.character-competences .main-div {
/*background-color: var(--color-light-1);*/
display: grid;
grid-template-columns: 1fr;
+ gap: 8px;
}
-.fvtt-hamalron .tab.character-status .main-div legend a {
+.fvtt-hamalron .tab.character-competences .main-div legend a {
font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px;
}
-.fvtt-hamalron .tab.character-status .main-div .mortality {
+.fvtt-hamalron .tab.character-competences .main-div .competences-group {
+ margin-bottom: 12px;
+ background: rgba(0, 0, 0, 0.03);
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: 4px;
+ padding: 8px;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences-group .competences-type-header {
+ font-weight: bold;
+ font-size: calc(var(--font-size-standard) * 1.1);
+ color: var(--color-text-dark-primary);
+ margin-bottom: 8px;
+ padding: 4px 8px;
+ border-left: 3px solid var(--color-border-dark-primary);
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 6px;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 6px;
+ background: rgba(255, 255, 255, 0.6);
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: 3px;
+ transition: all 0.2s ease;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence:hover {
+ background: rgba(255, 255, 255, 0.9);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .item-img {
+ width: 28px;
+ height: 28px;
+ border-radius: 3px;
+ flex-shrink: 0;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .name {
+ flex: 1;
+ min-width: 0;
+ font-weight: 500;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .name a {
+ color: var(--color-text-dark-primary);
+ text-decoration: none;
+ cursor: pointer;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .name a:hover {
+ color: var(--color-text-hyperlink);
+ text-decoration: underline;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .carte {
+ font-size: 0.85rem;
+ padding: 2px 6px;
+ background: rgba(0, 0, 0, 0.08);
+ border-radius: 3px;
+ white-space: nowrap;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .niveau {
+ font-size: 0.85rem;
+ padding: 2px 6px;
+ background: rgba(0, 100, 200, 0.1);
+ color: var(--color-text-dark-primary);
+ border-radius: 3px;
+ white-space: nowrap;
+ font-weight: 500;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .controls {
+ display: flex;
+ gap: 4px;
+ font-size: 0.85rem;
+ flex-shrink: 0;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .controls a {
+ padding: 2px 4px;
+ color: var(--color-text-dark-secondary);
+ cursor: pointer;
+ transition: color 0.2s ease;
+}
+.fvtt-hamalron .tab.character-competences .main-div .competences .competence .controls a:hover {
+ color: var(--color-text-dark-primary);
+}
+.fvtt-hamalron .tab.character-competences .main-div .add-competence-section {
+ text-align: center;
+ padding: 12px;
+}
+.fvtt-hamalron .tab.character-competences .main-div .add-competence-section .add-competence-button {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 16px;
+ background: rgba(0, 100, 200, 0.1);
+ border: 1px solid rgba(0, 100, 200, 0.3);
+ border-radius: 4px;
+ color: var(--color-text-dark-primary);
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+.fvtt-hamalron .tab.character-competences .main-div .add-competence-section .add-competence-button:hover {
+ background: rgba(0, 100, 200, 0.2);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+.fvtt-hamalron .tab.character-competences .main-div .add-competence-section .add-competence-button i {
+ font-size: 1rem;
+}
+.fvtt-hamalron .tab.character-competences .main-div .mortality {
display: flex;
align-items: center;
gap: 4px;
@@ -311,38 +533,38 @@ i.fvtt-hamalron {
min-width: 12rem;
max-width: 12rem;
}
-.fvtt-hamalron .tab.character-status .main-div .mortality label {
+.fvtt-hamalron .tab.character-competences .main-div .mortality label {
min-width: 5rem;
max-width: 5rem;
}
-.fvtt-hamalron .tab.character-status .main-div .counters {
+.fvtt-hamalron .tab.character-competences .main-div .counters {
display: flex;
direction: column;
align-items: center;
gap: 4px;
margin-left: 4px;
}
-.fvtt-hamalron .tab.character-status .main-div .counters .characteristics-label {
+.fvtt-hamalron .tab.character-competences .main-div .counters .characteristics-label {
color: grey;
font-size: small;
}
-.fvtt-hamalron .tab.character-status .main-div .counters label {
+.fvtt-hamalron .tab.character-competences .main-div .counters label {
min-width: 4rem;
max-width: 4rem;
}
-.fvtt-hamalron .tab.character-status .main-div .counters .spaced-left {
+.fvtt-hamalron .tab.character-competences .main-div .counters .spaced-left {
margin-left: 0.8rem;
}
-.fvtt-hamalron .tab.character-status .main-div .counters input {
+.fvtt-hamalron .tab.character-competences .main-div .counters input {
min-width: 2.5rem;
max-width: 2.5rem;
}
-.fvtt-hamalron .tab.character-status .main-div .ailments {
+.fvtt-hamalron .tab.character-competences .main-div .ailments {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 4px;
}
-.fvtt-hamalron .tab.character-status .main-div .ailments .ailment {
+.fvtt-hamalron .tab.character-competences .main-div .ailments .ailment {
display: flex;
align-items: center;
gap: 4px;
@@ -350,144 +572,58 @@ i.fvtt-hamalron {
min-width: 8rem;
max-width: 8rem;
}
-.fvtt-hamalron .tab.character-status .main-div .ailments .ailment label {
+.fvtt-hamalron .tab.character-competences .main-div .ailments .ailment label {
min-width: 5rem;
max-width: 5rem;
}
-.fvtt-hamalron .tab.character-status .main-div .ailments .ailment .item-img {
+.fvtt-hamalron .tab.character-competences .main-div .ailments .ailment .item-img {
width: 24px;
height: 24px;
margin: 4px 0 0 0;
}
-.fvtt-hamalron .tab.character-status .main-div .perks {
- display: grid;
- grid-template-columns: repeat(1, 1fr);
- gap: 4px;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk {
- display: flex;
- align-items: center;
- gap: 4px;
- margin-left: 4px;
- min-width: 20rem;
- max-width: 20rem;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .rollable:hover,
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .rollable:focus {
- text-shadow: 0 0 8px var(--color-shadow-primary);
- cursor: pointer;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .controls {
- font-size: 0.7rem;
- min-width: 1.8rem;
- max-width: 1.8rem;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .flavor {
- min-width: 24rem;
- max-width: 24rem;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .role {
- min-width: 5rem;
- max-width: 5rem;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .level {
- min-width: 4rem;
- max-width: 4rem;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .name {
- min-width: 10rem;
- max-width: 10rem;
-}
-.fvtt-hamalron .tab.character-status .main-div .perks .perk .item-img {
- width: 24px;
- height: 24px;
- margin: 4px 0 0 0;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div {
+.fvtt-hamalron .tab.character-sortileges .main-div {
/*background-color: var(--color-light-1);*/
display: grid;
grid-template-columns: 1fr;
}
-.fvtt-hamalron .tab.character-maleficas .main-div legend a {
+.fvtt-hamalron .tab.character-sortileges .main-div legend a {
font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica {
display: flex;
align-items: center;
gap: 4px;
min-width: 20rem;
max-width: 20rem;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica .controls {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica .controls {
font-size: 0.7rem;
min-width: 1.8rem;
max-width: 1.8rem;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica .name {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica .name {
min-width: 10rem;
max-width: 10rem;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica .damage {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica .damage {
min-width: 3.2rem;
max-width: 3.2rem;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica .domain {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica .domain {
min-width: 4rem;
max-width: 4rem;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica .level {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica .level {
min-width: 2rem;
max-width: 2rem;
}
-.fvtt-hamalron .tab.character-maleficas .main-div .maleficas .malefica .item-img {
- width: 24px;
- height: 24px;
- margin: 4px 0 0 0;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals {
- display: grid;
- grid-template-columns: repeat(1, 1fr);
- gap: 4px;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual {
- display: flex;
- align-items: center;
- gap: 4px;
- min-width: 14rem;
- max-width: 14rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .controls {
- font-size: 0.7rem;
- min-width: 1.8rem;
- max-width: 1.8rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .ingredients {
- min-width: 24rem;
- max-width: 24rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .name {
- min-width: 12rem;
- max-width: 12rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .difficulty {
- min-width: 2rem;
- max-width: 2rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .threshold {
- min-width: 2rem;
- max-width: 2rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .limit {
- min-width: 2rem;
- max-width: 2rem;
-}
-.fvtt-hamalron .tab.character-maleficas .main-div .rituals .ritual .item-img {
+.fvtt-hamalron .tab.character-sortileges .main-div .sortileges .malefica .item-img {
width: 24px;
height: 24px;
margin: 4px 0 0 0;
@@ -770,63 +906,130 @@ i.fvtt-hamalron {
.fvtt-hamalron .tab.character-biography .main-div prose-mirror.active {
min-height: 150px;
}
-.fvtt-hamalron .personnage .tarot-hand-container {
- padding: 1rem;
+.fvtt-hamalron .character-content .tarot-hand-container {
+ padding: 0.3rem;
height: 100%;
display: flex;
flex-direction: column;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-header {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header {
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 1.5rem;
- padding-bottom: 0.75rem;
+ margin-bottom: 0.2rem;
+ padding-bottom: 0.2rem;
border-bottom: 2px solid var(--color-border-dark);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-header h2 {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header h2 {
margin: 0;
font-size: 1.5rem;
color: var(--color-text-dark-primary);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-header .tarot-hand-info .card-count {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info {
display: flex;
align-items: center;
- gap: 0.5rem;
- padding: 0.5rem 1rem;
+ gap: 1rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info .card-count {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ padding: 0.3rem 0.6rem;
background: rgba(102, 126, 234, 0.2);
border-radius: 0.25rem;
border: 1px solid rgba(102, 126, 234, 0.4);
font-weight: bold;
+ font-size: 0.85rem;
color: var(--color-text-light-heading);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-header .tarot-hand-info .card-count i {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info .card-count i {
color: #667eea;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
- gap: 1.5rem;
- overflow-y: auto;
- padding-right: 0.5rem;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info .card-count.over-limit {
+ background: rgba(234, 102, 102, 0.2);
+ border-color: rgba(234, 102, 102, 0.4);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info .card-count.over-limit i {
+ color: #ea6666;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info .hand-warning {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 1rem;
+ background: rgba(234, 179, 8, 0.2);
+ border-radius: 0.25rem;
+ border: 1px solid rgba(234, 179, 8, 0.4);
+ color: #eab308;
+ font-weight: bold;
+ animation: pulse 2s ease-in-out infinite;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-header .tarot-hand-info .hand-warning i {
+ color: #eab308;
+}
+@keyframes pulse {
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.7;
+ }
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.3rem;
+ overflow-y: auto;
+ padding: 0.2rem;
+ justify-content: center;
+ align-items: flex-start;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper {
perspective: 1000px;
cursor: grab;
+ flex-shrink: 0;
+ position: relative;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper:active {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper:active {
cursor: grabbing;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper.success-card .tarot-card .tarot-card-inner .tarot-card-front {
+ border: 3px solid #ffd700;
+ box-shadow: 0 0 15px rgba(255, 215, 0, 0.6), 0 4px 8px rgba(0, 0, 0, 0.3);
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper.success-card .tarot-card-controls .success-indicator {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: rgba(255, 215, 0, 0.9);
+ color: #8b6914;
+ animation: pulse-gold 2s ease-in-out infinite;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper.success-card .tarot-card-controls .success-indicator i {
+ font-size: 0.7rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper.selected .tarot-card {
+ border: 2px solid #667eea;
+ box-shadow: 0 0 20px rgba(102, 126, 234, 0.6);
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper.selected .card-actions {
+ display: flex !important;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card {
position: relative;
- width: 100%;
- height: 400px;
+ width: 110px;
+ height: 190px;
transition: transform 0.3s ease;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card:hover {
- transform: translateY(-5px);
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card:hover {
+ transform: translateY(-10px) scale(1.05);
+ z-index: 10;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner {
position: relative;
width: 100%;
height: 100%;
@@ -834,7 +1037,7 @@ i.fvtt-hamalron {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
overflow: hidden;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front {
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(20, 20, 30, 0.95) 0%, rgba(40, 40, 50, 0.95) 100%);
@@ -842,154 +1045,193 @@ i.fvtt-hamalron {
border-radius: 0.5rem;
display: flex;
flex-direction: column;
- padding: 0.75rem;
+ padding: 0.4rem;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 0.75rem;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header {
+ position: absolute;
+ top: 0.25rem;
+ right: 0.25rem;
+ z-index: 2;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-name {
- margin: 0;
- font-size: 1.1rem;
- font-weight: bold;
- color: #667eea;
- flex: 1;
- line-height: 1.3;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls {
display: flex;
gap: 0.25rem;
+ opacity: 0;
+ transition: opacity 0.2s ease;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control {
display: flex;
align-items: center;
justify-content: center;
- width: 24px;
- height: 24px;
- border-radius: 0.25rem;
- background: rgba(0, 0, 0, 0.3);
- color: var(--color-text-light-heading);
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: rgba(0, 0, 0, 0.7);
+ color: white;
transition: all 0.2s ease;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control:hover {
- background: rgba(102, 126, 234, 0.5);
- color: white;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control.delete-control:hover {
+ background: rgba(234, 102, 102, 0.9);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control i {
- font-size: 0.75rem;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control.view-control:hover {
+ background: rgba(102, 126, 234, 0.9);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-image {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-header .tarot-card-controls .card-control i {
+ font-size: 0.7rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front:hover .tarot-card-header .tarot-card-controls {
+ opacity: 1;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-image {
width: 100%;
- height: 150px;
- margin-bottom: 0.75rem;
- border-radius: 0.25rem;
+ height: 125px;
+ border-radius: 0.25rem 0.25rem 0 0;
overflow: hidden;
- border: 1px solid var(--color-border-dark);
background: rgba(0, 0, 0, 0.3);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-image img {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
- margin-bottom: 0.75rem;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-name {
+ padding: 0.5rem;
+ background: rgba(0, 0, 0, 0.3);
+ border-bottom: 1px solid var(--color-border-dark);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 0.4rem 0.5rem;
- background: rgba(0, 0, 0, 0.2);
- border-radius: 0.25rem;
- font-size: 0.875rem;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-label {
- display: flex;
- align-items: center;
- gap: 0.35rem;
- color: var(--color-text-dark-secondary);
- font-weight: 500;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-label i {
- font-size: 0.75rem;
- opacity: 0.7;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-value {
- color: var(--color-text-light-heading);
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-name h4 {
+ margin: 0;
+ font-size: 0.85rem;
font-weight: bold;
+ color: #667eea;
+ text-align: center;
+ line-height: 1.2;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-value.symbole-coupe {
- color: #3498db;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-value.symbole-epee {
- color: #d4a574;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-value.symbole-denier {
- color: #f39c12;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-row .info-value.symbole-baton {
- color: #2ecc71;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description {
- flex: 1;
- overflow-y: auto;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info {
padding: 0.5rem;
background: rgba(0, 0, 0, 0.2);
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact {
+ display: flex;
+ flex-direction: column;
+ gap: 0.4rem;
+ font-size: 0.75rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-symbole {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-weight: bold;
+ justify-content: center;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-symbole i {
+ font-size: 0.6rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-symbole.symbole-coupe {
+ color: #3498db;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-symbole.symbole-epee {
+ color: #d4a574;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-symbole.symbole-denier {
+ color: #f39c12;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-symbole.symbole-baton {
+ color: #2ecc71;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-info-compact .card-valeur {
+ text-align: center;
+ color: #ffffff;
+ font-weight: bold;
+ font-size: 1rem;
+ background: rgba(0, 0, 0, 0.4);
+ padding: 0.3rem 0.5rem;
border-radius: 0.25rem;
- border: 1px solid var(--color-border-dark);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description .description-text {
- font-size: 0.8rem;
- line-height: 1.4;
- color: var(--color-text-dark-primary);
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-actions {
+ display: none;
+ margin-top: 0.5rem;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description .description-text p {
- margin: 0 0 0.5rem 0;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-actions .discard-and-draw-button {
+ width: 100%;
+ padding: 0.5rem;
+ background: rgba(102, 126, 234, 0.3);
+ border: 1px solid rgba(102, 126, 234, 0.6);
+ border-radius: 0.25rem;
+ color: #9ab4ff;
+ font-size: 0.75rem;
+ font-weight: bold;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.3rem;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description .description-text p:last-child {
- margin-bottom: 0;
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-actions .discard-and-draw-button i {
+ font-size: 0.7rem;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description::-webkit-scrollbar {
- width: 4px;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description::-webkit-scrollbar-track {
- background: rgba(0, 0, 0, 0.2);
- border-radius: 2px;
-}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description::-webkit-scrollbar-thumb {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-actions .discard-and-draw-button:hover {
background: rgba(102, 126, 234, 0.5);
- border-radius: 2px;
+ border-color: rgba(102, 126, 234, 0.8);
+ color: #aac4ff;
+ transform: translateY(-1px);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-description::-webkit-scrollbar-thumb:hover {
- background: rgba(102, 126, 234, 0.7);
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .card-actions .discard-and-draw-button:active {
+ transform: translateY(0);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-empty {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .discard-button {
+ margin-top: 0.5rem;
+ padding: 0.4rem 0.5rem;
+ background: rgba(234, 102, 102, 0.3);
+ border: 1px solid rgba(234, 102, 102, 0.6);
+ border-radius: 0.25rem;
+ color: #ea6666;
+ font-size: 0.7rem;
+ font-weight: bold;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.3rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .discard-button i {
+ font-size: 0.65rem;
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .discard-button:hover {
+ background: rgba(234, 102, 102, 0.5);
+ border-color: rgba(234, 102, 102, 0.8);
+ color: #ff6666;
+ transform: translateY(-1px);
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-cards .tarot-card-wrapper .tarot-card .tarot-card-inner .tarot-card-front .tarot-card-info .discard-button:active {
+ transform: translateY(0);
+}
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-empty {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-empty .empty-state {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-empty .empty-state {
text-align: center;
color: var(--color-text-dark-secondary);
max-width: 400px;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-empty .empty-state i {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-empty .empty-state i {
opacity: 0.2;
margin-bottom: 1rem;
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-empty .empty-state h3 {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-empty .empty-state h3 {
margin: 0 0 0.5rem 0;
font-size: 1.25rem;
color: var(--color-text-dark-primary);
}
-.fvtt-hamalron .personnage .tarot-hand-container .tarot-hand-empty .empty-state p {
+.fvtt-hamalron .character-content .tarot-hand-container .tarot-hand-empty .empty-state p {
margin: 0;
font-style: italic;
opacity: 0.8;
@@ -1038,8 +1280,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .enemy-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -1545,8 +1787,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .weapon-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -1639,8 +1881,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .armor-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -1729,8 +1971,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .perk-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -1823,8 +2065,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .equipment-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -1932,8 +2174,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .ritual-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -2026,8 +2268,8 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1);
}
.fvtt-hamalron .tarot-content legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
@@ -2093,188 +2335,6 @@ i.fvtt-hamalron {
.fvtt-hamalron .tarot-content label {
flex: 10%;
}
-.fvtt-hamalron .tarot-deck-manager .tarot-deck-manager-content {
- padding: 1rem;
- display: flex;
- flex-direction: column;
- gap: 1.5rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-header h2 {
- margin: 0 0 1rem 0;
- font-size: 1.5rem;
- color: var(--color-text-dark-primary);
- text-align: center;
- border-bottom: 2px solid var(--color-border-dark);
- padding-bottom: 0.5rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-header .deck-stats {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 1rem;
- margin-top: 1rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-header .deck-stats .stat-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.25rem;
- padding: 0.75rem;
- background: rgba(0, 0, 0, 0.2);
- border-radius: 0.25rem;
- border: 1px solid var(--color-border-dark);
-}
-.fvtt-hamalron .tarot-deck-manager .deck-header .deck-stats .stat-item i {
- font-size: 1.5rem;
- color: var(--color-text-light-heading);
- margin-bottom: 0.25rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-header .deck-stats .stat-item .stat-label {
- font-size: 0.75rem;
- color: var(--color-text-dark-secondary);
- text-transform: uppercase;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-header .deck-stats .stat-item .stat-value {
- font-size: 1.25rem;
- font-weight: bold;
- color: var(--color-text-light-heading);
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions {
- display: flex;
- flex-direction: column;
- gap: 1rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .action-button {
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 0.5rem;
- padding: 0.75rem 1rem;
- font-size: 1rem;
- font-weight: bold;
- border: none;
- border-radius: 0.25rem;
- cursor: pointer;
- transition: all 0.2s ease;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .action-button i {
- font-size: 1.25rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .action-button:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .reset-button {
- background: var(--color-border-dark);
- color: var(--color-text-light-heading);
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .reset-button:hover:not(:disabled) {
- background: var(--color-border-dark-tertiary);
- transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .draw-actions {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 0.5rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .draw-actions .draw-button {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-actions .draw-actions .draw-button:hover:not(:disabled) {
- background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
- transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(102, 126, 234, 0.4);
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws h3 {
- margin: 0 0 1rem 0;
- font-size: 1.25rem;
- color: var(--color-text-dark-primary);
- padding-bottom: 0.5rem;
- border-bottom: 1px solid var(--color-border-dark);
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list {
- display: flex;
- flex-direction: column;
- gap: 0.75rem;
- max-height: 300px;
- overflow-y: auto;
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card {
- display: flex;
- gap: 1rem;
- padding: 0.75rem;
- background: rgba(0, 0, 0, 0.2);
- border-radius: 0.25rem;
- border: 1px solid var(--color-border-dark);
- transition: all 0.2s ease;
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card:hover {
- background: rgba(0, 0, 0, 0.3);
- border-color: var(--color-border-dark-tertiary);
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-image {
- width: 60px;
- height: 60px;
- object-fit: cover;
- border-radius: 0.25rem;
- border: 1px solid var(--color-border-dark);
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: center;
- gap: 0.25rem;
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-name {
- margin: 0;
- font-size: 1rem;
- color: var(--color-text-light-heading);
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-details {
- display: flex;
- gap: 1rem;
- font-size: 0.875rem;
-}
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-details .card-symbole,
-.fvtt-hamalron .tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-details .card-valeur {
- color: var(--color-text-dark-secondary);
-}
-.fvtt-hamalron .tarot-deck-manager .no-draws {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 1rem;
- padding: 3rem 1rem;
- color: var(--color-text-dark-secondary);
- text-align: center;
-}
-.fvtt-hamalron .tarot-deck-manager .no-draws i {
- opacity: 0.3;
-}
-.fvtt-hamalron .tarot-deck-manager .no-draws p {
- margin: 0;
- font-style: italic;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-empty-warning {
- display: flex;
- align-items: center;
- gap: 0.75rem;
- padding: 1rem;
- background: rgba(255, 165, 0, 0.1);
- border: 1px solid rgba(255, 165, 0, 0.3);
- border-radius: 0.25rem;
- color: #ffa500;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-empty-warning i {
- font-size: 1.5rem;
-}
-.fvtt-hamalron .tarot-deck-manager .deck-empty-warning p {
- margin: 0;
- flex: 1;
-}
.fvtt-hamalron.ask-roll {
display: flex;
flex-direction: column;
@@ -2283,13 +2343,346 @@ i.fvtt-hamalron {
font-family: var(--font-secondary);
font-size: calc(var(--font-size-standard) * 1.1);
}
-.fvtt-hamalron .hamalron-tarot-draw {
+.fvtt-hamalron.competence-roll {
+ background: #e8e8e8;
+ border: 2px solid #999;
+ border-radius: 0.5rem;
+ overflow: hidden;
+}
+.fvtt-hamalron.competence-roll .competence-roll-header {
+ background: rgba(255, 255, 255, 0.5);
+ padding: 0.5rem;
+ border-bottom: 2px solid #999;
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact .actor-avatar {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid #667eea;
+ object-fit: cover;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact .actor-details {
+ flex: 1;
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact .actor-details .competence-name {
+ margin: 0 0 0.25rem 0;
+ font-size: 1rem;
+ color: #667eea;
+ font-weight: bold;
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact .actor-details .competence-meta {
+ display: flex;
+ gap: 0.75rem;
+ font-size: 0.75rem;
+ color: var(--color-text-dark-secondary);
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact .actor-details .competence-meta .meta-item {
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-header .actor-info-compact .actor-details .competence-meta .meta-item i {
+ color: #667eea;
+ font-size: 0.75rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body {
padding: 0.5rem;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-header {
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section {
+ background: rgba(102, 126, 234, 0.1);
+ border: 1px solid rgba(102, 126, 234, 0.4);
+ border-radius: 0.35rem;
+ padding: 0.4rem;
+ margin-bottom: 0.5rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-label {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.75rem;
+ font-weight: bold;
+ color: #4a5fc1;
+ margin-bottom: 0.35rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-label i {
+ font-size: 0.75rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-thumbnail {
+ width: 40px;
+ height: 40px;
+ border-radius: 0.25rem;
+ border: 1px solid rgba(102, 126, 234, 0.5);
+ object-fit: cover;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-name {
+ font-weight: bold;
+ color: var(--color-text-dark-primary);
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.75rem;
+ font-style: italic;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match.match-success {
+ color: #2ecc71;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match.match-success i {
+ color: #2ecc71;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match.match-partial {
+ color: #f39c12;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match.match-partial i {
+ color: #f39c12;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match.match-atout {
+ color: #9b59b6;
+ font-weight: bold;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match.match-atout i {
+ color: #9b59b6;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .card-match i {
+ font-size: 0.7rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .valet-special-rule,
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .cavalier-special-rule,
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .reine-special-rule,
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .roi-special-rule {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.75rem;
+ font-weight: bold;
+ padding: 0.3rem 0.4rem;
+ border-radius: 0.25rem;
+ background: rgba(255, 193, 7, 0.15);
+ border-left: 3px solid #ffc107;
+ color: #856404;
+ margin-top: 0.2rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .valet-special-rule i,
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .cavalier-special-rule i,
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .reine-special-rule i,
+.fvtt-hamalron.competence-roll .competence-roll-body .card-used-section .card-used-content .card-info .roi-special-rule i {
+ font-size: 0.8rem;
+ color: #ffc107;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section {
+ background: rgba(0, 0, 0, 0.05);
+ border-radius: 0.35rem;
+ padding: 0.4rem;
+ margin-bottom: 0.5rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.2rem 0;
+ font-size: 0.8rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-row .calc-label {
+ color: var(--color-text-dark-secondary);
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-row .calc-value {
+ font-weight: bold;
+ font-size: 0.9rem;
+ color: var(--color-text-dark-primary);
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-row .calc-value.calc-bonus {
+ color: #2ecc71;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-row .calc-value.calc-total {
+ font-size: 1.1rem;
+ color: #667eea;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-row.total-row {
+ padding-top: 0.3rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .calculation-section .calculation-divider {
+ height: 1px;
+ background: var(--color-border-dark);
+ margin: 0.4rem 0;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .difficulty-section .difficulty-info {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.4rem;
+ background: rgba(0, 0, 0, 0.05);
+ border-radius: 0.35rem;
+ font-size: 0.8rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .difficulty-section .difficulty-info i {
+ color: #f39c12;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .difficulty-section .difficulty-info .difficulty-label {
+ color: var(--color-text-dark-primary);
+ font-weight: 500;
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .difficulty-section .difficulty-info .difficulty-target {
+ margin-left: auto;
+ color: var(--color-text-dark-secondary);
+}
+.fvtt-hamalron.competence-roll .competence-roll-body .difficulty-section .difficulty-info .difficulty-target strong {
+ color: var(--color-text-dark-primary);
+ font-size: 1rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ padding: 0.5rem;
+ font-size: 1.1rem;
+ font-weight: bold;
+ border-top: 2px solid #999;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer .automatic-success-banner {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ width: 100%;
+ padding: 0.5rem;
+ background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
+ color: #8b6914;
+ font-size: 0.95rem;
+ font-weight: bold;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ border-radius: 0.25rem;
+ box-shadow: 0 2px 8px rgba(255, 215, 0, 0.4);
+ animation: pulse-banner 2s ease-in-out infinite;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer .automatic-success-banner i {
+ color: #8b6914;
+ text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.result-success {
+ background: rgba(46, 204, 113, 0.2);
+ color: #2ecc71;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.result-success .result-icon i {
+ color: #2ecc71;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.result-failure {
+ background: rgba(234, 102, 102, 0.2);
+ color: #ea6666;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.result-failure .result-icon i {
+ color: #ea6666;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons {
+ background: rgba(102, 126, 234, 0.1);
+ padding: 0.75rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .special-rules-section {
+ background: rgba(255, 193, 7, 0.15);
+ border: 2px solid #ffc107;
+ border-radius: 0.35rem;
+ padding: 0.5rem;
+ margin-bottom: 0.75rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .special-rules-section .special-rule-item {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.3rem 0;
+ font-weight: bold;
+ color: #856404;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .special-rules-section .special-rule-item:not(:last-child) {
+ border-bottom: 1px solid rgba(255, 193, 7, 0.3);
+ margin-bottom: 0.3rem;
+ padding-bottom: 0.4rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .special-rules-section .special-rule-item i {
+ font-size: 0.9rem;
+ color: #ffc107;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .special-rules-section .special-rule-item strong {
+ color: #6c5400;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons {
+ display: flex;
+ gap: 0.75rem;
+ width: 100%;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button {
+ flex: 1;
+ padding: 0.5rem 1rem;
+ border: 2px solid #667eea;
+ border-radius: 0.35rem;
+ background: white;
+ color: #667eea;
+ font-weight: bold;
+ font-size: 0.9rem;
+ cursor: pointer;
+ transition: all 0.2s;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button i {
+ font-size: 0.85rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button:hover {
+ background: #667eea;
+ color: white;
+ transform: translateY(-1px);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button.sous-tension-btn {
+ border-color: #f39c12;
+ color: #f39c12;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button.sous-tension-btn:hover {
+ background: #f39c12;
+ color: white;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button.oppose-btn {
+ border-color: #e74c3c;
+ color: #e74c3c;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer.gm-only-buttons .gm-buttons button.oppose-btn:hover {
+ background: #e74c3c;
+ color: white;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer .result-icon {
+ font-size: 1.2rem;
+}
+.fvtt-hamalron.competence-roll .competence-roll-footer .result-text {
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+.fvtt-hamalron.hamalron-tarot-draw {
+ padding: 0.5rem;
+}
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-header {
margin-bottom: 1rem;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-header .tarot-draw-title {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-header .tarot-draw-title {
display: flex;
align-items: center;
gap: 0.5rem;
@@ -2299,17 +2692,17 @@ i.fvtt-hamalron {
font-size: 1.25rem;
color: var(--color-text-dark-primary);
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-header .tarot-draw-title i {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-header .tarot-draw-title i {
color: #667eea;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content {
display: flex;
gap: 1rem;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-image {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-image {
flex-shrink: 0;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-image img {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-image img {
width: 150px;
height: 150px;
object-fit: cover;
@@ -2317,37 +2710,241 @@ i.fvtt-hamalron {
border: 2px solid var(--color-border-dark);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-detail-row {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-detail-row {
display: flex;
gap: 0.5rem;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-detail-row .detail-label {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-detail-row .detail-label {
font-weight: bold;
color: var(--color-text-dark-secondary);
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-detail-row .detail-value {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-detail-row .detail-value {
color: var(--color-text-dark-primary);
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-description {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-description {
margin-top: 0.5rem;
padding-top: 0.5rem;
border-top: 1px solid var(--color-border-dark);
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-description .description-label {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-description .description-label {
font-weight: bold;
color: var(--color-text-dark-secondary);
margin-bottom: 0.25rem;
}
-.fvtt-hamalron .hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-description .description-content {
+.fvtt-hamalron.hamalron-tarot-draw .tarot-draw-content .tarot-card-details .tarot-description .description-content {
color: var(--color-text-dark-primary);
font-style: italic;
}
+.fvtt-hamalron.tarot-draw-chat {
+ background: #e8e8e8;
+ border: 2px solid #999;
+ border-radius: 0.5rem;
+ overflow: hidden;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header {
+ background: rgba(255, 255, 255, 0.5);
+ padding: 0.5rem;
+ border-bottom: 2px solid #999;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact .card-thumbnail {
+ width: 60px;
+ height: 60px;
+ border-radius: 0.25rem;
+ object-fit: cover;
+ border: 2px solid #999;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact .card-details {
+ flex: 1;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact .card-details .card-name {
+ margin: 0 0 0.25rem 0;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #333;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact .card-details .card-meta {
+ display: flex;
+ gap: 0.75rem;
+ flex-wrap: wrap;
+ font-size: 0.75rem;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact .card-details .card-meta .meta-item {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ color: #666;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-header .draw-info-compact .card-details .card-meta .meta-item i {
+ color: #999;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-body {
+ padding: 0.5rem;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-body .description-section .description-label {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ font-size: 0.8rem;
+ font-weight: bold;
+ color: #666;
+ margin-bottom: 0.4rem;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-body .description-section .description-label i {
+ color: #999;
+}
+.fvtt-hamalron.tarot-draw-chat .tarot-draw-body .description-section .description-content {
+ font-size: 0.85rem;
+ color: #555;
+ font-style: italic;
+ line-height: 1.4;
+ padding: 0.4rem;
+ background: rgba(255, 255, 255, 0.3);
+ border-radius: 0.25rem;
+ border-left: 3px solid #999;
+}
+.fvtt-hamalron.tarot-tension-chat {
+ background: #e8e8e8;
+ border: 2px solid #999;
+ border-radius: 0.5rem;
+ overflow: hidden;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header {
+ background: rgba(255, 165, 0, 0.2);
+ padding: 0.5rem;
+ border-bottom: 2px solid #f39c12;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact .card-thumbnail {
+ width: 60px;
+ height: 60px;
+ border-radius: 0.25rem;
+ object-fit: cover;
+ border: 2px solid #f39c12;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact .card-details {
+ flex: 1;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact .card-details .card-name {
+ margin: 0 0 0.25rem 0;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #333;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact .card-details .card-meta {
+ display: flex;
+ gap: 0.75rem;
+ flex-wrap: wrap;
+ font-size: 0.75rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact .card-details .card-meta .meta-item {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ color: #666;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-header .tension-info-compact .card-details .card-meta .meta-item i {
+ color: #f39c12;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body {
+ padding: 0.5rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .difficulty-section {
+ margin-bottom: 0.75rem;
+ padding: 0.5rem;
+ background: rgba(243, 156, 18, 0.1);
+ border-left: 3px solid #f39c12;
+ border-radius: 0.25rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .difficulty-section .difficulty-label {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ font-size: 0.75rem;
+ font-weight: bold;
+ color: #666;
+ margin-bottom: 0.25rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .difficulty-section .difficulty-label i {
+ color: #f39c12;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .difficulty-section .difficulty-value {
+ font-size: 0.9rem;
+ font-weight: bold;
+ color: #333;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.3rem 0.5rem;
+ margin-bottom: 0.25rem;
+ background: rgba(255, 255, 255, 0.3);
+ border-radius: 0.25rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-row .calc-label {
+ font-size: 0.8rem;
+ color: #666;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-row .calc-value {
+ font-size: 0.85rem;
+ font-weight: bold;
+ color: #333;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-row .calc-value.positive {
+ color: #27ae60;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-row .calc-value.negative {
+ color: #e74c3c;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-total {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.5rem;
+ margin-top: 0.5rem;
+ background: rgba(243, 156, 18, 0.15);
+ border: 2px solid #f39c12;
+ border-radius: 0.25rem;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-total .total-label {
+ font-size: 0.85rem;
+ font-weight: bold;
+ color: #666;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+.fvtt-hamalron.tarot-tension-chat .tarot-tension-body .calculation-section .calculation-total .total-value {
+ font-size: 1.25rem;
+ font-weight: bold;
+ color: #f39c12;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+}
+@keyframes pulse-banner {
+ 0%,
+ 100% {
+ box-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
+ }
+ 50% {
+ box-shadow: 0 0 20px rgba(255, 215, 0, 0.8);
+ }
+}
.application.dialog.fvtt-hamalron {
color: var(--color-dark-1);
background-color: var(--color-light-1);
@@ -2365,9 +2962,186 @@ i.fvtt-hamalron {
color: var(--color-dark-2);
}
.fvtt-hamalron-roll-dialog fieldset {
- padding: 10px;
+ padding: 6px;
background-color: var(--color-light-1);
}
+.fvtt-hamalron-roll-dialog .dialog-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-bottom: 0;
+}
+.fvtt-hamalron-roll-dialog .dialog-info .actor-info {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.25rem 0.5rem;
+ background-color: rgba(0, 0, 0, 0.05);
+ border-radius: 0.25rem;
+}
+.fvtt-hamalron-roll-dialog .dialog-info .actor-info .actor-portrait {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid var(--color-dark-6);
+ object-fit: cover;
+}
+.fvtt-hamalron-roll-dialog .dialog-info .actor-info .actor-name {
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 0.9);
+ font-weight: bold;
+ color: var(--color-dark-1);
+}
+.fvtt-hamalron-roll-dialog .dialog-info .competence-info {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.25rem 0.5rem;
+}
+.fvtt-hamalron-roll-dialog .dialog-info .competence-info h3 {
+ margin: 0;
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1);
+ color: var(--title-color);
+ white-space: nowrap;
+}
+.fvtt-hamalron-roll-dialog .dialog-info .competence-info .competence-details {
+ display: flex;
+ gap: 0.5rem;
+ font-size: calc(var(--font-size-standard) * 0.85);
+}
+.fvtt-hamalron-roll-dialog .dialog-info .competence-info .competence-details .competence-symbole,
+.fvtt-hamalron-roll-dialog .dialog-info .competence-info .competence-details .competence-niveau {
+ padding: 0.25rem 0.5rem;
+ background-color: rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
+ font-weight: 500;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
+ gap: 0.5rem;
+ padding: 0.25rem;
+ min-height: 90px;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.15rem;
+ padding: 0.25rem;
+ border: 2px solid transparent;
+ border-radius: 0.35rem;
+ background-color: rgba(0, 0, 0, 0.05);
+ cursor: pointer;
+ transition: all 0.2s ease;
+ position: relative;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select:hover {
+ background-color: rgba(0, 0, 0, 0.1);
+ border-color: var(--color-dark-5);
+ transform: translateY(-2px) scale(1.3);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
+ z-index: 10;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select.selected {
+ background-color: rgba(100, 150, 255, 0.2);
+ border-color: var(--color-success);
+ box-shadow: 0 0 10px rgba(100, 150, 255, 0.5);
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select.success-card {
+ border: 3px solid #ffd700;
+ background: linear-gradient(135deg, rgba(255, 215, 0, 0.1) 0%, rgba(255, 223, 0, 0.2) 100%);
+ box-shadow: 0 0 15px rgba(255, 215, 0, 0.4);
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select.success-card:hover {
+ border-color: #ffed4e;
+ box-shadow: 0 6px 20px rgba(255, 215, 0, 0.6);
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select.success-card.selected {
+ border-color: #ffd700;
+ box-shadow: 0 0 20px rgba(255, 215, 0, 0.8);
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select .success-indicator {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ color: #ffd700;
+ font-size: 1rem;
+ text-shadow: 0 0 5px rgba(255, 215, 0, 0.8);
+ animation: pulse-gold 2s ease-in-out infinite;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select img {
+ width: 50px;
+ height: auto;
+ border-radius: 0.25rem;
+ border: 1px solid var(--color-dark-6);
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select .card-name {
+ font-size: calc(var(--font-size-standard) * 0.75);
+ text-align: center;
+ line-height: 1.1;
+ max-width: 70px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand .tarot-card-select .card-values {
+ font-size: calc(var(--font-size-standard) * 0.7);
+ text-align: center;
+ color: var(--color-dark-3);
+ font-weight: bold;
+ margin-top: 0.1rem;
+}
+.fvtt-hamalron-roll-dialog .tarot-hand p {
+ grid-column: 1 / -1;
+ text-align: center;
+ color: var(--color-dark-5);
+ font-style: italic;
+ margin: 1rem 0;
+}
+.fvtt-hamalron-roll-dialog .dialog-result .total-display {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 0.1rem;
+ padding: 0.1rem;
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
+ font-weight: bold;
+}
+.fvtt-hamalron-roll-dialog .dialog-result .total-display #competence-modifier {
+ color: var(--color-dark-1);
+}
+.fvtt-hamalron-roll-dialog .dialog-result .total-display #card-value-display {
+ color: var(--color-success);
+}
+.fvtt-hamalron-roll-dialog .dialog-result .total-display #total-value {
+ padding: 0.1rem 0.2rem;
+ background-color: rgba(0, 0, 0, 0.1);
+ border-radius: 0.35rem;
+ color: var(--title-color);
+ min-width: 2.1rem;
+ text-align: center;
+}
+.fvtt-hamalron-roll-dialog .dialog-result .difficulty-info {
+ text-align: center;
+ font-size: calc(var(--font-size-standard) * 0.9);
+ color: var(--color-dark-2);
+ margin-top: 0.1rem;
+ padding: 0.1rem 0;
+}
+.fvtt-hamalron-roll-dialog .dialog-result .difficulty-info #target-score {
+ font-weight: bold;
+ color: var(--color-dark-1);
+}
+.fvtt-hamalron-roll-dialog .difficulty-select {
+ width: 100%;
+ text-align: center;
+ padding: 0.25rem;
+}
.dialog-modifier {
display: flex;
justify-content: center;
@@ -2549,3 +3323,241 @@ i.fvtt-hamalron {
font-size: calc(var(--font-size-standard) * 1.2);
text-shadow: 0 0 10px var(--color-shadow-primary);
}
+@keyframes pulse-gold {
+ 0%,
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.8;
+ }
+}
+.tarot-deck-manager .tarot-deck-manager-content {
+ padding: 1.5rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
+ min-height: 100%;
+}
+.tarot-deck-manager .deck-header h2 {
+ margin: 0 0 0.75rem 0;
+ font-size: 1.25rem;
+ color: #667eea;
+ text-align: center;
+ border-bottom: 2px solid #667eea;
+ padding-bottom: 0.5rem;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+}
+.tarot-deck-manager .deck-header .deck-stats {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 0.5rem;
+ margin-top: 0.75rem;
+}
+.tarot-deck-manager .deck-header .deck-stats .stat-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.25rem;
+ padding: 0.5rem;
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.15) 100%);
+ border-radius: 0.5rem;
+ border: 2px solid rgba(102, 126, 234, 0.3);
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+.tarot-deck-manager .deck-header .deck-stats .stat-item:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+ border-color: rgba(102, 126, 234, 0.5);
+}
+.tarot-deck-manager .deck-header .deck-stats .stat-item i {
+ font-size: 1.25rem;
+ color: #667eea;
+ margin-bottom: 0.15rem;
+}
+.tarot-deck-manager .deck-header .deck-stats .stat-item .stat-label {
+ font-size: 0.7rem;
+ color: var(--color-text-dark-secondary);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ text-align: center;
+}
+.tarot-deck-manager .deck-header .deck-stats .stat-item .stat-value {
+ font-size: 1.25rem;
+ font-weight: bold;
+ color: #667eea;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+}
+.tarot-deck-manager .deck-actions {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.5rem;
+}
+.tarot-deck-manager .deck-actions .action-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ padding: 0.6rem 0.75rem;
+ font-size: 0.85rem;
+ font-weight: bold;
+ border: none;
+ border-radius: 0.5rem;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+.tarot-deck-manager .deck-actions .action-button i {
+ font-size: 1.1rem;
+}
+.tarot-deck-manager .deck-actions .action-button:hover:not(:disabled) {
+ transform: translateY(-3px);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
+}
+.tarot-deck-manager .deck-actions .action-button:active:not(:disabled) {
+ transform: translateY(-1px);
+}
+.tarot-deck-manager .deck-actions .action-button:disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+ filter: grayscale(50%);
+}
+.tarot-deck-manager .deck-actions .reset-button {
+ background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
+ color: white;
+}
+.tarot-deck-manager .deck-actions .reset-button:hover:not(:disabled) {
+ background: linear-gradient(135deg, #c0392b 0%, #e74c3c 100%);
+}
+.tarot-deck-manager .deck-actions .collect-hands-button {
+ background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
+ color: white;
+}
+.tarot-deck-manager .deck-actions .collect-hands-button:hover:not(:disabled) {
+ background: linear-gradient(135deg, #2980b9 0%, #3498db 100%);
+}
+.tarot-deck-manager .deck-actions .distribute-cards-button {
+ background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
+ color: white;
+}
+.tarot-deck-manager .deck-actions .distribute-cards-button:hover:not(:disabled) {
+ background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
+}
+.tarot-deck-manager .deck-actions .shuffle-discard-button {
+ background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
+ color: white;
+}
+.tarot-deck-manager .deck-actions .shuffle-discard-button:hover:not(:disabled) {
+ background: linear-gradient(135deg, #e67e22 0%, #f39c12 100%);
+}
+.tarot-deck-manager .deck-actions .draw-button {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+}
+.tarot-deck-manager .deck-actions .draw-button:hover:not(:disabled) {
+ background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
+}
+.tarot-deck-manager .deck-actions .draw-tension-button {
+ background: linear-gradient(135deg, #f39c12 0%, #d35400 100%);
+ color: white;
+}
+.tarot-deck-manager .deck-actions .draw-tension-button:hover:not(:disabled) {
+ background: linear-gradient(135deg, #d35400 0%, #f39c12 100%);
+}
+.tarot-deck-manager .recent-draws h3 {
+ margin: 0 0 1rem 0;
+ font-size: 1.25rem;
+ color: var(--color-text-dark-primary);
+ padding-bottom: 0.5rem;
+ border-bottom: 1px solid var(--color-border-dark);
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ max-height: 300px;
+ overflow-y: auto;
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card {
+ display: flex;
+ gap: 1rem;
+ padding: 0.75rem;
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 0.25rem;
+ border: 1px solid var(--color-border-dark);
+ transition: all 0.2s ease;
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card:hover {
+ background: rgba(0, 0, 0, 0.3);
+ border-color: var(--color-border-dark-tertiary);
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-image {
+ width: 60px;
+ height: 60px;
+ object-fit: cover;
+ border-radius: 0.25rem;
+ border: 1px solid var(--color-border-dark);
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 0.25rem;
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-name {
+ margin: 0;
+ font-size: 1rem;
+ color: var(--color-text-light-heading);
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-details {
+ display: flex;
+ gap: 1rem;
+ font-size: 0.875rem;
+}
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-details .card-symbole,
+.tarot-deck-manager .recent-draws .drawn-cards-list .drawn-card .card-info .card-details .card-valeur {
+ color: var(--color-text-dark-secondary);
+}
+.tarot-deck-manager .no-draws {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 1rem;
+ padding: 3rem 1rem;
+ color: var(--color-text-dark-secondary);
+ text-align: center;
+}
+.tarot-deck-manager .no-draws i {
+ opacity: 0.3;
+}
+.tarot-deck-manager .no-draws p {
+ margin: 0;
+ font-style: italic;
+}
+.tarot-deck-manager .deck-empty-warning {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 1rem;
+ background: rgba(255, 165, 0, 0.1);
+ border: 1px solid rgba(255, 165, 0, 0.3);
+ border-radius: 0.25rem;
+ color: #ffa500;
+}
+.tarot-deck-manager .deck-empty-warning i {
+ font-size: 1.5rem;
+}
+.tarot-deck-manager .deck-empty-warning p {
+ margin: 0;
+ flex: 1;
+}
diff --git a/fvtt-hamalron.mjs b/fvtt-hamalron.mjs
index 335e378..bf3bf6c 100644
--- a/fvtt-hamalron.mjs
+++ b/fvtt-hamalron.mjs
@@ -87,6 +87,15 @@ Hooks.once("init", function () {
default: "",
})
+ game.settings.register("fvtt-hamalron", "tarotDeckState", {
+ name: "Tarot Deck State",
+ hint: "Stores the current state of the tarot deck and discard pile",
+ scope: "world",
+ config: false,
+ type: Object,
+ default: { deck: [], discard: [] },
+ })
+
// Activate socket handler
game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent)
diff --git a/lang/fr.json b/lang/fr.json
index c76de50..1fd6f29 100644
--- a/lang/fr.json
+++ b/lang/fr.json
@@ -1,4 +1,22 @@
{
+ "TYPES": {
+ "Actor": {
+ "personnage": "Personnage",
+ "PNJ": "PNJ"
+ },
+ "Item": {
+ "arme": "Arme",
+ "armure": "Armure",
+ "competence": "Compétence",
+ "equipement": "Équipement",
+ "faction": "Faction",
+ "langue": "Langue",
+ "peuple": "Peuple",
+ "region": "Région",
+ "sortilege": "Sortilège",
+ "tarot": "Tarot"
+ }
+ },
"HAMALRON": {
"Arme": {
"FIELDS": {
@@ -197,6 +215,12 @@
},
"type": {
"label": "Type"
+ },
+ "faction": {
+ "label": "Faction"
+ },
+ "peuple": {
+ "label": "Peuple"
}
}
},
@@ -337,7 +361,10 @@
}
},
"Delete": "Supprimer",
- "Dialog": {},
+ "Dialog": {
+ "discardCardTitle": "Défausser la carte",
+ "discardCardContent": "Voulez-vous vraiment défausser {cardName} et tirer une nouvelle carte ?"
+ },
"Edit": "Éditer",
"Enemy": {
"FIELDS": {
@@ -396,18 +423,23 @@
"appearance": "Apparence",
"armor": "Armure",
"armors": "Armures",
+ "automaticSuccess": "Réussite Automatique",
"backstory": "Histoire",
"biodata": "Données biologiques",
"biography": "Biographie",
"bonds": "Liens",
"bonus": "Déclencheur XP droit",
"capacity": "Capacité",
+ "cardBonus": "Bonus de carte",
+ "cardUsed": "Carte utilisée",
"cards": "Cartes",
"cargo": "Cargaison",
"cartesSucces": "Cartes Succès",
"character": "Personnage",
"characteristics": "Caractéristiques",
"combat": "Combat",
+ "competence": "Compétence",
+ "competenceModifier": "Modificateur de compétence",
"competences": "Compétences",
"creature": "Créature",
"current": "Act.",
@@ -416,12 +448,14 @@
"damages": "Dégâts",
"deals": "Accords",
"description": "Description",
+ "differentSymbol": "Symbole différent",
"difficulty": "Difficulté",
"dislikes": "N'aime pas",
"dragTarotHere": "Glissez-déposez des cartes de tarot ici depuis le répertoire des objets",
"equipment": "Équipement",
"equipments": "Équipements",
"experience": "Expérience",
+ "faction": "Faction",
"failure": "Échec",
"fears": "Peurs",
"fiendishFailure": "Échec diabolique",
@@ -436,8 +470,9 @@
"knowledge": "Connaissance",
"languages": "Langues",
"likes": "Aime",
- "maleficas": "Maléfices",
+ "sortileges": "Sortilèges",
"malus": "Malus",
+ "matchingSymbol": "Symbole correspondant",
"max": "Max",
"maximum": "Maximum",
"mind": "Esprit",
@@ -462,10 +497,17 @@
"newTarot": "Nouveau tarot",
"newTrait": "Nouveau trait",
"newWeapon": "Nouvelle arme",
+ "niveau": "Niveau",
"noTarotCards": "Aucune carte de tarot",
+ "mustDiscardCard": "Vous devez éliminer une carte",
+ "discard": "Défausser",
+ "discardCard": "Défausser cette carte",
+ "discardAndDraw": "Défausser et tirer",
+ "drawCard": "Tirer une carte",
"notes": "Notes",
"penalty": "Déclencheur XP inversé",
"perks": "Avantages",
+ "peuple": "Peuple",
"physical": "Physique",
"positiveEffect": "Effet positif",
"progression": "Progression",
@@ -476,6 +518,7 @@
"rollView": "Vue de jet",
"satanicSuccess": "Succès satanique",
"scars": "Cicatrices",
+ "selectTarotCard": "Sélectionnez une carte de tarot",
"skill": "Compétence",
"skillRoll": "Jet de compétence",
"skills": "Compétences",
@@ -490,17 +533,24 @@
"stats": "Stats",
"status": "Statut",
"stealth": "Furtivité",
+ "sousTension": "Sous tension",
+ "oppose": "Opposé",
"success": "Succès",
+ "symbole": "Symbole",
"talents": "Talents",
"targetScore": "Score cible",
"tarot": "Tarot",
"tarotHand": "Main de tarot",
"technology": "Technologie",
+ "tensionModifier": "Modificateur sous tension",
+ "titleCompetence": "Jet de compétence",
"titleSkill": "Jet de compétence",
"titleStat": "Boîte de dialogue de jet de caractéristique",
"titleWeapon": "Jet d'arme",
"total": "Total",
"totalScore": "Score total",
+ "totalValue": "Valeur totale",
+ "cardValue": "Valeur de la carte",
"traits": "Traits",
"trauma": "Traumatisme",
"unknown": "Inconnu",
@@ -510,49 +560,19 @@
"vices": "Vices",
"weapons": "Armes"
},
- "Malefica": {
- "FIELDS": {
- "choiceMaintainDuration": {
- "label": "Passif/Durée"
- },
- "damage": {
- "label": "Dégâts"
- },
- "damageType": {
- "label": "Type de dégâts"
- },
- "description": {
- "label": "Description"
- },
- "domain": {
- "label": "Domaine"
- },
- "duration": {
- "label": "Durée"
- },
- "hasDamage": {
- "label": "A des dégâts"
- },
- "level": {
- "label": "Niveau"
- },
- "maintain": {
- "label": "Passif"
- },
- "range": {
- "label": "Portée"
- },
- "target": {
- "label": "Cible"
- },
- "time": {
- "label": "Temps"
- }
- }
- },
"Notifications": {
"speciesTraitDeleted": "Trait d'espèce précédent supprimé : ",
- "tarotDeleted": "Carte de Tarot précédente supprimée : "
+ "tarotDeleted": "Carte de Tarot précédente supprimée : ",
+ "tarotHandFull": "Vous avez déjà 8 cartes dans votre main. Vous devez en éliminer une avant d'en ajouter une autre.",
+ "cardDiscarded": "Carte défaussée : ",
+ "cardUsed": "Carte utilisée : ",
+ "newCardDrawn": "Nouvelle carte tirée : ",
+ "tarotCardAlreadyExists": "Cette carte existe déjà dans votre main : ",
+ "cannotDrawCard": "Vous avez déjà 7 cartes ou plus dans votre main.",
+ "deckManagerNotAvailable": "Le gestionnaire de deck n'est pas disponible.",
+ "deckEmpty": "Le deck est vide. Impossible de tirer une carte.",
+ "cardDiscardedAndDrawn": "Carte défaussée et nouvelle carte tirée : ",
+ "cardDiscardedNoNew": "Carte défaussée. Le deck est vide, aucune nouvelle carte n'a pu être tirée."
},
"Sortilege": {
"FIELDS": {
@@ -585,26 +605,9 @@
"Roll": {
"cancel": "Annuler",
"roll": "Lancer",
+ "rollCompetence": "Jet de compétence",
"skill": "Compétence"
},
- "TYPES": {
- "Actor": {
- "personnage": "Personnage",
- "PNJ": "PNJ"
- },
- "Item": {
- "arme": "Arme",
- "armure": "Armure",
- "competence": "Compétence",
- "equipement": "Équipement",
- "faction": "Faction",
- "langue": "Langue",
- "peuple": "Peuple",
- "region": "Région",
- "sortilege": "Sortilège",
- "tarot": "Tarot"
- }
- },
"Tarot": {
"FIELDS": {
"bonus": {
@@ -650,26 +653,55 @@
"valet": "Valet",
"cavalier": "Cavalier",
"reine": "Reine",
- "roi": "Roi"
+ "roi": "Roi",
+ "lemat": "Le Mat",
+ "11": "Le Bateleur",
+ "12": "La Papesse",
+ "13": "L'Impératrice",
+ "14": "L'Empereur",
+ "15": "Le Pape",
+ "16": "L'Amoureux",
+ "17": "Le Chariot",
+ "18": "La Justice",
+ "19": "L'Ermite",
+ "20": "La Roue de Fortune",
+ "21": "La Force",
+ "22": "Le Pendu"
}
}
},
"TarotDeck": {
"CardsDrawn": "Cartes tirées",
"CardsInDeck": "Cartes dans le jeu",
+ "CardsInDiscard": "Cartes dans la défausse",
+ "CollectHands": "Récupérer les mains",
+ "CollectHandsConfirm": "Récupérer toutes les mains ?",
+ "CollectHandsWarning": "Cela récupérera toutes les cartes de tarot de tous les personnages joueurs et les réintégrera dans le deck. Les doublons seront supprimés pour garantir un deck de 78 cartes.",
+ "HandsCollected": "{collected} cartes récupérées. Deck réinitialisé avec {deckSize} cartes uniques.",
+ "DistributeCards": "Distribuer 8 cartes",
+ "DistributeConfirm": "Distribuer les cartes ?",
+ "DistributeWarning": "Cela distribuera 8 cartes du deck à chaque joueur connecté.",
+ "CardsDistributed": "{cards} cartes distribuées à {players} joueur(s).",
+ "NotEnoughCards": "Pas assez de cartes dans le deck (minimum 8 requises).",
"DeckEmpty": "Le jeu est vide",
"DeckEmptyWarning": "Le jeu est vide. Veuillez réinitialiser le jeu pour continuer.",
"DeckReset": "Le jeu a été réinitialisé et mélangé",
+ "DiscardShuffled": "La défausse a été mélangée dans le jeu",
+ "DrawCard": "Tirer une carte",
"DrawFive": "Tirer 5 cartes",
"DrawOne": "Tirer 1 carte",
+ "DrawTension": "Tirage sous tension",
"DrawThree": "Tirer 3 cartes",
"GMOnly": "Seul le MJ peut accéder au gestionnaire de jeu de tarot",
"NoCardsFound": "Aucune carte de tarot trouvée dans le monde. Veuillez d'abord créer des objets tarot.",
+ "NoDiscard": "La défausse est vide",
"NoDrawsYet": "Aucune carte tirée pour l'instant",
"RecentDraws": "Cartes tirées récemment",
"ResetConfirm": "Réinitialiser le jeu ?",
"ResetDeck": "Réinitialiser le jeu",
"ResetWarning": "Cela réinitialisera le jeu et mélangera toutes les cartes. L'historique des cartes tirées sera effacé.",
+ "SelectDifficulty": "Sélectionner la difficulté",
+ "ShuffleDiscard": "Mélanger la défausse",
"Title": "Gestionnaire de jeu de tarot",
"TotalCards": "Total des cartes"
},
diff --git a/macro-import-competences.js b/macro-import-competences.js
new file mode 100644
index 0000000..35849b2
--- /dev/null
+++ b/macro-import-competences.js
@@ -0,0 +1,105 @@
+/**
+ * Macro d'import des compétences depuis competences.json
+ * Crée un dossier "Compétences" et y importe toutes les compétences
+ */
+
+async function importCompetences() {
+ // Charger le fichier JSON
+ const response = await fetch('systems/fvtt-hamalron/assets/data/competences.json');
+ const competencesData = await response.json();
+
+ ui.notifications.info("Début de l'import des compétences...");
+
+ // Créer ou récupérer le dossier pour les compétences
+ let competencesFolder = game.folders.find(f => f.name === "Compétences" && f.type === "Item");
+
+ if (!competencesFolder) {
+ competencesFolder = await Folder.create({
+ name: "Compétences",
+ type: "Item",
+ color: "#4169e1",
+ sorting: "a"
+ });
+ console.log("Dossier 'Compétences' créé");
+ } else {
+ console.log("Dossier 'Compétences' existant trouvé");
+ }
+
+ // Compteurs pour le résumé
+ let importCount = 0;
+ let updateCount = 0;
+ let errorCount = 0;
+
+ ui.notifications.info(`Début de l'import de ${competencesData.length} compétences...`);
+
+ // Parcourir toutes les compétences
+ for (const competenceJson of competencesData) {
+ try {
+ // Préparer les données de la compétence selon le modèle
+ const itemData = {
+ name: competenceJson.name,
+ type: 'competence',
+ system: {
+ description: competenceJson.description,
+ type: competenceJson.type,
+ carteSymbole: competenceJson.carteSymbole,
+ niveau: 'inexperimente', // Valeur par défaut
+ }
+ };
+
+ // Ajouter les champs optionnels s'ils existent
+ if (competenceJson.faction) {
+ itemData.system.faction = competenceJson.faction;
+ }
+
+ if (competenceJson.peuple) {
+ itemData.system.peuple = competenceJson.peuple;
+ }
+
+ // Vérifier si la compétence existe déjà
+ const existing = game.items.find(i => i.name === competenceJson.name && i.type === 'competence');
+
+ if (existing) {
+ // Mettre à jour la compétence existante
+ await existing.update(itemData);
+ updateCount++;
+ console.log(`Compétence mise à jour: ${competenceJson.name}`);
+ } else {
+ // Créer une nouvelle compétence dans le dossier
+ await Item.create({
+ ...itemData,
+ folder: competencesFolder.id
+ });
+ importCount++;
+ console.log(`✓ Créé: ${competenceJson.name}`);
+ }
+
+ } catch (error) {
+ errorCount++;
+ console.error(`Erreur lors de l'import de ${competenceJson.name}:`, error);
+ }
+ }
+
+ // Afficher le résumé
+ const message = `
+
Import des compétences terminé
+ Compétences créées: ${importCount}
+ Compétences mises à jour: ${updateCount}
+ Erreurs: ${errorCount}
+ `;
+
+ ChatMessage.create({
+ user: game.user.id,
+ content: message
+ });
+
+ ui.notifications.info(`Import terminé: ${importCount} créées, ${updateCount} mises à jour, ${errorCount} erreurs.`);
+
+ console.log('=== Résumé de l\'import ===');
+ console.log(`Compétences créées: ${importCount}`);
+ console.log(`Compétences mises à jour: ${updateCount}`);
+ console.log(`Erreurs: ${errorCount}`);
+}
+
+// Exécuter l'import
+importCompetences();
diff --git a/macro-import-factions.js b/macro-import-factions.js
new file mode 100644
index 0000000..4048245
--- /dev/null
+++ b/macro-import-factions.js
@@ -0,0 +1,93 @@
+/**
+ * Macro d'import des factions depuis factions.json
+ * Crée un dossier "Factions" et y importe toutes les factions
+ */
+
+async function importFactions() {
+ // Charger le fichier JSON
+ const response = await fetch('systems/fvtt-hamalron/assets/data/factions.json');
+ const factionsData = await response.json();
+
+ ui.notifications.info("Début de l'import des factions...");
+
+ // Créer ou récupérer le dossier pour les factions
+ let factionsFolder = game.folders.find(f => f.name === "Factions" && f.type === "Item");
+
+ if (!factionsFolder) {
+ factionsFolder = await Folder.create({
+ name: "Factions",
+ type: "Item",
+ color: "#8b0000",
+ sorting: "a"
+ });
+ console.log("Dossier 'Factions' créé");
+ } else {
+ console.log("Dossier 'Factions' existant trouvé");
+ }
+
+ // Compteurs pour le résumé
+ let importCount = 0;
+ let updateCount = 0;
+ let errorCount = 0;
+
+ ui.notifications.info(`Début de l'import de ${factionsData.length} factions...`);
+
+ // Parcourir toutes les factions
+ for (const factionJson of factionsData) {
+ try {
+ // Préparer les données de la faction selon le modèle
+ const itemData = {
+ name: factionJson.nom,
+ type: 'faction',
+ system: {
+ description: factionJson.description
+ }
+ };
+
+ // Vérifier si la faction existe déjà
+ const existing = game.items.find(i => i.name === factionJson.nom && i.type === 'faction');
+
+ if (existing) {
+ // Mettre à jour la faction existante
+ await existing.update(itemData);
+ updateCount++;
+ console.log(`Faction mise à jour: ${factionJson.nom}`);
+ } else {
+ // Créer une nouvelle faction dans le dossier
+ await Item.create({
+ ...itemData,
+ folder: factionsFolder.id
+ });
+ importCount++;
+ console.log(`✓ Créé: ${factionJson.nom}`);
+ }
+
+ } catch (error) {
+ errorCount++;
+ console.error(`Erreur lors de l'import de ${factionJson.nom}:`, error);
+ }
+ }
+
+ // Afficher le résumé
+ const message = `
+ Import des factions terminé
+ Factions créées: ${importCount}
+ Factions mises à jour: ${updateCount}
+ Erreurs: ${errorCount}
+ `;
+
+ ChatMessage.create({
+ user: game.user.id,
+ content: message
+ });
+
+ ui.notifications.info(`Import terminé: ${importCount} créées, ${updateCount} mises à jour, ${errorCount} erreurs.`);
+
+ console.log('=== Résumé de l\'import ===');
+ console.log(`Factions créées: ${importCount}`);
+ console.log(`Factions mises à jour: ${updateCount}`);
+ console.log(`Erreurs: ${errorCount}`);
+}
+
+// Exécuter l'import
+importFactions();
diff --git a/macro-import-peuples.js b/macro-import-peuples.js
new file mode 100644
index 0000000..bbdf88a
--- /dev/null
+++ b/macro-import-peuples.js
@@ -0,0 +1,93 @@
+/**
+ * Macro d'import des peuples depuis peuples.json
+ * Crée un dossier "Peuples" et y importe tous les peuples
+ */
+
+async function importPeuples() {
+ // Charger le fichier JSON
+ const response = await fetch('systems/fvtt-hamalron/assets/data/peuples.json');
+ const peuplesData = await response.json();
+
+ ui.notifications.info("Début de l'import des peuples...");
+
+ // Créer ou récupérer le dossier pour les peuples
+ let peuplesFolder = game.folders.find(f => f.name === "Peuples" && f.type === "Item");
+
+ if (!peuplesFolder) {
+ peuplesFolder = await Folder.create({
+ name: "Peuples",
+ type: "Item",
+ color: "#228b22",
+ sorting: "a"
+ });
+ console.log("Dossier 'Peuples' créé");
+ } else {
+ console.log("Dossier 'Peuples' existant trouvé");
+ }
+
+ // Compteurs pour le résumé
+ let importCount = 0;
+ let updateCount = 0;
+ let errorCount = 0;
+
+ ui.notifications.info(`Début de l'import de ${peuplesData.length} peuples...`);
+
+ // Parcourir tous les peuples
+ for (const peupleJson of peuplesData) {
+ try {
+ // Préparer les données du peuple selon le modèle
+ const itemData = {
+ name: peupleJson.nom,
+ type: 'peuple',
+ system: {
+ description: peupleJson.description
+ }
+ };
+
+ // Vérifier si le peuple existe déjà
+ const existing = game.items.find(i => i.name === peupleJson.nom && i.type === 'peuple');
+
+ if (existing) {
+ // Mettre à jour le peuple existant
+ await existing.update(itemData);
+ updateCount++;
+ console.log(`Peuple mis à jour: ${peupleJson.nom}`);
+ } else {
+ // Créer un nouveau peuple dans le dossier
+ await Item.create({
+ ...itemData,
+ folder: peuplesFolder.id
+ });
+ importCount++;
+ console.log(`✓ Créé: ${peupleJson.nom}`);
+ }
+
+ } catch (error) {
+ errorCount++;
+ console.error(`Erreur lors de l'import de ${peupleJson.nom}:`, error);
+ }
+ }
+
+ // Afficher le résumé
+ const message = `
+ Import des peuples terminé
+ Peuples créés: ${importCount}
+ Peuples mis à jour: ${updateCount}
+ Erreurs: ${errorCount}
+ `;
+
+ ChatMessage.create({
+ user: game.user.id,
+ content: message
+ });
+
+ ui.notifications.info(`Import terminé: ${importCount} créés, ${updateCount} mis à jour, ${errorCount} erreurs.`);
+
+ console.log('=== Résumé de l\'import ===');
+ console.log(`Peuples créés: ${importCount}`);
+ console.log(`Peuples mis à jour: ${updateCount}`);
+ console.log(`Erreurs: ${errorCount}`);
+}
+
+// Exécuter l'import
+importPeuples();
diff --git a/module/applications/sheets/personnage-sheet.mjs b/module/applications/sheets/personnage-sheet.mjs
index cf6a292..3ecff00 100644
--- a/module/applications/sheets/personnage-sheet.mjs
+++ b/module/applications/sheets/personnage-sheet.mjs
@@ -1,4 +1,5 @@
import HamalronActorSheet from "./base-actor-sheet.mjs"
+import { SYSTEM } from "../../config/system.mjs"
export default class HamalronPersonnageSheet extends HamalronActorSheet {
/** @override */
@@ -20,6 +21,12 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
createRitual: HamalronPersonnageSheet.#onCreateRitual,
createPerk: HamalronPersonnageSheet.#onCreatePerk,
modifyAmmo: HamalronPersonnageSheet.#onModifyAmmo,
+ modifyResistance: HamalronPersonnageSheet.#onModifyResistance,
+ discardCard: HamalronPersonnageSheet.#onDiscardCard,
+ rollCompetence: HamalronPersonnageSheet.#onRollCompetence,
+ drawCard: HamalronPersonnageSheet.#onDrawCard,
+ selectCard: HamalronPersonnageSheet.#onSelectCard,
+ discardAndDraw: HamalronPersonnageSheet.#onDiscardAndDraw,
},
}
@@ -31,18 +38,18 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
tabs: {
template: "templates/generic/tab-navigation.hbs",
},
- status: {
+ competences: {
template: "systems/fvtt-hamalron/templates/personnage-status.hbs",
},
- maleficas: {
+ tarot: {
+ template: "systems/fvtt-hamalron/templates/personnage-tarot.hbs",
+ },
+ sortileges: {
template: "systems/fvtt-hamalron/templates/personnage-sortileges.hbs",
},
equipment: {
template: "systems/fvtt-hamalron/templates/personnage-equipement.hbs",
},
- tarot: {
- template: "systems/fvtt-hamalron/templates/personnage-tarot.hbs",
- },
biography: {
template: "systems/fvtt-hamalron/templates/personnage-biographie.hbs",
},
@@ -50,7 +57,7 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
/** @override */
tabGroups = {
- sheet: "status",
+ sheet: "competences",
}
/**
@@ -59,10 +66,10 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
*/
#getTabs() {
const tabs = {
- status: { id: "status", group: "sheet", icon: "fa-solid fa-compass", label: "HAMALRON.Label.status" },
- maleficas: { id: "maleficas", group: "sheet", icon: "fa-solid fa-compass", label: "HAMALRON.Label.maleficas" },
- equipment: { id: "equipment", group: "sheet", icon: "fa-solid fa-shapes", label: "HAMALRON.Label.equipment" },
+ competences: { id: "competences", group: "sheet", icon: "fa-solid fa-list-check", label: "HAMALRON.Label.competences" },
tarot: { id: "tarot", group: "sheet", icon: "fa-solid fa-cards", label: "HAMALRON.Label.tarot" },
+ sortileges: { id: "sortileges", group: "sheet", icon: "fa-solid fa-wand-magic-sparkles", label: "HAMALRON.Label.sortileges" },
+ equipment: { id: "equipment", group: "sheet", icon: "fa-solid fa-shapes", label: "HAMALRON.Label.equipment" },
biography: { id: "biography", group: "sheet", icon: "fa-solid fa-book", label: "HAMALRON.Label.biography" },
}
for (const v of Object.values(tabs)) {
@@ -78,9 +85,6 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
context.tabs = this.#getTabs()
const doc = this.document
- context.trait = doc.itemTypes['species-trait']?.[0]
- context.upright = doc.itemTypes.tarot.find(t => t.system.orientation === "Upright")
- context.downright = doc.itemTypes.tarot.find(t => t.system.orientation === "Downright")
return context
}
@@ -91,30 +95,36 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
context.systemFields = this.document.system.schema.fields
switch (partId) {
case "main":
+ // Get peuple and faction items (only one of each allowed)
+ context.peuple = doc.itemTypes.peuple?.[0] || null
+ context.faction = doc.itemTypes.faction?.[0] || null
+ context.isEditMode = this.isEditMode
+ context.isPlayMode = this.isPlayMode
break
- case "status":
- context.tab = context.tabs.status
- context.perks = doc.itemTypes.perk || []
- // Sort the perks by system.role and then by the system.level
- context.perks.sort((a, b) => {
- if (a.system.role === b.system.role) {
- return a.system.level.localeCompare(b.system.level)
- }
- return a.system.role.localeCompare(b.system.role)
+ case "competences":
+ context.tab = context.tabs.competences
+ const allCompetences = doc.itemTypes.competence || []
+ // Ajouter les données de niveau enrichies à chaque compétence
+ allCompetences.forEach(c => {
+ const niveauData = SYSTEM.NIVEAU_COMPETENCES[c.system.niveau]
+ c.niveauName = niveauData?.name || c.system.niveau
+ c.niveauModificateur = niveauData?.modificateur ?? 0
})
+ // Grouper les compétences par type et trier par nom dans chaque groupe
+ context.competencesCommunes = allCompetences.filter(c => c.system.type === 'commune').sort((a, b) => a.name.localeCompare(b.name))
+ context.competencesPeuple = allCompetences.filter(c => c.system.type === 'peuple').sort((a, b) => a.name.localeCompare(b.name))
+ context.competencesFaction = allCompetences.filter(c => c.system.type === 'faction').sort((a, b) => a.name.localeCompare(b.name))
break;
- case "maleficas":
- context.tab = context.tabs.maleficas
- context.maleficas = doc.itemTypes.malefica || []
- // Sort the maleficas by system.domain and then by the system.level
- context.maleficas.sort((a, b) => {
+ case "sortileges":
+ context.tab = context.tabs.sortileges
+ context.sortileges = doc.itemTypes.sortilege || []
+ // Sort the sortileges by system.domain and then by the system.level
+ context.sortileges.sort((a, b) => {
if (a.system.domain === b.system.domain) {
return a.system.level.localeCompare(b.system.level)
}
return a.system.domain.localeCompare(b.system.domain)
})
- context.rituals = doc.itemTypes.ritual || []
- context.rituals.sort((a, b) => a.name.localeCompare(b.name))
break
case "equipment":
context.tab = context.tabs.equipment
@@ -129,9 +139,23 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
context.tab = context.tabs.tarot
context.tarotCards = doc.itemTypes.tarot || []
context.tarotCards.sort((a, b) => a.name.localeCompare(b.name))
- // Enrich descriptions for each tarot card
+ context.handLimit = 7
+ context.handSize = context.tarotCards.length
+ context.isOverLimit = context.handSize > context.handLimit
+ context.canAddCard = context.handSize < 8
+ // Marquer les cartes de succès et enrichir les descriptions
for (const card of context.tarotCards) {
card.enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(card.system.description, { async: true })
+ // Vérifier si c'est une carte de succès
+ if (doc.system.cartesSucces && card.system.type !== "atout") {
+ card.isSuccessCard = Object.keys(doc.system.cartesSucces).some(symbole => {
+ const successCardData = doc.system.cartesSucces[symbole]
+ return card.system.symbole === symbole &&
+ card.system.valeur === successCardData.value.toString()
+ })
+ } else {
+ card.isSuccessCard = false
+ }
}
break
case "biography":
@@ -196,6 +220,190 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
await item.update({ "system.ammoQuantity": newAmmo })
}
+ static async #onModifyResistance(event, target) {
+ const symbole = target.dataset.symbole
+ const delta = Number.parseInt(target.dataset.delta)
+
+ if (!symbole || isNaN(delta)) {
+ console.warn(`HamalronPersonnageSheet: Invalid resistance modification parameters`)
+ return
+ }
+
+ const resistance = this.document.system.resistances[symbole]
+ if (!resistance) {
+ console.warn(`HamalronPersonnageSheet: Resistance ${symbole} not found`)
+ return
+ }
+
+ const newValue = Math.max(0, Math.min(resistance.max, resistance.value + delta))
+ await this.document.update({ [`system.resistances.${symbole}.value`]: newValue })
+ }
+
+ static async #onDiscardCard(event, target) {
+ const itemId = $(event.target).data("item-id")
+ const item = this.document.items.get(itemId)
+ if (!item || item.type !== "tarot") {
+ console.warn(`HamalronPersonnageSheet: Tarot card with ID ${itemId} not found`)
+ return
+ }
+
+ // Supprimer la carte du personnage
+ await item.delete()
+ ui.notifications.info(game.i18n.localize("HAMALRON.Notifications.cardDiscarded") + item.name)
+ }
+
+ static async #onSelectCard(event, target) {
+ const cardWrapper = $(target).closest(".tarot-card-wrapper")
+ const wasSelected = cardWrapper.hasClass("selected")
+
+ // Désélectionner toutes les cartes
+ $(".tarot-card-wrapper").removeClass("selected")
+
+ // Sélectionner la carte cliquée si elle n'était pas déjà sélectionnée
+ if (!wasSelected) {
+ cardWrapper.addClass("selected")
+ }
+ }
+
+ static async #onDiscardAndDraw(event, target) {
+ const itemId = $(target).data("item-id")
+ const item = this.document.items.get(itemId)
+ if (!item || item.type !== "tarot") {
+ console.warn(`HamalronPersonnageSheet: Tarot card with ID ${itemId} not found`)
+ return
+ }
+
+ // Dialog de confirmation
+ const confirmed = await foundry.applications.api.DialogV2.confirm({
+ window: {
+ title: game.i18n.localize("HAMALRON.Dialog.discardCardTitle"),
+ },
+ content: `${game.i18n.format("HAMALRON.Dialog.discardCardContent", { cardName: item.name })}
`,
+ rejectClose: false,
+ modal: true,
+ })
+
+ if (!confirmed) return
+
+ // Récupérer le deck manager
+ const module = await import("../tarot-deck-manager.mjs")
+ const HamalronTarotDeckManager = module.default
+
+ if (!HamalronTarotDeckManager._instance) {
+ HamalronTarotDeckManager._instance = new HamalronTarotDeckManager()
+ }
+
+ const deckManager = HamalronTarotDeckManager._instance
+
+ if (!deckManager) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.deckManagerNotAvailable"))
+ return
+ }
+
+ // Ajouter la carte à la défausse
+ deckManager.addToDiscard({
+ id: item.id,
+ name: item.name,
+ img: item.img,
+ symbole: item.system.symbole,
+ valeur: item.system.valeur,
+ type: item.system.type,
+ description: item.system.description,
+ })
+
+ // Supprimer la carte du personnage
+ await item.delete()
+
+ // Tirer une nouvelle carte si le deck n'est pas vide
+ if (deckManager.deck.length > 0) {
+ const newCards = deckManager.drawCards(1)
+ if (newCards.length > 0) {
+ const newCard = newCards[0]
+
+ // Cas spécial : Le Mat
+ if (newCard.valeur === "lemat") {
+ console.log("Le Mat drawn! Executing special rules...")
+ const { default: HamalronTirageTarot } = await import("../../documents/tirage-tarot.mjs")
+ await HamalronTirageTarot.handleLeMatEffect(this.document, deckManager)
+ } else {
+ const originalItem = game.items.get(newCard.id)
+ if (originalItem) {
+ await this.document.createEmbeddedDocuments("Item", [originalItem.toObject()])
+ ui.notifications.info(game.i18n.localize("HAMALRON.Notifications.cardDiscardedAndDrawn") + newCard.name)
+ }
+ }
+ }
+ } else {
+ ui.notifications.info(game.i18n.localize("HAMALRON.Notifications.cardDiscardedNoNew"))
+ }
+
+ deckManager.saveDeckState()
+ deckManager.render()
+ }
+
+ static async #onDrawCard(event, target) {
+ const currentTarotCount = this.document.items.filter(i => i.type === "tarot").length
+
+ // Vérifier que le joueur a moins de 7 cartes
+ if (currentTarotCount >= 7) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.cannotDrawCard"))
+ return
+ }
+
+ // Récupérer le deck manager singleton
+ const module = await import("../tarot-deck-manager.mjs")
+ const HamalronTarotDeckManager = module.default
+
+ // Vérifier si l'instance existe, sinon la créer
+ if (!HamalronTarotDeckManager._instance) {
+ HamalronTarotDeckManager._instance = new HamalronTarotDeckManager()
+ }
+
+ const deckManager = HamalronTarotDeckManager._instance
+
+ if (!deckManager) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.deckManagerNotAvailable"))
+ return
+ }
+
+ if (deckManager.deck.length === 0) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.deckEmpty"))
+ return
+ }
+
+ // Tirer une nouvelle carte
+ const newCards = deckManager.drawCards(1)
+ if (newCards.length > 0) {
+ const newCard = newCards[0]
+
+ // Cas spécial : Le Mat
+ if (newCard.valeur === "lemat") {
+ console.log("Le Mat drawn! Executing special rules...")
+ const { default: HamalronTirageTarot } = await import("../../documents/tirage-tarot.mjs")
+ await HamalronTirageTarot.handleLeMatEffect(this.document, deckManager)
+ } else {
+ // Trouver l'item original pour le dupliquer
+ const originalItem = game.items.get(newCard.id)
+ if (originalItem) {
+ await this.document.createEmbeddedDocuments("Item", [originalItem.toObject()])
+ ui.notifications.info(game.i18n.localize("HAMALRON.Notifications.newCardDrawn") + newCard.name)
+ }
+ }
+ deckManager.saveDeckState()
+ deckManager.render()
+ }
+ }
+
+ static async #onRollCompetence(event, target) {
+ const itemId = $(target).data("item-id")
+ const item = this.document.items.get(itemId)
+ if (!item || item.type !== "competence") {
+ console.warn(`HamalronPersonnageSheet: Competence with ID ${itemId} not found`)
+ return
+ }
+ await this.document.system.roll("competence", item)
+ }
+
/**
* Handles the roll action triggered by user interaction.
*
@@ -239,12 +447,19 @@ export default class HamalronPersonnageSheet extends HamalronActorSheet {
if (data.type === "Item") {
const item = await fromUuid(data.uuid)
if (item.type === "tarot") {
- // Delete the existing tarot item
- const existingTarot = this.document.items.find(i => i.type === "tarot" && i.system.orientation === item.system.orientation)
- if (existingTarot) {
- await existingTarot.delete()
- // Display info message
- ui.notifications.info(game.i18n.localize("HAMALRON.Notifications.tarotDeleted") + existingTarot.name)
+ // Check if a card with the same name already exists
+ const existingCard = this.document.items.find(i => i.type === "tarot" && i.name === item.name)
+ if (existingCard) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.tarotCardAlreadyExists") + item.name)
+ return
+ }
+
+ const currentTarotCount = this.document.items.filter(i => i.type === "tarot").length
+
+ // Check if we already have 8 cards (hard limit)
+ if (currentTarotCount >= 8) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.tarotHandFull"))
+ return
}
}
if (item.type === "species-trait") {
diff --git a/module/applications/tarot-deck-manager.mjs b/module/applications/tarot-deck-manager.mjs
index e08173b..d22c846 100644
--- a/module/applications/tarot-deck-manager.mjs
+++ b/module/applications/tarot-deck-manager.mjs
@@ -4,8 +4,8 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
constructor(options = {}) {
super(options)
this.deck = []
- this.drawnCards = []
- this.resetDeck()
+ this.discard = []
+ this.loadDeckState()
}
/** @override */
@@ -26,6 +26,10 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
resetDeck: HamalronTarotDeckManager.#onResetDeck,
drawCard: HamalronTarotDeckManager.#onDrawCard,
drawMultiple: HamalronTarotDeckManager.#onDrawMultiple,
+ shuffleDiscard: HamalronTarotDeckManager.#onShuffleDiscard,
+ collectHands: HamalronTarotDeckManager.#onCollectHands,
+ distributeCards: HamalronTarotDeckManager.#onDistributeCards,
+ drawTension: HamalronTarotDeckManager.#onDrawTension,
},
}
@@ -36,12 +40,39 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
},
}
+ /**
+ * Save the current deck state to settings
+ */
+ async saveDeckState() {
+ const state = {
+ deck: this.deck,
+ discard: this.discard,
+ }
+ await game.settings.set("fvtt-hamalron", "tarotDeckState", state)
+ console.log("Deck state saved:", state)
+ }
+
+ /**
+ * Load the deck state from settings
+ */
+ loadDeckState() {
+ const state = game.settings.get("fvtt-hamalron", "tarotDeckState")
+ if (state && state.deck && state.deck.length > 0) {
+ this.deck = state.deck
+ this.discard = state.discard || []
+ console.log("Deck state loaded:", state)
+ } else {
+ // Si aucun état sauvegardé, initialiser un nouveau deck
+ this.resetDeck()
+ }
+ }
+
/**
* Reset the deck to a full tarot deck
*/
resetDeck() {
this.deck = []
- this.drawnCards = []
+ this.discard = []
// Créer toutes les cartes du jeu de tarot
const items = game.items.filter(i => i.type === "tarot")
@@ -63,6 +94,7 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
// Mélanger le deck
this.shuffleDeck()
+ this.saveDeckState()
this.render()
}
@@ -90,7 +122,6 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
const drawn = []
for (let i = 0; i < count && this.deck.length > 0; i++) {
const card = this.deck.shift()
- this.drawnCards.push(card)
drawn.push(card)
}
@@ -130,10 +161,10 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
const context = await super._prepareContext(options)
context.deckCount = this.deck.length
- context.drawnCount = this.drawnCards.length
- context.totalCards = this.deck.length + this.drawnCards.length
+ context.discardCount = this.discard.length
+ context.totalCards = this.deck.length + this.discard.length
context.hasCards = this.deck.length > 0
- context.drawnCards = this.drawnCards.slice(-5).reverse() // Show last 5 drawn cards
+ context.hasDiscard = this.discard.length > 0
return context
}
@@ -166,6 +197,9 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
const cards = this.drawCards(1)
if (cards.length > 0) {
await this.sendCardsToChat(cards)
+ // Ajouter les cartes directement à la défausse
+ cards.forEach(card => this.addToDiscard(card))
+ this.saveDeckState()
this.render()
}
}
@@ -180,10 +214,316 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin
const cards = this.drawCards(count)
if (cards.length > 0) {
await this.sendCardsToChat(cards)
+ // Ajouter les cartes directement à la défausse
+ cards.forEach(card => this.addToDiscard(card))
+ this.saveDeckState()
this.render()
}
}
+ /**
+ * Add a card to the discard pile
+ * @param {Object} card - Card to add to discard
+ */
+ addToDiscard(card) {
+ // Vérifier que la carte n'est pas déjà dans la défausse
+ const cardExists = this.discard.some(c => c.id === card.id)
+ if (!cardExists) {
+ this.discard.push(card)
+ this.saveDeckState()
+ this.render()
+ }
+ }
+
+ /**
+ * Collect all tarot cards from player characters and return them to the deck
+ * @param {Event} event
+ * @param {HTMLElement} target
+ */
+ static async #onCollectHands(event, target) {
+ const confirmed = await foundry.applications.api.DialogV2.confirm({
+ window: { title: game.i18n.localize("HAMALRON.TarotDeck.CollectHandsConfirm") },
+ content: `${game.i18n.localize("HAMALRON.TarotDeck.CollectHandsWarning")}
`,
+ rejectClose: false,
+ modal: true,
+ })
+
+ if (!confirmed) return
+
+ let totalCollected = 0
+
+ // Récupérer tous les acteurs de type personnage (incluant tous, pas seulement ceux avec propriété joueur)
+ const playerCharacters = game.actors.filter(a => a.type === "personnage")
+
+ console.log("Found characters:", playerCharacters.length)
+
+ // Collecter toutes les cartes de tarot de tous les personnages
+ for (const actor of playerCharacters) {
+ const tarotCards = actor.items.filter(i => i.type === "tarot")
+ console.log(`Actor ${actor.name} has ${tarotCards.length} tarot cards`)
+
+ if (tarotCards.length > 0) {
+ // Supprimer les cartes de l'acteur
+ const cardIds = tarotCards.map(c => c.id)
+ console.log(`Deleting ${cardIds.length} cards from ${actor.name}`)
+ await actor.deleteEmbeddedDocuments("Item", cardIds)
+ console.log(`Deleted cards from ${actor.name}`)
+ totalCollected += tarotCards.length
+ }
+ }
+
+ // Réinitialiser le deck avec toutes les cartes de tarot disponibles
+ this.deck = []
+ this.discard = []
+
+ const items = game.items.filter(i => i.type === "tarot")
+
+ if (items.length > 0) {
+ // Créer un Map pour éviter les doublons (utiliser l'ID unique)
+ const uniqueCards = new Map()
+
+ items.forEach(item => {
+ const key = `${item.system.symbole}_${item.system.valeur}_${item.system.type}`
+ if (!uniqueCards.has(key)) {
+ uniqueCards.set(key, {
+ id: item.id,
+ name: item.name,
+ img: item.img,
+ symbole: item.system.symbole,
+ valeur: item.system.valeur,
+ type: item.system.type,
+ description: item.system.description,
+ })
+ }
+ })
+
+ this.deck = Array.from(uniqueCards.values())
+ }
+
+ // Mélanger le deck
+ this.shuffleDeck()
+
+ this.saveDeckState()
+
+ ui.notifications.info(
+ game.i18n.format("HAMALRON.TarotDeck.HandsCollected", {
+ collected: totalCollected,
+ deckSize: this.deck.length
+ })
+ )
+
+ this.render()
+ }
+
+ /**
+ * Distribute 8 cards to all connected players
+ * @param {Event} event
+ * @param {HTMLElement} target
+ */
+ static async #onDistributeCards(event, target) {
+ if (this.deck.length < 8) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.TarotDeck.NotEnoughCards"))
+ return
+ }
+
+ const confirmed = await foundry.applications.api.DialogV2.confirm({
+ window: { title: game.i18n.localize("HAMALRON.TarotDeck.DistributeConfirm") },
+ content: `${game.i18n.localize("HAMALRON.TarotDeck.DistributeWarning")}
`,
+ rejectClose: false,
+ modal: true,
+ })
+
+ if (!confirmed) return
+
+ let distributedCount = 0
+ let playersCount = 0
+
+ // Récupérer tous les utilisateurs connectés (sauf le GM)
+ const connectedPlayers = game.users.filter(u => u.active && !u.isGM)
+
+ for (const user of connectedPlayers) {
+ // Trouver le personnage du joueur (premier actor de type personnage dont il est propriétaire)
+ const playerCharacter = game.actors.find(a =>
+ a.type === "personnage" &&
+ a.testUserPermission(user, "OWNER")
+ )
+
+ if (playerCharacter) {
+ // Tirer 8 cartes pour ce personnage
+ const cardsToDistribute = []
+ for (let i = 0; i < 8 && this.deck.length > 0; i++) {
+ const card = this.deck.shift()
+ cardsToDistribute.push(card)
+ }
+
+ // Créer les items sur l'acteur
+ for (const card of cardsToDistribute) {
+ const originalItem = game.items.get(card.id)
+ if (originalItem) {
+ await playerCharacter.createEmbeddedDocuments("Item", [originalItem.toObject()])
+ distributedCount++
+
+ // Cas spécial : Le Mat
+ if (card.valeur === "lemat") {
+ console.log(`Le Mat distributed to ${playerCharacter.name}! Executing special rules...`)
+ // Import de TirageTarot pour accéder à la fonction helper
+ const { default: HamalronTirageTarot } = await import("../documents/tirage-tarot.mjs")
+ await HamalronTirageTarot.handleLeMatEffect(playerCharacter, this)
+ }
+ }
+ }
+
+ playersCount++
+ }
+ }
+
+ this.saveDeckState()
+
+ ui.notifications.info(
+ game.i18n.format("HAMALRON.TarotDeck.CardsDistributed", {
+ cards: distributedCount,
+ players: playersCount
+ })
+ )
+
+ this.render()
+ }
+
+ /**
+ * Shuffle discard pile back into deck
+ * @param {Event} event
+ * @param {HTMLElement} target
+ */
+ static async #onShuffleDiscard(event, target) {
+ if (this.discard.length === 0) {
+ ui.notifications.warn(game.i18n.localize("HAMALRON.TarotDeck.NoDiscard"))
+ return
+ }
+
+ // Ajouter toutes les cartes de la défausse au deck
+ this.deck.push(...this.discard)
+ this.discard = []
+
+ // Mélanger le deck
+ this.shuffleDeck()
+
+ this.saveDeckState()
+
+ ui.notifications.info(game.i18n.localize("HAMALRON.TarotDeck.DiscardShuffled"))
+ this.render()
+ }
+
+ /**
+ * Handle draw tension action
+ * @param {Event} event
+ * @param {HTMLElement} target
+ */
+ static async #onDrawTension(event, target) {
+ // Import system config
+ const { DIFFICULTY_CHOICES } = await import('../config/system.mjs')
+
+ // Créer les options de difficulté
+ const difficulties = Object.entries(DIFFICULTY_CHOICES)
+ .filter(([key]) => key !== 'soustension_oppose')
+ .map(([key, value]) => ({
+ value: key,
+ label: value.label
+ }))
+
+ // Créer le contenu HTML du dialogue
+ const selectOptions = difficulties.map(d =>
+ `${d.label} `
+ ).join('')
+
+ const content = `
+
+ {{localize "HAMALRON.Label.difficulty"}}
+
+ ${selectOptions}
+
+
+ `
+
+ // Afficher le dialogue
+ const result = await foundry.applications.api.DialogV2.wait({
+ window: { title: game.i18n.localize("HAMALRON.TarotDeck.SelectDifficulty") },
+ content: content,
+ buttons: [
+ {
+ action: "draw",
+ label: game.i18n.localize("HAMALRON.TarotDeck.DrawCard"),
+ default: true,
+ callback: (event, button, dialog) => {
+ const select = button.form.elements["tension-difficulty"]
+ return select.value
+ }
+ },
+ {
+ action: "cancel",
+ label: game.i18n.localize("Cancel")
+ }
+ ],
+ rejectClose: false,
+ modal: true
+ })
+
+ if (!result) return
+
+ // Tirer une carte
+ const cards = this.drawCards(1)
+ if (cards.length === 0) return
+
+ const card = cards[0]
+ const difficultyKey = result
+ const difficulty = DIFFICULTY_CHOICES[difficultyKey]
+
+ // Récupérer la valeur numérique de la carte
+ const { TAROT_VALEURS } = await import('../config/system.mjs')
+ const cardValue = TAROT_VALEURS[card.valeur]?.value || 0
+ const tensionBonus = difficulty.soustension || 0
+ const totalScore = cardValue + tensionBonus
+
+ // Afficher dans le chat
+ await this.sendTensionDrawToChat(card, difficulty, cardValue, tensionBonus, totalScore)
+
+ // Ajouter à la défausse
+ this.addToDiscard(card)
+ this.saveDeckState()
+ this.render()
+ }
+
+ /**
+ * Send tension draw to chat
+ * @param {Object} card - The drawn card
+ * @param {Object} difficulty - The selected difficulty
+ * @param {number} cardValue - Card numeric value
+ * @param {number} tensionBonus - Tension modifier
+ * @param {number} totalScore - Total score
+ */
+ async sendTensionDrawToChat(card, difficulty, cardValue, tensionBonus, totalScore) {
+ const speaker = ChatMessage.getSpeaker({ alias: "Maître du Jeu" })
+
+ const content = await foundry.applications.handlebars.renderTemplate(
+ "systems/fvtt-hamalron/templates/chat-tarot-tension.hbs",
+ {
+ card: card,
+ symboleLabel: game.i18n.localize(`HAMALRON.Tarot.FIELDS.symbole.${card.symbole}`),
+ valeurLabel: game.i18n.localize(`HAMALRON.Tarot.FIELDS.valeur.${card.valeur}`),
+ typeLabel: game.i18n.localize(`HAMALRON.Tarot.FIELDS.type.${card.type}`),
+ difficulty: difficulty,
+ cardValue: cardValue,
+ tensionBonus: tensionBonus,
+ totalScore: totalScore
+ }
+ )
+
+ await ChatMessage.create({
+ speaker: speaker,
+ content: content,
+ type: CONST.CHAT_MESSAGE_TYPES.OTHER,
+ })
+ }
+
/**
* Open the Tarot Deck Manager application
* @returns {HamalronTarotDeckManager}
diff --git a/module/config/system.mjs b/module/config/system.mjs
index 4d21e30..6bb6d5c 100644
--- a/module/config/system.mjs
+++ b/module/config/system.mjs
@@ -23,10 +23,23 @@ export const TAROT_TYPES = {
}
export const TAROT_VALEURS = {
+ "11": { id: "11", label: "11", value: 11 },
+ "12": { id: "12", label: "12", value: 12 },
+ "13": { id: "13", label: "13", value: 13 },
+ "14": { id: "14", label: "14", value: 14 },
+ "15": { id: "15", label: "15", value: 15 },
+ "16": { id: "16", label: "16", value: 16 },
+ "17": { id: "17", label: "17", value: 17 },
+ "18": { id: "18", label: "18", value: 18 },
+ "19": { id: "19", label: "19", value: 19 },
+ "20": { id: "20", label: "20", value: 20 },
+ "21": { id: "21", label: "21", value: 21 },
+ "22": { id: "22", label: "22", value: 22 },
"roi": { id: "roi", label: "Roi", value: 14 },
"reine": { id: "reine", label: "Reine", value: 13 },
"cavalier": { id: "cavalier", label: "Cavalier", value: 12 },
"valet": { id: "valet", label: "Valet", value: 11 },
+ "lemat": { id: "lemat", label: "Le Mat", value: 23 },
"10": { id: "10", label: "10", value: 10 },
"9": { id: "9", label: "9", value: 9 },
"8": { id: "8", label: "8", value: 8 },
@@ -40,6 +53,7 @@ export const TAROT_VALEURS = {
}
export const DIFFICULTY_CHOICES = {
+ "soustension_oppose": { id: "soustension_oppose", label: "Sous Tension ou Opposé", standard: null, "soustension": null },
"tresfacile": { id: "tresfacile", label: "Très Facile", standard: 3, "soustension": -4 },
"facile": { id: "facile", label: "Facile", standard: 5, "soustension": -2 },
"moyenne": { id: "moyenne", label: "Moyenne", standard: 7, "soustension": 0 },
@@ -54,7 +68,7 @@ export const WEAPON_TYPES = {
}
export const COMPETENCE_TYPES = {
- "generale": { id: "generale", label: "Générale" },
+ "commune": { id: "commune", label: "Commune" },
"faction": { id: "faction", label: "Faction" },
"peuple": { id: "peuple", label: "Peuple" },
}
@@ -70,6 +84,42 @@ export const SORTILEGE_CATEGORIES = {
"ritual": { id: "ritual", label: "Rituel" },
}
+export const NIVEAU_COMPETENCES = {
+ "inexperimente": {
+ "name": "Inexpérimenté",
+ "id": "inexperimente",
+ "abreviation": "I",
+ "modificateur": 0,
+ "cout_acquisition_points": 0,
+ "description": "Niveau de départ par défaut pour toutes les compétences non apprises."
+ },
+ "amateur": {
+ "name": "Amateur",
+ "id": "amateur",
+ "abreviation": "A",
+ "modificateur": 1,
+ "cout_acquisition_points": 1,
+ "description": "Le personnage possède des notions de base dans la compétence."
+ },
+ "competent": {
+ "name": "Compétent",
+ "id": "competent",
+ "abreviation": "C",
+ "modificateur": 3,
+ "cout_acquisition_points": 3,
+ "cout_progression_depuis_amateur": 2,
+ "description": "Le personnage maîtrise la compétence et résiste mieux aux actions adverses."
+ },
+ "expert": {
+ "name": "Expert",
+ "abreviation": "E",
+ "modificateur": 5,
+ "cout_acquisition_points": 5,
+ "cout_progression_depuis_competent": 2,
+ "description": "Le personnage est un maître absolu dans son domaine."
+ }
+}
+
/**
* Include all constant definitions within the SYSTEM global export
* @type {Object}
@@ -84,5 +134,6 @@ export const SYSTEM = {
COMPETENCE_TYPES: COMPETENCE_TYPES,
ENEMY_TYPES: ENEMY_TYPES,
SORTILEGE_CATEGORIES: SORTILEGE_CATEGORIES,
+ NIVEAU_COMPETENCES: NIVEAU_COMPETENCES,
ASCII
}
diff --git a/module/documents/item.mjs b/module/documents/item.mjs
index 0f94704..eb644e1 100644
--- a/module/documents/item.mjs
+++ b/module/documents/item.mjs
@@ -1,14 +1,14 @@
export const defaultItemImg = {
- arme: "systems/fvtt-hamalron/assets/icons/arme.webp",
- armure: "systems/fvtt-hamalron/assets/icons/armure.webp",
- competence: "systems/fvtt-hamalron/assets/icons/competence.webp",
- equipement: "systems/fvtt-hamalron/assets/icons/equipement.webp",
- faction: "systems/fvtt-hamalron/assets/icons/faction.webp",
- langue: "systems/fvtt-hamalron/assets/icons/langue.webp",
- peuple: "systems/fvtt-hamalron/assets/icons/peuple.webp",
- region: "systems/fvtt-hamalron/assets/icons/region.webp",
- sortilege: "systems/fvtt-hamalron/assets/icons/sortilege.webp",
- tarot: "systems/fvtt-hamalron/assets/icons/tarot.webp",
+ arme: "systems/fvtt-hamalron/assets/icons/arme.svg",
+ armure: "systems/fvtt-hamalron/assets/icons/armure.svg",
+ competence: "systems/fvtt-hamalron/assets/icons/competence.svg",
+ equipement: "systems/fvtt-hamalron/assets/icons/equipement.svg",
+ faction: "systems/fvtt-hamalron/assets/icons/faction.svg",
+ langue: "systems/fvtt-hamalron/assets/icons/langue.svg",
+ peuple: "systems/fvtt-hamalron/assets/icons/peuple.svg",
+ region: "systems/fvtt-hamalron/assets/icons/region.svg",
+ sortilege: "systems/fvtt-hamalron/assets/icons/sortilege.svg",
+ tarot: "systems/fvtt-hamalron/assets/icons/tarot.svg",
}
export default class HamalronItem extends Item {
diff --git a/module/documents/tirage-tarot.mjs b/module/documents/tirage-tarot.mjs
index ea5cf6c..e419a00 100644
--- a/module/documents/tirage-tarot.mjs
+++ b/module/documents/tirage-tarot.mjs
@@ -8,6 +8,57 @@ export default class HamalronTirageTarot {
*/
static CHAT_TEMPLATE = "systems/fvtt-hamalron/templates/chat-message.hbs"
+ /**
+ * Handle Le Mat special effect when distributed to a player
+ * @param {Actor} actor - The actor who received Le Mat
+ * @param {HamalronTarotDeckManager} deckManager - The deck manager instance
+ */
+ static async handleLeMatEffect(actor, deckManager) {
+ // 1. Défausser toutes les cartes du joueur
+ const allTarotCards = actor.items.filter(i => i.type === "tarot")
+ if (allTarotCards.length > 0) {
+ const cardIds = allTarotCards.map(c => c.id)
+ await actor.deleteEmbeddedDocuments("Item", cardIds)
+ console.log(`Discarded ${cardIds.length} cards from player`)
+
+ // Ajouter toutes les cartes à la défausse
+ for (const card of allTarotCards) {
+ deckManager.addToDiscard({
+ id: card.id,
+ name: card.name,
+ img: card.img,
+ symbole: card.system.symbole,
+ valeur: card.system.valeur,
+ type: card.system.type,
+ description: card.system.description,
+ })
+ }
+ }
+
+ // 2. Tirer 7 nouvelles cartes pour le joueur
+ for (let i = 0; i < 7; i++) {
+ if (deckManager.deck.length > 0) {
+ const newCards = deckManager.drawCards(1)
+ if (newCards.length > 0) {
+ const newCard = newCards[0]
+ const originalItem = game.items.get(newCard.id)
+ if (originalItem) {
+ await actor.createEmbeddedDocuments("Item", [originalItem.toObject()])
+ }
+ }
+ }
+ }
+
+ // 3. Regrouper la défausse et le deck, puis mélanger
+ deckManager.deck.push(...deckManager.discard)
+ deckManager.discard = []
+ deckManager.shuffleDeck()
+
+ await deckManager.saveDeckState()
+ deckManager.render()
+ ui.notifications.info(`Le Mat ! Toutes vos cartes ont été défaussées et vous recevez 7 nouvelles cartes. Le deck a été mélangé.`)
+ }
+
static async prompt(options = {}) {
let formula = `3D6 + 0D6KH - 0D6KH + ${options?.rollItem?.value}`
@@ -15,6 +66,34 @@ export default class HamalronTirageTarot {
switch (options.rollType) {
case "stat":
break
+ case "competence":
+ {
+ // Récupérer les cartes de tarot du personnage
+ options.tarotCards = actor.items.filter(i => i.type === "tarot")
+ // Récupérer le modificateur de compétence depuis NIVEAU_COMPETENCES
+ const niveauData = SYSTEM.NIVEAU_COMPETENCES[options.rollItem.system.niveau]
+ options.competenceModifier = niveauData ? niveauData.modificateur : 0
+
+ // Marquer les cartes de succès
+ if (options.tarotCards && actor.system.cartesSucces) {
+ options.tarotCards = options.tarotCards.map(card => {
+ const isSuccessCard = card.system.type !== "atout" && Object.keys(actor.system.cartesSucces).some(symbole => {
+ const successCardData = actor.system.cartesSucces[symbole]
+ return card.system.symbole === symbole &&
+ card.system.valeur === successCardData.value.toString()
+ })
+ // Créer un objet simple avec toutes les propriétés nécessaires
+ return {
+ id: card.id,
+ name: card.name,
+ img: card.img,
+ system: card.system,
+ isSuccessCard: isSuccessCard
+ }
+ })
+ }
+ }
+ break
case "damage":
{
let formula = options.rollItem.system.damage
@@ -56,6 +135,7 @@ export default class HamalronTirageTarot {
let dialogContext = {
actorId: options.actorId,
actorName: options.actorName,
+ actorImage: options.actorImage,
rollType: options.rollType,
rollItem: foundry.utils.duplicate(options.rollItem), // Object only, no class
weapon: options?.weapon,
@@ -69,23 +149,45 @@ export default class HamalronTirageTarot {
difficulty: "0",
nbAdvantages: "0",
nbDisadvantages: "0",
+ tarotCards: options.tarotCards || [],
+ competenceModifier: options.competenceModifier || 0,
+ difficultyChoices: Object.fromEntries(Object.entries(SYSTEM.DIFFICULTY_CHOICES).map(([key, val]) => [key, val.label])),
}
const content = await foundry.applications.handlebars.renderTemplate("systems/fvtt-hamalron/templates/roll-dialog.hbs", dialogContext)
- const title = HamalronRoll.createTitle(options.rollType, options.rollTarget)
+ const title = HamalronTirageTarot.createTitle(options.rollType, options.rollTarget)
const label = game.i18n.localize("HAMALRON.Roll.roll")
+ const cancelLabel = game.i18n.localize("HAMALRON.Roll.cancel")
const rollContext = await foundry.applications.api.DialogV2.wait({
window: { title: title },
classes: ["fvtt-hamalron"],
+ position: { width: 420 },
content,
buttons: [
{
+ action: "cancel",
+ label: cancelLabel,
+ default: false,
+ },
+ {
+ action: "roll",
label: label,
+ default: true,
+ disabled: options.rollType === "competence",
callback: (event, button, dialog) => {
const output = Array.from(button.form.elements).reduce((obj, input) => {
if (input.name) obj[input.name] = input.value
return obj
}, {})
+ // Ajouter les données de sélection de carte pour les compétences
+ if (options.rollType === "competence") {
+ console.log("DEBUG CALLBACK: options.selectedCardId =", options.selectedCardId, "options.selectedCardValue =", options.selectedCardValue)
+ output.selectedCardId = options.selectedCardId
+ output.selectedCardValue = options.selectedCardValue
+ output.selectedDifficulty = options.selectedDifficulty
+ output.targetScore = options.targetScore
+ console.log("DEBUG CALLBACK: output =", output)
+ }
return output
},
},
@@ -96,11 +198,11 @@ export default class HamalronTirageTarot {
render: (event, dialog) => {
$(".roll-stat-advantages").change(event => {
options.nbAdvantages = Number(event.target.value)
- HamalronRoll.updateFullFormula(options)
+ HamalronTirageTarot.updateFullFormula(options)
})
$(".roll-stat-disadvantages").change(event => {
options.nbDisadvantages = Number(event.target.value)
- HamalronRoll.updateFullFormula(options)
+ HamalronTirageTarot.updateFullFormula(options)
})
$(".select-combat-option").change(event => {
let field = $(event.target).data("field")
@@ -110,14 +212,302 @@ export default class HamalronTirageTarot {
} else {
options.numericModifier -= modifier
}
- HamalronRoll.updateFullFormula(options)
+ HamalronTirageTarot.updateFullFormula(options)
})
+
+ // Gestion de la sélection de carte pour les compétences
+ if (options.rollType === "competence") {
+ let selectedCardId = null
+ options.selectedDifficulty = "soustension_oppose"
+ options.targetScore = null
+
+ // Calculer et afficher les valeurs pour chaque carte
+ const competenceSymbole = options.rollItem.system.carteSymbole
+ $(".tarot-card-select").each(function () {
+ const cardSymbole = $(this).data("card-symbole")
+ const cardValeur = $(this).data("card-valeur")
+ const cardType = $(this).data("card-type")
+
+ const valeurData = SYSTEM.TAROT_VALEURS[cardValeur]
+ const baseValue = valeurData ? valeurData.value : 0
+
+ let calculatedValue = 0
+ if (cardType === "atout") {
+ calculatedValue = baseValue
+ } else if (cardSymbole === competenceSymbole) {
+ calculatedValue = baseValue
+ } else {
+ calculatedValue = Math.ceil(baseValue / 2)
+ }
+
+ $(this).find(".card-values").text(`${baseValue} → ${calculatedValue}`)
+ })
+
+ // Gestion du changement de difficulté
+ $(".difficulty-select").change(function () {
+ const difficultyKey = $(this).val()
+ options.selectedDifficulty = difficultyKey
+ const difficultyData = SYSTEM.DIFFICULTY_CHOICES[difficultyKey]
+
+ if (difficultyData.standard === null) {
+ // Sous tension ou opposé - pas de score cible
+ options.targetScore = null
+ $("#target-score").text("-")
+ } else {
+ options.targetScore = difficultyData.standard
+ $("#target-score").text(options.targetScore)
+ }
+ })
+
+ $(".tarot-card-select").click(function () {
+ // Désélectionner toutes les cartes
+ $(".tarot-card-select").removeClass("selected")
+ // Sélectionner la carte cliquée
+ $(this).addClass("selected")
+
+ selectedCardId = $(this).data("card-id")
+ console.log("DEBUG CLICK: selectedCardId =", selectedCardId)
+ const cardSymbole = $(this).data("card-symbole")
+ const cardValeur = $(this).data("card-valeur")
+ const cardType = $(this).data("card-type")
+
+ // Calculer la valeur de la carte
+ const competenceSymbole = options.rollItem.system.carteSymbole
+ let cardValue = 0
+
+ // Récupérer la valeur numérique de la carte depuis TAROT_VALEURS
+ const valeurData = SYSTEM.TAROT_VALEURS[cardValeur]
+ const baseValue = valeurData ? valeurData.value : 0
+
+ if (cardType === "atout") {
+ // Si c'est un atout, prendre directement la valeur
+ cardValue = baseValue
+ } else if (cardSymbole === competenceSymbole) {
+ // Si le symbole correspond, prendre la valeur complète
+ cardValue = baseValue
+ } else {
+ // Sinon, diviser par 2 arrondi au supérieur
+ cardValue = Math.ceil(baseValue / 2)
+ }
+
+ // Stocker la carte sélectionnée et sa valeur calculée
+ options.selectedCardId = selectedCardId
+ options.selectedCardValue = cardValue
+ console.log("DEBUG CLICK END: options.selectedCardId =", options.selectedCardId, "options.selectedCardValue =", options.selectedCardValue)
+
+ // Mettre à jour l'affichage
+ $("#card-value-display").text(`+ ${cardValue}`)
+ $("#total-value").text(options.competenceModifier + cardValue)
+
+ // Activer le bouton de lancement
+ $("button[data-action='roll']").prop("disabled", false)
+ })
+
+ // Permettre de désélectionner en cliquant à nouveau
+ $(".tarot-card-select").dblclick(function () {
+ $(this).removeClass("selected")
+ options.selectedCardId = null
+ options.selectedCardValue = 0
+ $("#card-value-display").text("+ 0")
+ $("#total-value").text(options.competenceModifier)
+
+ // Désactiver le bouton de lancement
+ $("button[data-action='roll']").prop("disabled", true)
+ })
+ }
}
})
// If the user cancels the dialog, exit
if (rollContext === null) return
+ // Fusionner les données du dialogue dans options
+ Object.assign(options, rollContext)
+
+ // Gestion spéciale pour les compétences (pas de dés)
+ if (options.rollType === "competence") {
+ const totalValue = options.competenceModifier + (options.selectedCardValue || 0)
+
+ // Récupérer la carte sélectionnée si elle existe
+ let selectedCard = null
+ let cardSymboleMatch = false
+ let isAutomaticSuccess = false
+
+ if (options.selectedCardId) {
+ selectedCard = actor.items.get(options.selectedCardId)
+ if (selectedCard) {
+ cardSymboleMatch = selectedCard.system.symbole === options.rollItem.system.carteSymbole
+
+ // Vérifier si c'est une carte de succès (les atouts ne peuvent jamais être des cartes de succès)
+ if (actor.system.cartesSucces && selectedCard.system.type !== "atout") {
+ isAutomaticSuccess = Object.keys(actor.system.cartesSucces).some(symbole => {
+ const successCardData = actor.system.cartesSucces[symbole]
+ return selectedCard.system.symbole === symbole &&
+ selectedCard.system.valeur === successCardData.value.toString()
+ })
+ }
+ }
+ }
+
+ // Préparer les données pour le chat
+ const difficultyData = SYSTEM.DIFFICULTY_CHOICES[options.selectedDifficulty || "moyenne"]
+ const isSousTensionOppose = options.selectedDifficulty === "soustension_oppose"
+ const isSuccess = isAutomaticSuccess || totalValue > options.targetScore
+
+ // Détecter si la carte est un valet
+ const isValet = selectedCard?.system.valeur === "valet"
+
+ // Détecter si la carte est un cavalier
+ const isCavalier = selectedCard?.system.valeur === "cavalier"
+
+ // Détecter si la carte est une reine
+ const isReine = selectedCard?.system.valeur === "reine"
+
+ // Détecter si la carte est un roi
+ const isRoi = selectedCard?.system.valeur === "roi"
+
+ // Détecter si la carte est un atout
+ const isAtout = selectedCard?.system.type === "atout"
+
+ // Si c'est un cavalier et un échec, transformer en égalité
+ const isEquality = isCavalier && !isSuccess && !isSousTensionOppose
+
+ const chatData = {
+ cssClass: [SYSTEM.id, "competence-roll"].join(" "),
+ actingCharImg: options.actorImage,
+ actingCharName: options.actorName,
+ actorName: options.actorName,
+ competence: options.rollItem,
+ competenceModifier: options.competenceModifier,
+ selectedCard: selectedCard,
+ cardBonus: options.selectedCardValue || 0,
+ cardSymboleMatch: cardSymboleMatch,
+ totalValue: totalValue,
+ difficulty: difficultyData.label,
+ targetScore: options.targetScore,
+ isSuccess: isSuccess,
+ isAutomaticSuccess: isAutomaticSuccess,
+ isSousTensionOppose: isSousTensionOppose,
+ isValet: isValet,
+ isCavalier: isCavalier,
+ isReine: isReine,
+ isRoi: isRoi,
+ isAtout: isAtout,
+ isEquality: isEquality,
+ }
+
+ // Créer le message de chat
+ const content = await foundry.applications.handlebars.renderTemplate(
+ "systems/fvtt-hamalron/templates/chat-competence.hbs",
+ chatData
+ )
+
+ const messageData = {
+ user: game.user.id,
+ speaker: ChatMessage.getSpeaker({ actor }),
+ content: content,
+ style: CONST.CHAT_MESSAGE_STYLES.OTHER,
+ }
+
+ // Appliquer le mode de visibilité
+ ChatMessage.applyRollMode(messageData, rollContext.visibility)
+
+ await ChatMessage.create(messageData)
+
+ // Gérer la carte utilisée
+ console.log("DEBUG: selectedCard =", selectedCard, "options.selectedCardId =", options.selectedCardId)
+ if (selectedCard) {
+ console.log("Managing used card:", selectedCard.name)
+ // Supprimer la carte de l'acteur
+ const cardItem = actor.items.get(selectedCard.id)
+ if (cardItem) {
+ await actor.deleteEmbeddedDocuments("Item", [selectedCard.id])
+ console.log("Card deleted from actor")
+ }
+
+ // Récupérer le deck manager singleton
+ const module = await import("../applications/tarot-deck-manager.mjs")
+ const HamalronTarotDeckManager = module.default
+ let deckManager = HamalronTarotDeckManager._instance
+
+ // Si le deck manager n'existe pas, le créer
+ if (!deckManager) {
+ console.log("Deck manager not initialized, creating new instance...")
+ deckManager = new HamalronTarotDeckManager()
+ await deckManager.resetDeck()
+ }
+
+ console.log("Deck manager instance:", deckManager)
+
+ if (deckManager) {
+ console.log("Deck manager is available")
+ // Ajouter la carte à la défausse
+ deckManager.addToDiscard({
+ id: selectedCard.id,
+ name: selectedCard.name,
+ img: selectedCard.img,
+ symbole: selectedCard.system.symbole,
+ valeur: selectedCard.system.valeur,
+ type: selectedCard.system.type,
+ description: selectedCard.system.description,
+ })
+ console.log("Card added to discard")
+
+ // Tirer une nouvelle carte automatiquement
+ console.log("Attempting to draw new card. Deck length:", deckManager.deck.length)
+ if (deckManager.deck.length > 0) {
+ const newCards = deckManager.drawCards(1)
+ console.log("Cards drawn:", newCards)
+ if (newCards.length > 0) {
+ const newCard = newCards[0]
+ console.log("New card to add:", newCard)
+ // Trouver l'item tarot dans game.items
+ let originalItem = game.items.get(newCard.id)
+ console.log("Original item found by ID:", originalItem)
+
+ // Si pas trouvé dans game.items, chercher dans tous les items disponibles
+ if (!originalItem) {
+ console.log("Searching for card in game.items by properties...")
+ originalItem = game.items.find(i =>
+ i.type === "tarot" &&
+ i.name === newCard.name &&
+ i.system.symbole === newCard.symbole &&
+ i.system.valeur === newCard.valeur
+ )
+ console.log("Original item found by search:", originalItem)
+ }
+
+ if (originalItem) {
+ // Cas spécial : Le Mat
+ if (newCard.valeur === "lemat") {
+ console.log("Le Mat drawn! Executing special rules...")
+ await HamalronTirageTarot.handleLeMatEffect(actor, deckManager)
+ } else {
+ console.log("Creating embedded document for actor...")
+ await actor.createEmbeddedDocuments("Item", [originalItem.toObject()])
+ console.log("New card added to actor")
+ ui.notifications.info(`${game.i18n.localize("HAMALRON.Notifications.newCardDrawn")}: ${newCard.name}`)
+ }
+ } else {
+ console.warn("Original item not found for card:", newCard)
+ }
+ } else {
+ console.log("No cards were drawn (empty result)")
+ }
+ } else {
+ console.log("Deck is empty, cannot draw new card")
+ }
+
+ deckManager.saveDeckState()
+ deckManager.render()
+ ui.notifications.info(`${game.i18n.localize("HAMALRON.Notifications.cardUsed")}: ${selectedCard.name}`)
+ }
+ }
+
+ return null
+ }
+
+ // Code existant pour les autres types de jets
let rollData = foundry.utils.mergeObject(foundry.utils.duplicate(options), rollContext)
rollData.rollMode = rollContext.visibility
rollData.targetScore = 8
@@ -203,6 +593,8 @@ export default class HamalronTirageTarot {
return `${game.i18n.localize("HAMALRON.Label.titleStat")}`
case "weapon":
return `${game.i18n.localize("HAMALRON.Label.titleWeapon")}`
+ case "competence":
+ return `${game.i18n.localize("HAMALRON.Label.titleCompetence")}`
default:
return game.i18n.localize("HAMALRON.Label.titleStandard")
}
diff --git a/module/models/competence.mjs b/module/models/competence.mjs
index 2b06030..adb64da 100644
--- a/module/models/competence.mjs
+++ b/module/models/competence.mjs
@@ -6,9 +6,11 @@ export default class HamalronCompetence extends foundry.abstract.TypeDataModel {
const schema = {};
schema.description = new fields.HTMLField({ required: true, textSearch: true })
- schema.type = new fields.StringField({ required: true, initial: "generale", choices: Object.fromEntries(Object.entries(SYSTEM.COMPETENCE_TYPES).map(([key, val]) => [key, val.label])) });
+ schema.type = new fields.StringField({ required: true, initial: "commune", choices: Object.fromEntries(Object.entries(SYSTEM.COMPETENCE_TYPES).map(([key, val]) => [key, val.label])) });
schema.carteSymbole = new fields.StringField({ required: true, initial: "coupe", choices: Object.fromEntries(Object.entries(SYSTEM.TAROT_SYMBOLES).map(([key, val]) => [key, val.label])) });
- schema.niveau = new fields.NumberField({ required: true, initial: 0, min: 0, integer: true });
+ schema.niveau = new fields.StringField({ required: true, initial: "inexperimente", choices: Object.fromEntries(Object.entries(SYSTEM.NIVEAU_COMPETENCES).map(([key, val]) => [key, val.name])) });
+ schema.faction = new fields.StringField({ required: false, initial: "" });
+ schema.peuple = new fields.StringField({ required: false, initial: "" });
return schema;
}
diff --git a/module/utils.mjs b/module/utils.mjs
index 1f8902d..add78e9 100644
--- a/module/utils.mjs
+++ b/module/utils.mjs
@@ -128,6 +128,15 @@ export default class HamalronUtils {
Handlebars.registerHelper('add', function (a, b) {
return parseInt(a) + parseInt(b);
+ })
+
+ Handlebars.registerHelper('tarotValue', function (valeur) {
+ // Pour les valeurs numériques simples, retourner directement
+ const numValue = Number.parseInt(valeur);
+ if (!Number.isNaN(numValue)) return numValue;
+ // Pour les figures et atouts, récupérer depuis SYSTEM
+ const valeurData = SYSTEM.TAROT_VALEURS[valeur];
+ return valeurData ? valeurData.value : valeur;
});
Handlebars.registerHelper('mul', function (a, b) {
return parseInt(a) * parseInt(b);
@@ -169,7 +178,7 @@ export default class HamalronUtils {
return key === "creature" || key === "daemon";
})
Handlebars.registerHelper('getRomanLevel', function (level) {
- if (level=== "highpowers") return "High";
+ if (level === "highpowers") return "High";
if (level === "mastery") return "Mastery";
level = parseInt(level);
if (level === 0) return "0";
diff --git a/packs-system/hamalron-items/000004.log b/packs-system/hamalron-items/000004.log
deleted file mode 100644
index e69de29..0000000
diff --git a/packs-system/hamalron-items/CURRENT b/packs-system/hamalron-items/CURRENT
index 1a84852..32108be 100644
--- a/packs-system/hamalron-items/CURRENT
+++ b/packs-system/hamalron-items/CURRENT
@@ -1 +1 @@
-MANIFEST-000002
+MANIFEST-000016
diff --git a/packs-system/hamalron-items/LOG b/packs-system/hamalron-items/LOG
index 27bc993..68621cc 100644
--- a/packs-system/hamalron-items/LOG
+++ b/packs-system/hamalron-items/LOG
@@ -1,5 +1,7 @@
-2025/12/25-21:02:35.693464 7f01589ff6c0 Delete type=3 #1
-2025/12/25-23:05:15.035540 7f01427fc6c0 Level-0 table #5: started
-2025/12/25-23:05:15.035618 7f01427fc6c0 Level-0 table #5: 0 bytes OK
-2025/12/25-23:05:15.043074 7f01427fc6c0 Delete type=0 #3
-2025/12/25-23:05:15.054249 7f01427fc6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
+2026/01/02-10:10:10.253712 7f93ebfff6c0 Recovering log #15
+2026/01/02-10:10:10.307712 7f93ebfff6c0 Delete type=0 #15
+2026/01/02-10:10:10.307764 7f93ebfff6c0 Delete type=3 #14
+2026/01/02-20:13:00.317288 7f93e9ffb6c0 Level-0 table #19: started
+2026/01/02-20:13:00.317383 7f93e9ffb6c0 Level-0 table #19: 0 bytes OK
+2026/01/02-20:13:00.324182 7f93e9ffb6c0 Delete type=0 #17
+2026/01/02-20:13:00.343771 7f93e9ffb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
diff --git a/packs-system/hamalron-items/LOG.old b/packs-system/hamalron-items/LOG.old
new file mode 100644
index 0000000..9e33e46
--- /dev/null
+++ b/packs-system/hamalron-items/LOG.old
@@ -0,0 +1,3 @@
+2025/12/28-22:58:25.963740 7f4a83fff6c0 Recovering log #12
+2025/12/28-22:58:25.975413 7f4a83fff6c0 Delete type=3 #10
+2025/12/28-22:58:25.975552 7f4a83fff6c0 Delete type=0 #12
diff --git a/packs-system/hamalron-items/MANIFEST-000002 b/packs-system/hamalron-items/MANIFEST-000002
deleted file mode 100644
index 84678b8..0000000
Binary files a/packs-system/hamalron-items/MANIFEST-000002 and /dev/null differ
diff --git a/packs-system/hamalron-items/MANIFEST-000016 b/packs-system/hamalron-items/MANIFEST-000016
new file mode 100644
index 0000000..5fc379e
Binary files /dev/null and b/packs-system/hamalron-items/MANIFEST-000016 differ
diff --git a/styles/chat.less b/styles/chat.less
index 24bfa71..e7aca5b 100644
--- a/styles/chat.less
+++ b/styles/chat.less
@@ -1,87 +1,726 @@
-&.ask-roll {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.1);
-}
+.fvtt-hamalron {
+ &.ask-roll {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-family: var(--font-secondary);
+ font-size: calc(var(--font-size-standard) * 1.1);
+ }
-.hamalron-tarot-draw {
- padding: 0.5rem;
+ &.competence-roll {
+ background: #e8e8e8;
+ border: 2px solid #999;
+ border-radius: 0.5rem;
+ overflow: hidden;
- .tarot-draw-header {
- margin-bottom: 1rem;
+ .competence-roll-header {
+ background: rgba(255, 255, 255, 0.5);
+ padding: 0.5rem;
+ border-bottom: 2px solid #999;
- .tarot-draw-title {
+ .actor-info-compact {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+
+ .actor-avatar {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid #667eea;
+ object-fit: cover;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+ }
+
+ .actor-details {
+ flex: 1;
+
+ .competence-name {
+ margin: 0 0 0.25rem 0;
+ font-size: 1rem;
+ color: #667eea;
+ font-weight: bold;
+ }
+
+ .competence-meta {
+ display: flex;
+ gap: 0.75rem;
+ font-size: 0.75rem;
+ color: var(--color-text-dark-secondary);
+
+ .meta-item {
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+
+ i {
+ color: #667eea;
+ font-size: 0.75rem;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .competence-roll-body {
+ padding: 0.5rem;
+
+ .card-used-section {
+ background: rgba(102, 126, 234, 0.1);
+ border: 1px solid rgba(102, 126, 234, 0.4);
+ border-radius: 0.35rem;
+ padding: 0.4rem;
+ margin-bottom: 0.5rem;
+
+ .card-used-label {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.75rem;
+ font-weight: bold;
+ color: #4a5fc1;
+ margin-bottom: 0.35rem;
+
+ i {
+ font-size: 0.75rem;
+ }
+ }
+
+ .card-used-content {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+
+ .card-thumbnail {
+ width: 40px;
+ height: 40px;
+ border-radius: 0.25rem;
+ border: 1px solid rgba(102, 126, 234, 0.5);
+ object-fit: cover;
+ }
+
+ .card-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+
+ .card-name {
+ font-weight: bold;
+ color: var(--color-text-dark-primary);
+ }
+
+ .card-match {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.75rem;
+ font-style: italic;
+
+ &.match-success {
+ color: #2ecc71;
+ i {
+ color: #2ecc71;
+ }
+ }
+
+ &.match-partial {
+ color: #f39c12;
+ i {
+ color: #f39c12;
+ }
+ }
+
+ &.match-atout {
+ color: #9b59b6;
+ font-weight: bold;
+ i {
+ color: #9b59b6;
+ }
+ }
+
+ i {
+ font-size: 0.7rem;
+ }
+ }
+
+ // Styles pour les règles spéciales des cartes
+ .valet-special-rule,
+ .cavalier-special-rule,
+ .reine-special-rule,
+ .roi-special-rule {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ font-size: 0.75rem;
+ font-weight: bold;
+ padding: 0.3rem 0.4rem;
+ border-radius: 0.25rem;
+ background: rgba(255, 193, 7, 0.15);
+ border-left: 3px solid #ffc107;
+ color: #856404;
+ margin-top: 0.2rem;
+
+ i {
+ font-size: 0.8rem;
+ color: #ffc107;
+ }
+ }
+ }
+ }
+ }
+
+ .calculation-section {
+ background: rgba(0, 0, 0, 0.05);
+ border-radius: 0.35rem;
+ padding: 0.4rem;
+ margin-bottom: 0.5rem;
+
+ .calculation-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.2rem 0;
+ font-size: 0.8rem;
+
+ .calc-label {
+ color: var(--color-text-dark-secondary);
+ }
+
+ .calc-value {
+ font-weight: bold;
+ font-size: 0.9rem;
+ color: var(--color-text-dark-primary);
+
+ &.calc-bonus {
+ color: #2ecc71;
+ }
+
+ &.calc-total {
+ font-size: 1.1rem;
+ color: #667eea;
+ }
+ }
+
+ &.total-row {
+ padding-top: 0.3rem;
+ }
+ }
+
+ .calculation-divider {
+ height: 1px;
+ background: var(--color-border-dark);
+ margin: 0.4rem 0;
+ }
+ }
+
+ .difficulty-section {
+ .difficulty-info {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.4rem;
+ background: rgba(0, 0, 0, 0.05);
+ border-radius: 0.35rem;
+ font-size: 0.8rem;
+
+ i {
+ color: #f39c12;
+ }
+
+ .difficulty-label {
+ color: var(--color-text-dark-primary);
+ font-weight: 500;
+ }
+
+ .difficulty-target {
+ margin-left: auto;
+ color: var(--color-text-dark-secondary);
+
+ strong {
+ color: var(--color-text-dark-primary);
+ font-size: 1rem;
+ }
+ }
+ }
+ }
+ }
+
+ .competence-roll-footer {
display: flex;
+ flex-direction: column;
align-items: center;
+ justify-content: center;
gap: 0.5rem;
- margin: 0;
- padding-bottom: 0.5rem;
- border-bottom: 2px solid var(--color-border-dark);
- font-size: 1.25rem;
- color: var(--color-text-dark-primary);
+ padding: 0.5rem;
+ font-size: 1.1rem;
+ font-weight: bold;
+ border-top: 2px solid #999;
- i {
- color: #667eea;
+ .automatic-success-banner {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ width: 100%;
+ padding: 0.5rem;
+ background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
+ color: #8b6914;
+ font-size: 0.95rem;
+ font-weight: bold;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ border-radius: 0.25rem;
+ box-shadow: 0 2px 8px rgba(255, 215, 0, 0.4);
+ animation: pulse-banner 2s ease-in-out infinite;
+
+ i {
+ color: #8b6914;
+ text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
+ }
+ }
+
+ &.result-success {
+ background: rgba(46, 204, 113, 0.2);
+ color: #2ecc71;
+
+ .result-icon i {
+ color: #2ecc71;
+ }
+ }
+
+ &.result-failure {
+ background: rgba(234, 102, 102, 0.2);
+ color: #ea6666;
+
+ .result-icon i {
+ color: #ea6666;
+ }
+ }
+
+ &.gm-only-buttons {
+ background: rgba(102, 126, 234, 0.1);
+ padding: 0.75rem;
+
+ .special-rules-section {
+ background: rgba(255, 193, 7, 0.15);
+ border: 2px solid #ffc107;
+ border-radius: 0.35rem;
+ padding: 0.5rem;
+ margin-bottom: 0.75rem;
+
+ .special-rule-item {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ padding: 0.3rem 0;
+ font-weight: bold;
+ color: #856404;
+
+ &:not(:last-child) {
+ border-bottom: 1px solid rgba(255, 193, 7, 0.3);
+ margin-bottom: 0.3rem;
+ padding-bottom: 0.4rem;
+ }
+
+ i {
+ font-size: 0.9rem;
+ color: #ffc107;
+ }
+
+ strong {
+ color: #6c5400;
+ }
+ }
+ }
+
+ .gm-buttons {
+ display: flex;
+ gap: 0.75rem;
+ width: 100%;
+
+ button {
+ flex: 1;
+ padding: 0.5rem 1rem;
+ border: 2px solid #667eea;
+ border-radius: 0.35rem;
+ background: white;
+ color: #667eea;
+ font-weight: bold;
+ font-size: 0.9rem;
+ cursor: pointer;
+ transition: all 0.2s;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+
+ i {
+ font-size: 0.85rem;
+ }
+
+ &:hover {
+ background: #667eea;
+ color: white;
+ transform: translateY(-1px);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ }
+
+ &.sous-tension-btn {
+ border-color: #f39c12;
+ color: #f39c12;
+
+ &:hover {
+ background: #f39c12;
+ color: white;
+ }
+ }
+
+ &.oppose-btn {
+ border-color: #e74c3c;
+ color: #e74c3c;
+
+ &:hover {
+ background: #e74c3c;
+ color: white;
+ }
+ }
+ }
+ }
+ }
+
+ .result-icon {
+ font-size: 1.2rem;
+ }
+
+ .result-text {
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
}
}
}
- .tarot-draw-content {
- display: flex;
- gap: 1rem;
+ &.hamalron-tarot-draw {
+ padding: 0.5rem;
- .tarot-card-image {
- flex-shrink: 0;
+ .tarot-draw-header {
+ margin-bottom: 1rem;
- img {
- width: 150px;
- height: 150px;
- object-fit: cover;
- border-radius: 0.25rem;
- border: 2px solid var(--color-border-dark);
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+ .tarot-draw-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ margin: 0;
+ padding-bottom: 0.5rem;
+ border-bottom: 2px solid var(--color-border-dark);
+ font-size: 1.25rem;
+ color: var(--color-text-dark-primary);
+
+ i {
+ color: #667eea;
+ }
}
}
- .tarot-card-details {
- flex: 1;
+ .tarot-draw-content {
display: flex;
- flex-direction: column;
- gap: 0.5rem;
+ gap: 1rem;
- .tarot-detail-row {
- display: flex;
- gap: 0.5rem;
+ .tarot-card-image {
+ flex-shrink: 0;
- .detail-label {
- font-weight: bold;
- color: var(--color-text-dark-secondary);
- }
-
- .detail-value {
- color: var(--color-text-dark-primary);
+ img {
+ width: 150px;
+ height: 150px;
+ object-fit: cover;
+ border-radius: 0.25rem;
+ border: 2px solid var(--color-border-dark);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
}
- .tarot-description {
- margin-top: 0.5rem;
- padding-top: 0.5rem;
- border-top: 1px solid var(--color-border-dark);
+ .tarot-card-details {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ .tarot-detail-row {
+ display: flex;
+ gap: 0.5rem;
+
+ .detail-label {
+ font-weight: bold;
+ color: var(--color-text-dark-secondary);
+ }
+
+ .detail-value {
+ color: var(--color-text-dark-primary);
+ }
+ }
+
+ .tarot-description {
+ margin-top: 0.5rem;
+ padding-top: 0.5rem;
+ border-top: 1px solid var(--color-border-dark);
+
+ .description-label {
+ font-weight: bold;
+ color: var(--color-text-dark-secondary);
+ margin-bottom: 0.25rem;
+ }
+
+ .description-content {
+ color: var(--color-text-dark-primary);
+ font-style: italic;
+ }
+ }
+ }
+ }
+ }
+
+ &.tarot-draw-chat {
+ background: #e8e8e8;
+ border: 2px solid #999;
+ border-radius: 0.5rem;
+ overflow: hidden;
+
+ .tarot-draw-header {
+ background: rgba(255, 255, 255, 0.5);
+ padding: 0.5rem;
+ border-bottom: 2px solid #999;
+
+ .draw-info-compact {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+
+ .card-thumbnail {
+ width: 60px;
+ height: 60px;
+ border-radius: 0.25rem;
+ object-fit: cover;
+ border: 2px solid #999;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
+ }
+
+ .card-details {
+ flex: 1;
+
+ .card-name {
+ margin: 0 0 0.25rem 0;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .card-meta {
+ display: flex;
+ gap: 0.75rem;
+ flex-wrap: wrap;
+ font-size: 0.75rem;
+
+ .meta-item {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ color: #666;
+
+ i {
+ color: #999;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .tarot-draw-body {
+ padding: 0.5rem;
+
+ .description-section {
.description-label {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ font-size: 0.8rem;
font-weight: bold;
- color: var(--color-text-dark-secondary);
- margin-bottom: 0.25rem;
+ color: #666;
+ margin-bottom: 0.4rem;
+
+ i {
+ color: #999;
+ }
}
.description-content {
- color: var(--color-text-dark-primary);
+ font-size: 0.85rem;
+ color: #555;
font-style: italic;
+ line-height: 1.4;
+ padding: 0.4rem;
+ background: rgba(255, 255, 255, 0.3);
+ border-radius: 0.25rem;
+ border-left: 3px solid #999;
+ }
+ }
+ }
+ }
+
+ &.tarot-tension-chat {
+ background: #e8e8e8;
+ border: 2px solid #999;
+ border-radius: 0.5rem;
+ overflow: hidden;
+
+ .tarot-tension-header {
+ background: rgba(255, 165, 0, 0.2);
+ padding: 0.5rem;
+ border-bottom: 2px solid #f39c12;
+
+ .tension-info-compact {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+
+ .card-thumbnail {
+ width: 60px;
+ height: 60px;
+ border-radius: 0.25rem;
+ object-fit: cover;
+ border: 2px solid #f39c12;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
+ }
+
+ .card-details {
+ flex: 1;
+
+ .card-name {
+ margin: 0 0 0.25rem 0;
+ font-size: 1rem;
+ font-weight: bold;
+ color: #333;
+ }
+
+ .card-meta {
+ display: flex;
+ gap: 0.75rem;
+ flex-wrap: wrap;
+ font-size: 0.75rem;
+
+ .meta-item {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ color: #666;
+
+ i {
+ color: #f39c12;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .tarot-tension-body {
+ padding: 0.5rem;
+
+ .difficulty-section {
+ margin-bottom: 0.75rem;
+ padding: 0.5rem;
+ background: rgba(243, 156, 18, 0.1);
+ border-left: 3px solid #f39c12;
+ border-radius: 0.25rem;
+
+ .difficulty-label {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ font-size: 0.75rem;
+ font-weight: bold;
+ color: #666;
+ margin-bottom: 0.25rem;
+
+ i {
+ color: #f39c12;
+ }
+ }
+
+ .difficulty-value {
+ font-size: 0.9rem;
+ font-weight: bold;
+ color: #333;
+ }
+ }
+
+ .calculation-section {
+ .calculation-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.3rem 0.5rem;
+ margin-bottom: 0.25rem;
+ background: rgba(255, 255, 255, 0.3);
+ border-radius: 0.25rem;
+
+ .calc-label {
+ font-size: 0.8rem;
+ color: #666;
+ }
+
+ .calc-value {
+ font-size: 0.85rem;
+ font-weight: bold;
+ color: #333;
+
+ &.positive {
+ color: #27ae60;
+ }
+
+ &.negative {
+ color: #e74c3c;
+ }
+ }
+ }
+
+ .calculation-total {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.5rem;
+ margin-top: 0.5rem;
+ background: rgba(243, 156, 18, 0.15);
+ border: 2px solid #f39c12;
+ border-radius: 0.25rem;
+
+ .total-label {
+ font-size: 0.85rem;
+ font-weight: bold;
+ color: #666;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ }
+
+ .total-value {
+ font-size: 1.25rem;
+ font-weight: bold;
+ color: #f39c12;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+ }
}
}
}
}
}
+
+@keyframes pulse-banner {
+ 0%,
+ 100% {
+ box-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
+ }
+ 50% {
+ box-shadow: 0 0 20px rgba(255, 215, 0, 0.8);
+ }
+}
diff --git a/styles/fonts.less b/styles/fonts.less
index bcf315a..a6324bb 100644
--- a/styles/fonts.less
+++ b/styles/fonts.less
@@ -1,9 +1,9 @@
@font-face {
- font-family: "MinionProRegular";
- src: url("../assets/fonts/Minion Pro Regular.ttf") format("truetype");
+ font-family: "TimesNewRoman";
+ src: url("../assets/fonts/Times New Roman.ttf") format("truetype");
}
@font-face {
- font-family: "SupernaturalKnight";
- src: url("../assets/fonts/Supernatural_Knight.ttf") format("truetype");
+ font-family: "EagleLake";
+ src: url("../assets/fonts/EagleLake-Regular.ttf") format("truetype");
}
diff --git a/styles/fvtt-hamalron.less b/styles/fvtt-hamalron.less
index 37bd11f..c5e911d 100644
--- a/styles/fvtt-hamalron.less
+++ b/styles/fvtt-hamalron.less
@@ -16,8 +16,8 @@
@import "region.less";
@import "sortilege.less";
@import "tarot.less";
- @import "tarot-deck-manager.less";
- @import "chat.less";
}
+@import "chat.less";
@import "roll.less";
+@import "tarot-deck-manager.less";
diff --git a/styles/global.less b/styles/global.less
index 0872135..873e342 100644
--- a/styles/global.less
+++ b/styles/global.less
@@ -2,22 +2,25 @@
--font-size-standard: 0.9rem;
--font-size-result: 1.4rem;
--background-image-base: url("../assets/ui/sheet_background_01.webp");
- --font-primary: "MinionProRegular";
- --font-secondary: "MinionProRegular";
- --font-title: "SupernaturalKnight";
+ --font-primary: "TimesNewRoman";
+ --font-secondary: "TimesNewRoman";
+ --font-title: "EagleLake";
--logo-standard: url("../assets/ui/pentagram_logo.webp");
- --title-color: #c9a876;
+ --title-color: #dea60b;
--background-box: #e0dcdc;
--color-success: rgb(15, 122, 15);
--color-failure: #8b7355;
--color-warning: darkorange;
--color-critical-success: rgb(21, 39, 204);
--color-critical-failure: rgb(141, 32, 231);
+ --color-sheet-nav: #120c04;
+ --input-height: 1.2rem;
}
body {
--color-light-1: rgba(182, 178, 178, 0.6);
--color-warm-1: #c9a876;
+ --input-height: 1.4rem;
}
#logo {
diff --git a/styles/mixins.less b/styles/mixins.less
index 7d625b0..545a19c 100644
--- a/styles/mixins.less
+++ b/styles/mixins.less
@@ -48,8 +48,8 @@
}
legend {
- font-family: var(--font-secondary);
- font-size: calc(var(--font-size-standard) * 1.2);
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
font-weight: bold;
letter-spacing: 1px;
}
diff --git a/styles/personnage-tarot.less b/styles/personnage-tarot.less
index 1cfe704..7362900 100644
--- a/styles/personnage-tarot.less
+++ b/styles/personnage-tarot.less
@@ -1,6 +1,6 @@
-.personnage {
+.character-content {
.tarot-hand-container {
- padding: 1rem;
+ padding: 0.3rem;
height: 100%;
display: flex;
flex-direction: column;
@@ -9,8 +9,8 @@
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 1.5rem;
- padding-bottom: 0.75rem;
+ margin-bottom: 0.2rem;
+ padding-bottom: 0.2rem;
border-bottom: 2px solid var(--color-border-dark);
h2 {
@@ -20,47 +20,135 @@
}
.tarot-hand-info {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+
.card-count {
display: flex;
align-items: center;
- gap: 0.5rem;
- padding: 0.5rem 1rem;
+ gap: 0.3rem;
+ padding: 0.3rem 0.6rem;
background: rgba(102, 126, 234, 0.2);
border-radius: 0.25rem;
border: 1px solid rgba(102, 126, 234, 0.4);
font-weight: bold;
+ font-size: 0.85rem;
color: var(--color-text-light-heading);
i {
color: #667eea;
}
+
+ &.over-limit {
+ background: rgba(234, 102, 102, 0.2);
+ border-color: rgba(234, 102, 102, 0.4);
+
+ i {
+ color: #ea6666;
+ }
+ }
+ }
+
+ .hand-warning {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 1rem;
+ background: rgba(234, 179, 8, 0.2);
+ border-radius: 0.25rem;
+ border: 1px solid rgba(234, 179, 8, 0.4);
+ color: #eab308;
+ font-weight: bold;
+ animation: pulse 2s ease-in-out infinite;
+
+ i {
+ color: #eab308;
+ }
+ }
+
+ @keyframes pulse {
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.7;
+ }
}
}
}
.tarot-hand-cards {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
- gap: 1.5rem;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.3rem;
overflow-y: auto;
- padding-right: 0.5rem;
+ padding: 0.2rem;
+ justify-content: center;
+ align-items: flex-start;
.tarot-card-wrapper {
perspective: 1000px;
cursor: grab;
+ flex-shrink: 0;
+ position: relative;
&:active {
cursor: grabbing;
}
+ &.success-card {
+ .tarot-card {
+ .tarot-card-inner {
+ .tarot-card-front {
+ border: 3px solid #ffd700;
+ box-shadow:
+ 0 0 15px rgba(255, 215, 0, 0.6),
+ 0 4px 8px rgba(0, 0, 0, 0.3);
+ }
+ }
+ }
+
+ .tarot-card-controls {
+ .success-indicator {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: rgba(255, 215, 0, 0.9);
+ color: #8b6914;
+ animation: pulse-gold 2s ease-in-out infinite;
+
+ i {
+ font-size: 0.7rem;
+ }
+ }
+ }
+ }
+
+ &.selected {
+ .tarot-card {
+ border: 2px solid #667eea;
+ box-shadow: 0 0 20px rgba(102, 126, 234, 0.6);
+ }
+
+ .card-actions {
+ display: flex !important;
+ }
+ }
+
.tarot-card {
position: relative;
- width: 100%;
- height: 400px;
+ width: 110px;
+ height: 190px;
transition: transform 0.3s ease;
&:hover {
- transform: translateY(-5px);
+ transform: translateY(-10px) scale(1.05);
+ z-index: 10;
}
.tarot-card-inner {
@@ -83,57 +171,55 @@
border-radius: 0.5rem;
display: flex;
flex-direction: column;
- padding: 0.75rem;
+ padding: 0.4rem;
.tarot-card-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 0.75rem;
-
- .tarot-card-name {
- margin: 0;
- font-size: 1.1rem;
- font-weight: bold;
- color: #667eea;
- flex: 1;
- line-height: 1.3;
- }
+ position: absolute;
+ top: 0.25rem;
+ right: 0.25rem;
+ z-index: 2;
.tarot-card-controls {
display: flex;
gap: 0.25rem;
+ opacity: 0;
+ transition: opacity 0.2s ease;
.card-control {
display: flex;
align-items: center;
justify-content: center;
- width: 24px;
- height: 24px;
- border-radius: 0.25rem;
- background: rgba(0, 0, 0, 0.3);
- color: var(--color-text-light-heading);
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: rgba(0, 0, 0, 0.7);
+ color: white;
transition: all 0.2s ease;
- &:hover {
- background: rgba(102, 126, 234, 0.5);
- color: white;
+ &.delete-control:hover {
+ background: rgba(234, 102, 102, 0.9);
+ }
+
+ &.view-control:hover {
+ background: rgba(102, 126, 234, 0.9);
}
i {
- font-size: 0.75rem;
+ font-size: 0.7rem;
}
}
}
}
+ &:hover .tarot-card-header .tarot-card-controls {
+ opacity: 1;
+ }
+
.tarot-card-image {
width: 100%;
- height: 150px;
- margin-bottom: 0.75rem;
- border-radius: 0.25rem;
+ height: 125px;
+ border-radius: 0.25rem 0.25rem 0 0;
overflow: hidden;
- border: 1px solid var(--color-border-dark);
background: rgba(0, 0, 0, 0.3);
img {
@@ -143,37 +229,44 @@
}
}
+ .tarot-card-name {
+ padding: 0.5rem;
+ background: rgba(0, 0, 0, 0.3);
+ border-bottom: 1px solid var(--color-border-dark);
+
+ h4 {
+ margin: 0;
+ font-size: 0.85rem;
+ font-weight: bold;
+ color: #667eea;
+ text-align: center;
+ line-height: 1.2;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ }
+
.tarot-card-info {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
- margin-bottom: 0.75rem;
+ padding: 0.5rem;
+ background: rgba(0, 0, 0, 0.2);
- .card-info-row {
+ .card-info-compact {
display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 0.4rem 0.5rem;
- background: rgba(0, 0, 0, 0.2);
- border-radius: 0.25rem;
- font-size: 0.875rem;
+ flex-direction: column;
+ gap: 0.4rem;
+ font-size: 0.75rem;
- .info-label {
+ .card-symbole {
display: flex;
align-items: center;
- gap: 0.35rem;
- color: var(--color-text-dark-secondary);
- font-weight: 500;
+ gap: 0.3rem;
+ font-weight: bold;
+ justify-content: center;
i {
- font-size: 0.75rem;
- opacity: 0.7;
+ font-size: 0.6rem;
}
- }
-
- .info-value {
- color: var(--color-text-light-heading);
- font-weight: bold;
&.symbole-coupe {
color: #3498db;
@@ -191,46 +284,84 @@
color: #2ecc71;
}
}
+
+ .card-valeur {
+ text-align: center;
+ color: #ffffff;
+ font-weight: bold;
+ font-size: 1rem;
+ background: rgba(0, 0, 0, 0.4);
+ padding: 0.3rem 0.5rem;
+ border-radius: 0.25rem;
+ }
}
- }
- .tarot-card-description {
- flex: 1;
- overflow-y: auto;
- padding: 0.5rem;
- background: rgba(0, 0, 0, 0.2);
- border-radius: 0.25rem;
- border: 1px solid var(--color-border-dark);
+ .card-actions {
+ display: none;
+ margin-top: 0.5rem;
- .description-text {
- font-size: 0.8rem;
- line-height: 1.4;
- color: var(--color-text-dark-primary);
+ .discard-and-draw-button {
+ width: 100%;
+ padding: 0.5rem;
+ background: rgba(102, 126, 234, 0.3);
+ border: 1px solid rgba(102, 126, 234, 0.6);
+ border-radius: 0.25rem;
+ color: #9ab4ff;
+ font-size: 0.75rem;
+ font-weight: bold;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.3rem;
- p {
- margin: 0 0 0.5rem 0;
+ i {
+ font-size: 0.7rem;
+ }
- &:last-child {
- margin-bottom: 0;
+ &:hover {
+ background: rgba(102, 126, 234, 0.5);
+ border-color: rgba(102, 126, 234, 0.8);
+ color: #aac4ff;
+ transform: translateY(-1px);
+ }
+
+ &:active {
+ transform: translateY(0);
}
}
}
- &::-webkit-scrollbar {
- width: 4px;
- }
+ .discard-button {
+ margin-top: 0.5rem;
+ padding: 0.4rem 0.5rem;
+ background: rgba(234, 102, 102, 0.3);
+ border: 1px solid rgba(234, 102, 102, 0.6);
+ border-radius: 0.25rem;
+ color: #ea6666;
+ font-size: 0.7rem;
+ font-weight: bold;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.3rem;
- &::-webkit-scrollbar-track {
- background: rgba(0, 0, 0, 0.2);
- border-radius: 2px;
- }
-
- &::-webkit-scrollbar-thumb {
- background: rgba(102, 126, 234, 0.5);
- border-radius: 2px;
+ i {
+ font-size: 0.65rem;
+ }
&:hover {
- background: rgba(102, 126, 234, 0.7);
+ background: rgba(234, 102, 102, 0.5);
+ border-color: rgba(234, 102, 102, 0.8);
+ color: #ff6666;
+ transform: translateY(-1px);
+ }
+
+ &:active {
+ transform: translateY(0);
}
}
}
diff --git a/styles/personnage.less b/styles/personnage.less
index e84f5ed..d9ac297 100644
--- a/styles/personnage.less
+++ b/styles/personnage.less
@@ -6,11 +6,17 @@
.sheet-tabs {
background-color: var(--color-light-1);
+ font-family: var(--font-title);
+
+ a {
+ color: var(--color-sheet-nav);
+ font-size: 0.9rem;
+ }
}
.character-main {
- /*background-color: var(--color-light-1);*/
display: flex;
+ justify-content: center;
.character-pc {
display: flex;
@@ -18,7 +24,7 @@
flex: 1;
.character-left {
- min-width: 180px;
+ min-width: 220px;
display: flex;
flex-direction: column;
@@ -62,15 +68,9 @@
.character-right {
display: flex;
flex-direction: column;
- gap: 5px;
+ gap: 2px;
.character-definition {
- .character-definition-pronouns {
- input {
- min-width: 21.2rem;
- max-width: 21.2rem;
- }
- }
.form-group {
display: flex;
align-items: center;
@@ -97,6 +97,32 @@
margin-right: 1rem;
margin-bottom: auto;
}
+ .item-controls {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ flex: 1;
+
+ .item-name {
+ flex: 1;
+ min-width: 0;
+ }
+
+ .control {
+ flex-shrink: 0;
+ cursor: pointer;
+ opacity: 0.7;
+ transition: opacity 0.2s;
+
+ &:hover {
+ opacity: 1;
+ }
+
+ i {
+ font-size: 0.9rem;
+ }
+ }
+ }
}
.character-name {
display: flex;
@@ -113,40 +139,146 @@
}
.character-pc-play {
- min-width: 500px;
+ min-width: 660px;
}
.character-pc-edit {
- min-width: 500px;
+ min-width: 660px;
}
.character-stats {
/*background-color: var(--color-light-1);*/
display: flex;
flex-direction: column;
- gap: 5px;
+ gap: 2px;
flex: 1;
+ .stats-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.2rem;
+ }
+
.character-stat {
display: flex;
align-items: center;
- .icon-stat {
- width: 24px;
- height: 24px;
- margin-right: 4px;
+ justify-content: space-between;
+ gap: 0.2rem;
+ padding: 0.1rem 0.2rem;
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
+
+ .stat-label {
+ flex: 1;
+ min-width: 0;
+
+ &.rollable:hover,
+ &.rollable:focus {
+ text-shadow: 0 0 8px var(--color-shadow-primary);
+ cursor: pointer;
+ }
+
+ i {
+ margin-right: 0.25rem;
+ }
}
- .rollable:hover,
- .rollable:focus {
- text-shadow: 0 0 8px var(--color-shadow-primary);
- cursor: pointer;
+
+ .stat-values {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ flex-shrink: 0;
+
+ input {
+ width: 3rem;
+ text-align: center;
+ }
+
+ .stat-value {
+ width: 3rem;
+ text-align: center;
+ display: inline-block;
+ }
+
+ .separator {
+ font-weight: bold;
+ color: var(--color-text-dark-secondary);
+ }
}
- .rollable {
- min-width: 3.5rem;
- max-width: 3.5rem;
+ }
+ }
+
+ .character-resistances {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ flex: 1;
+
+ .resistances-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.2rem;
+ }
+
+ .resistance-stat {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.2rem;
+ padding: 0.1rem 0.2rem;
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
+
+ .stat-label {
+ flex: 1;
+ min-width: 0;
}
- input {
- min-width: 2.5rem;
- max-width: 2.5rem;
+
+ .stat-values {
+ display: flex;
+ align-items: center;
+ gap: 0.2rem;
+ flex-shrink: 0;
+
+ input {
+ width: 3rem;
+ text-align: center;
+ }
+
+ .stat-value {
+ width: 3rem;
+ text-align: center;
+ display: inline-block;
+ }
+
+ .resistance-control {
+ cursor: pointer;
+ opacity: 0.8;
+ transition: all 0.2s ease;
+ padding: 0.15rem 0.35rem;
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 3px;
+ color: var(--color-text-dark-primary);
+
+ &:hover {
+ opacity: 1;
+ background: rgba(0, 100, 200, 0.2);
+ transform: scale(1.1);
+ }
+
+ &:active {
+ transform: scale(0.95);
+ }
+
+ i {
+ font-size: 0.7rem;
+ }
+ }
+
+ .separator {
+ font-weight: bold;
+ color: var(--color-text-dark-secondary);
+ }
}
}
}
@@ -160,16 +292,145 @@
}
}
-.tab.character-status .main-div {
+.tab.character-competences .main-div {
/*background-color: var(--color-light-1);*/
display: grid;
grid-template-columns: 1fr;
+ gap: 8px;
legend {
a {
font-size: calc(var(--font-size-standard) * 1.4);
padding-left: 5px;
}
}
+
+ .competences-group {
+ margin-bottom: 12px;
+ background: rgba(0, 0, 0, 0.03);
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: 4px;
+ padding: 8px;
+
+ .competences-type-header {
+ font-weight: bold;
+ font-size: calc(var(--font-size-standard) * 1.1);
+ color: var(--color-text-dark-primary);
+ margin-bottom: 8px;
+ padding: 4px 8px;
+ border-left: 3px solid var(--color-border-dark-primary);
+ }
+ }
+
+ .competences {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 6px;
+
+ .competence {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 6px;
+ background: rgba(255, 255, 255, 0.6);
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: 3px;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: rgba(255, 255, 255, 0.9);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+
+ .item-img {
+ width: 28px;
+ height: 28px;
+ border-radius: 3px;
+ flex-shrink: 0;
+ }
+
+ .name {
+ flex: 1;
+ min-width: 0;
+ font-weight: 500;
+
+ a {
+ color: var(--color-text-dark-primary);
+ text-decoration: none;
+ cursor: pointer;
+
+ &:hover {
+ color: var(--color-text-hyperlink);
+ text-decoration: underline;
+ }
+ }
+ }
+
+ .carte {
+ font-size: 0.85rem;
+ padding: 2px 6px;
+ background: rgba(0, 0, 0, 0.08);
+ border-radius: 3px;
+ white-space: nowrap;
+ }
+
+ .niveau {
+ font-size: 0.85rem;
+ padding: 2px 6px;
+ background: rgba(0, 100, 200, 0.1);
+ color: var(--color-text-dark-primary);
+ border-radius: 3px;
+ white-space: nowrap;
+ font-weight: 500;
+ }
+
+ .controls {
+ display: flex;
+ gap: 4px;
+ font-size: 0.85rem;
+ flex-shrink: 0;
+
+ a {
+ padding: 2px 4px;
+ color: var(--color-text-dark-secondary);
+ cursor: pointer;
+ transition: color 0.2s ease;
+
+ &:hover {
+ color: var(--color-text-dark-primary);
+ }
+ }
+ }
+ }
+ }
+
+ .add-competence-section {
+ text-align: center;
+ padding: 12px;
+
+ .add-competence-button {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 16px;
+ background: rgba(0, 100, 200, 0.1);
+ border: 1px solid rgba(0, 100, 200, 0.3);
+ border-radius: 4px;
+ color: var(--color-text-dark-primary);
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: rgba(0, 100, 200, 0.2);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+
+ i {
+ font-size: 1rem;
+ }
+ }
+ }
+
.mortality {
display: flex;
align-items: center;
@@ -227,53 +488,9 @@
}
}
}
- .perks {
- display: grid;
- grid-template-columns: repeat(1, 1fr);
- gap: 4px;
- .perk {
- display: flex;
- align-items: center;
- gap: 4px;
- margin-left: 4px;
- min-width: 20rem;
- max-width: 20rem;
- .rollable:hover,
- .rollable:focus {
- text-shadow: 0 0 8px var(--color-shadow-primary);
- cursor: pointer;
- }
- .controls {
- font-size: 0.7rem;
- min-width: 1.8rem;
- max-width: 1.8rem;
- }
- .flavor {
- min-width: 24rem;
- max-width: 24rem;
- }
- .role {
- min-width: 5rem;
- max-width: 5rem;
- }
- .level {
- min-width: 4rem;
- max-width: 4rem;
- }
- .name {
- min-width: 10rem;
- max-width: 10rem;
- }
- .item-img {
- width: 24px;
- height: 24px;
- margin: 4px 0 0 0;
- }
- }
- }
}
-.tab.character-maleficas .main-div {
+.tab.character-sortileges .main-div {
/*background-color: var(--color-light-1);*/
display: grid;
grid-template-columns: 1fr;
@@ -284,7 +501,7 @@
}
}
- .maleficas {
+ .sortileges {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
@@ -322,49 +539,6 @@
}
}
}
-
- .rituals {
- display: grid;
- grid-template-columns: repeat(1, 1fr);
- gap: 4px;
- .ritual {
- display: flex;
- align-items: center;
- gap: 4px;
- min-width: 14rem;
- max-width: 14rem;
- .controls {
- font-size: 0.7rem;
- min-width: 1.8rem;
- max-width: 1.8rem;
- }
- .ingredients {
- min-width: 24rem;
- max-width: 24rem;
- }
- .name {
- min-width: 12rem;
- max-width: 12rem;
- }
- .difficulty {
- min-width: 2rem;
- max-width: 2rem;
- }
- .threshold {
- min-width: 2rem;
- max-width: 2rem;
- }
- .limit {
- min-width: 2rem;
- max-width: 2rem;
- }
- .item-img {
- width: 24px;
- height: 24px;
- margin: 4px 0 0 0;
- }
- }
- }
}
.tab.character-equipment .main-div {
diff --git a/styles/roll.less b/styles/roll.less
index 64ebeed..3d21bdc 100644
--- a/styles/roll.less
+++ b/styles/roll.less
@@ -19,9 +19,219 @@
.fvtt-hamalron-roll-dialog {
fieldset {
- padding: 10px;
+ padding: 6px;
background-color: var(--color-light-1);
}
+
+ .dialog-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-bottom: 0;
+
+ .actor-info {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.25rem 0.5rem;
+ background-color: rgba(0, 0, 0, 0.05);
+ border-radius: 0.25rem;
+
+ .actor-portrait {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: 2px solid var(--color-dark-6);
+ object-fit: cover;
+ }
+
+ .actor-name {
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 0.9);
+ font-weight: bold;
+ color: var(--color-dark-1);
+ }
+ }
+
+ .competence-info {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.25rem 0.5rem;
+
+ h3 {
+ margin: 0;
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1);
+ color: var(--title-color);
+ white-space: nowrap;
+ }
+
+ .competence-details {
+ display: flex;
+ gap: 0.5rem;
+ font-size: calc(var(--font-size-standard) * 0.85);
+
+ .competence-symbole,
+ .competence-niveau {
+ padding: 0.25rem 0.5rem;
+ background-color: rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
+ font-weight: 500;
+ }
+ }
+ }
+ }
+
+ .tarot-hand {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
+ gap: 0.5rem;
+ padding: 0.25rem;
+ min-height: 90px;
+
+ .tarot-card-select {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.15rem;
+ padding: 0.25rem;
+ border: 2px solid transparent;
+ border-radius: 0.35rem;
+ background-color: rgba(0, 0, 0, 0.05);
+ cursor: pointer;
+ transition: all 0.2s ease;
+ position: relative;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.1);
+ border-color: var(--color-dark-5);
+ transform: translateY(-2px) scale(1.3);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
+ z-index: 10;
+ }
+
+ &.selected {
+ background-color: rgba(100, 150, 255, 0.2);
+ border-color: var(--color-success);
+ box-shadow: 0 0 10px rgba(100, 150, 255, 0.5);
+ }
+
+ &.success-card {
+ border: 3px solid #ffd700;
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 215, 0, 0.1) 0%,
+ rgba(255, 223, 0, 0.2) 100%
+ );
+ box-shadow: 0 0 15px rgba(255, 215, 0, 0.4);
+
+ &:hover {
+ border-color: #ffed4e;
+ box-shadow: 0 6px 20px rgba(255, 215, 0, 0.6);
+ }
+
+ &.selected {
+ border-color: #ffd700;
+ box-shadow: 0 0 20px rgba(255, 215, 0, 0.8);
+ }
+ }
+
+ .success-indicator {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ color: #ffd700;
+ font-size: 1rem;
+ text-shadow: 0 0 5px rgba(255, 215, 0, 0.8);
+ animation: pulse-gold 2s ease-in-out infinite;
+ }
+
+ img {
+ width: 50px;
+ height: auto;
+ border-radius: 0.25rem;
+ border: 1px solid var(--color-dark-6);
+ }
+
+ .card-name {
+ font-size: calc(var(--font-size-standard) * 0.75);
+ text-align: center;
+ line-height: 1.1;
+ max-width: 70px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ }
+
+ .card-values {
+ font-size: calc(var(--font-size-standard) * 0.7);
+ text-align: center;
+ color: var(--color-dark-3);
+ font-weight: bold;
+ margin-top: 0.1rem;
+ }
+ }
+
+ p {
+ grid-column: 1 / -1;
+ text-align: center;
+ color: var(--color-dark-5);
+ font-style: italic;
+ margin: 1rem 0;
+ }
+ }
+
+ .dialog-result {
+ .total-display {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 0.1rem;
+ padding: 0.1rem;
+ font-family: var(--font-title);
+ font-size: calc(var(--font-size-standard) * 1.1);
+ font-weight: bold;
+
+ #competence-modifier {
+ color: var(--color-dark-1);
+ }
+
+ #card-value-display {
+ color: var(--color-success);
+ }
+
+ #total-value {
+ padding: 0.1rem 0.2rem;
+ background-color: rgba(0, 0, 0, 0.1);
+ border-radius: 0.35rem;
+ color: var(--title-color);
+ min-width: 2.1rem;
+ text-align: center;
+ }
+ }
+
+ .difficulty-info {
+ text-align: center;
+ font-size: calc(var(--font-size-standard) * 0.9);
+ color: var(--color-dark-2);
+ margin-top: 0.1rem;
+ padding: 0.1rem 0;
+
+ #target-score {
+ font-weight: bold;
+ color: var(--color-dark-1);
+ }
+ }
+ }
+
+ .difficulty-select {
+ width: 100%;
+ text-align: center;
+ padding: 0.25rem;
+ }
}
.dialog-modifier {
@@ -216,3 +426,15 @@
text-shadow: 0 0 10px var(--color-shadow-primary);
}
}
+
+@keyframes pulse-gold {
+ 0%,
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.2);
+ opacity: 0.8;
+ }
+}
diff --git a/styles/tarot-deck-manager.less b/styles/tarot-deck-manager.less
index dfb41a7..1d46153 100644
--- a/styles/tarot-deck-manager.less
+++ b/styles/tarot-deck-manager.less
@@ -1,111 +1,174 @@
.tarot-deck-manager {
.tarot-deck-manager-content {
- padding: 1rem;
+ padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 1.5rem;
+ background: linear-gradient(
+ 135deg,
+ rgba(102, 126, 234, 0.05) 0%,
+ rgba(118, 75, 162, 0.05) 100%
+ );
+ min-height: 100%;
}
.deck-header {
h2 {
- margin: 0 0 1rem 0;
- font-size: 1.5rem;
- color: var(--color-text-dark-primary);
+ margin: 0 0 0.75rem 0;
+ font-size: 1.25rem;
+ color: #667eea;
text-align: center;
- border-bottom: 2px solid var(--color-border-dark);
+ border-bottom: 2px solid #667eea;
padding-bottom: 0.5rem;
+ text-transform: uppercase;
+ letter-spacing: 0.1em;
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.deck-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
- gap: 1rem;
- margin-top: 1rem;
+ gap: 0.5rem;
+ margin-top: 0.75rem;
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
- padding: 0.75rem;
- background: rgba(0, 0, 0, 0.2);
- border-radius: 0.25rem;
- border: 1px solid var(--color-border-dark);
+ padding: 0.5rem;
+ background: linear-gradient(
+ 135deg,
+ rgba(102, 126, 234, 0.15) 0%,
+ rgba(118, 75, 162, 0.15) 100%
+ );
+ border-radius: 0.5rem;
+ border: 2px solid rgba(102, 126, 234, 0.3);
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+ &:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
+ border-color: rgba(102, 126, 234, 0.5);
+ }
i {
- font-size: 1.5rem;
- color: var(--color-text-light-heading);
- margin-bottom: 0.25rem;
+ font-size: 1.25rem;
+ color: #667eea;
+ margin-bottom: 0.15rem;
}
.stat-label {
- font-size: 0.75rem;
+ font-size: 0.7rem;
color: var(--color-text-dark-secondary);
text-transform: uppercase;
+ letter-spacing: 0.05em;
+ text-align: center;
}
.stat-value {
font-size: 1.25rem;
font-weight: bold;
- color: var(--color-text-light-heading);
+ color: #667eea;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
}
}
}
.deck-actions {
- display: flex;
- flex-direction: column;
- gap: 1rem;
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.5rem;
.action-button {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
- padding: 0.75rem 1rem;
- font-size: 1rem;
+ padding: 0.6rem 0.75rem;
+ font-size: 0.85rem;
font-weight: bold;
border: none;
- border-radius: 0.25rem;
+ border-radius: 0.5rem;
cursor: pointer;
- transition: all 0.2s ease;
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
i {
- font-size: 1.25rem;
+ font-size: 1.1rem;
+ }
+
+ &:hover:not(:disabled) {
+ transform: translateY(-3px);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
+ }
+
+ &:active:not(:disabled) {
+ transform: translateY(-1px);
}
&:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
+ filter: grayscale(50%);
}
}
.reset-button {
- background: var(--color-border-dark);
- color: var(--color-text-light-heading);
+ background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
+ color: white;
&:hover:not(:disabled) {
- background: var(--color-border-dark-tertiary);
- transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
+ background: linear-gradient(135deg, #c0392b 0%, #e74c3c 100%);
}
}
- .draw-actions {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 0.5rem;
+ .collect-hands-button {
+ background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
+ color: white;
- .draw-button {
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
+ &:hover:not(:disabled) {
+ background: linear-gradient(135deg, #2980b9 0%, #3498db 100%);
+ }
+ }
- &:hover:not(:disabled) {
- background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
- transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(102, 126, 234, 0.4);
- }
+ .distribute-cards-button {
+ background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
+ color: white;
+
+ &:hover:not(:disabled) {
+ background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
+ }
+ }
+
+ .shuffle-discard-button {
+ background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
+ color: white;
+
+ &:hover:not(:disabled) {
+ background: linear-gradient(135deg, #e67e22 0%, #f39c12 100%);
+ }
+ }
+
+ .draw-button {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+
+ &:hover:not(:disabled) {
+ background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
+ }
+ }
+
+ .draw-tension-button {
+ background: linear-gradient(135deg, #f39c12 0%, #d35400 100%);
+ color: white;
+
+ &:hover:not(:disabled) {
+ background: linear-gradient(135deg, #d35400 0%, #f39c12 100%);
}
}
}
diff --git a/templates/character-biography.hbs b/templates/character-biography.hbs
deleted file mode 100644
index 3ddab0c..0000000
--- a/templates/character-biography.hbs
+++ /dev/null
@@ -1,154 +0,0 @@
-
-
-
-
- {{localize "HAMALRON.Label.experience"}}
-
- {{formField systemFields.experience.fields.current value=system.experience.current type="number" rootId=partId
- disabled=isPlayMode}}
-
-
- {{formField systemFields.experience.fields.total value=system.experience.total type="number" rootId=partId
- disabled=isPlayMode}}
-
-
- {{formField systemFields.experience.fields.training value=system.experience.training type="number" rootId=partId
- disabled=isPlayMode}}
-
-
-
-
- {{localize "HAMALRON.Label.biodata"}}
-
- {{formField systemFields.biodata.fields.aliases value=system.biodata.aliases rootId=partId disabled=isPlayMode}}
-
-
-
- {{formField systemFields.biodata.fields.gender value=system.biodata.gender rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.age value=system.biodata.age rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.height value=system.biodata.height rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.weight value=system.biodata.weight rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.eyes value=system.biodata.eyes rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.hair value=system.biodata.hair rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.home value=system.biodata.home rootId=partId disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.birthplace value=system.biodata.birthplace rootId=partId
- disabled=isPlayMode}}
-
-
- {{formField systemFields.biodata.fields.dod value=system.biodata.dod rootId=partId
- disabled=isPlayMode}}
-
-
-
-
-
- {{localize "HAMALRON.Label.deals"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each deals as |item|}}
-
-
-
- {{item.name}}
-
-
-
- {{/each}}
-
-
-
-
-
- {{localize "HAMALRON.Label.backstory"}}
- {{formInput systemFields.backstory enriched=enrichedBackstory value=system.backstory name="system.backstory" toggled=true}}
-
-
-
-
- {{localize "HAMALRON.Label.appearance"}}
- {{formInput systemFields.appearance enriched=enrichedAppearance value=system.appearance name="system.appearance"
- toggled=true}}
-
-
- {{localize "HAMALRON.Label.scars"}}
- {{formInput systemFields.scars enriched=scars value=system.scars name="system.scars"
- toggled=true}}
-
-
-
-
-
- {{localize "HAMALRON.Label.likes"}}
- {{formInput systemFields.likes enriched=enrichedLikes value=system.likes name="system.likes"
- toggled=true}}
-
-
- {{localize "HAMALRON.Label.dislikes"}}
- {{formInput systemFields.dislikes enriched=enrichedDislikes value=system.dislikes name="system.dislikes"
- toggled=true}}
-
-
-
-
-
- {{localize "HAMALRON.Label.fears"}}
- {{formInput systemFields.fears enriched=enrichedFears value=system.fears name="system.fears"
- toggled=true}}
-
-
- {{localize "HAMALRON.Label.vices"}}
- {{formInput systemFields.vices enriched=enrichedVices value=system.vices name="system.vices"
- toggled=true}}
-
-
-
-
-
- {{localize "HAMALRON.Label.goals"}}
- {{formInput systemFields.goals enriched=enrichedGoals value=system.goals name="system.goals"
- toggled=true}}
-
-
- {{localize "HAMALRON.Label.ambitions"}}
- {{formInput systemFields.ambitions enriched=enrichedAmbitions value=system.ambitions name="system.ambitions"
- toggled=true}}
-
-
-
-
-
- {{localize "HAMALRON.Label.values"}}
- {{formInput systemFields.values enriched=enrichedValues value=system.values name="system.values"
- toggled=true}}
-
-
- {{localize "HAMALRON.Label.bonds"}}
- {{formInput systemFields.bonds enriched=enrichedBonds value=system.bonds name="system.bonds"
- toggled=true}}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/character-equipment.hbs b/templates/character-equipment.hbs
deleted file mode 100644
index fc39174..0000000
--- a/templates/character-equipment.hbs
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
-
- {{localize "HAMALRON.Label.weapons"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each weapons as |item|}}
-
-
-
-
-
- {{item.name}}
-
-
-
{{upperFirst item.system.properties}}
-
{{upperFirst item.system.range}}
-
- {{#if (eq item.system.weaponType "melee")}}
-
-
-
- {{else}}
-
-
- {{item.system.ammoQuantity}}
-
-
-
{{upperFirst item.system.ammo}}
- {{/if}}
-
-
-
- {{item.system.damageFormula}}
-
-
-
- {{/each}}
-
-
-
-
- {{localize "HAMALRON.Label.armors"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each armors as |item|}}
-
-
-
- {{item.name}}
-
-
{{item.system.bonus}}
-
{{item.system.resilience}}
-
{{item.system.reduction}}
-
-
-
- {{/each}}
-
-
-
-
- {{localize "HAMALRON.Label.equipments"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each equipments as |item|}}
- {{!log 'armor' this}}
-
-
-
- {{item.name}}
-
-
{{item.system.quantity}}
-
-
-
- {{/each}}
-
-
-
-
- Limboes and Ammo
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/character-main.hbs b/templates/character-main.hbs
deleted file mode 100644
index 42c0f3e..0000000
--- a/templates/character-main.hbs
+++ /dev/null
@@ -1,106 +0,0 @@
-
- {{!log "character-main" this}}
-
- {{localize "HAMALRON.Label.character"}}
-
-
-
-
-
-
-
-
-
- {{formInput fields.name value=source.name rootId=partId disabled=isPlayMode}}
-
-
-
-
-
-
-
- {{formField systemFields.pronouns value=system.pronouns rootId=partId disabled=isPlayMode}}
-
-
-
-
- {{formField systemFields.species value=system.species rootId=partId disabled=isPlayMode}}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{localize "HAMALRON.Label.stats"}}
-
- {{localize
- "HAMALRON.Label.flesh"}}
- {{formInput systemFields.stats.fields.flesh.fields.value value=system.stats.flesh.value rootId=partId disabled=isPlayMode type="number" }}
-
-
- {{localize
- "HAMALRON.Label.skin"}}
- {{formInput systemFields.stats.fields.skin.fields.value value=system.stats.skin.value rootId=partId disabled=isPlayMode type="number" }}
-
-
- {{localize
- "HAMALRON.Label.heart"}}
- {{formInput systemFields.stats.fields.heart.fields.value value=system.stats.heart.value rootId=partId disabled=isPlayMode type="number" }}
-
-
- {{localize
- "HAMALRON.Label.mind"}}
- {{formInput systemFields.stats.fields.mind.fields.value value=system.stats.mind.value rootId=partId disabled=isPlayMode type="number" }}
-
-
- {{localize
- "HAMALRON.Label.soul"}}
- {{formInput systemFields.stats.fields.soul.fields.value value=system.stats.soul.value rootId=partId disabled=isPlayMode type="number" }}
-
-
-
-
\ No newline at end of file
diff --git a/templates/character-maleficas.hbs b/templates/character-maleficas.hbs
deleted file mode 100644
index 7a63925..0000000
--- a/templates/character-maleficas.hbs
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
- {{localize "HAMALRON.Label.maleficas"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each maleficas as |item|}}
- {{!log 'weapon' this}}
-
-
-
-
-
-
{{upperFirst item.system.domain}}
-
{{getRomanLevel item.system.level}}
- {{#if item.system.hasDamage}}
-
-
- {{item.system.damage}}
- {{else}}
-
-
- {{/if}}
-
-
-
- {{/each}}
-
-
-
-
- {{localize "HAMALRON.Label.rituals"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each rituals as |item|}}
-
-
-
-
-
-
{{upperFirst item.system.ingredients}}
-
{{upperFirst item.system.difficulty}}
-
{{upperFirst item.system.threshold}}
-
{{upperFirst item.system.limit}}
-
-
-
- {{/each}}
-
-
-
-
\ No newline at end of file
diff --git a/templates/character-status.hbs b/templates/character-status.hbs
deleted file mode 100644
index 43c791f..0000000
--- a/templates/character-status.hbs
+++ /dev/null
@@ -1,84 +0,0 @@
-
-
-
-
- {{localize "HAMALRON.Label.characteristics"}}
-
-
-
- Trauma {{formInput systemFields.trauma.fields.current value=system.trauma.current}} /
- {{formInput systemFields.trauma.fields.max value=system.trauma.max}}
-
- Darkness {{formInput systemFields.darkness.fields.current value=system.darkness.current}} /
- {{formInput systemFields.darkness.fields.max value=system.darkness.max}}
- {{formInput systemFields.darkness.fields.value value=system.darkness.value}}
- Defense {{formInput systemFields.defense.fields.base value=system.defense.base}}
- {{formInput systemFields.defense.fields.bonus value=system.defense.bonus }}
- {{formInput systemFields.defense.fields.total value=system.defense.total}}
- {{formInput systemFields.defense.fields.resistance value=system.defense.resistance}}
- Movement {{formInput systemFields.movement.fields.base value=system.movement.base}}
- {{formInput systemFields.movement.fields.reduce value=system.defense.reduce }}
-
-
-
- Curr. Max
- Curr. Max Mal.DR
- Base Armor Total Resi.
- Base Redu.
-
-
-
-
-
-
-
- {{localize "HAMALRON.Label.perks"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each perks as |item|}}
-
-
-
-
-
-
{{upperFirst item.system.flavorText}}
-
{{upperFirst item.system.role}}
-
{{getRomanLevel item.system.level}}
-
-
-
- {{/each}}
-
-
-
-
- {{localize "HAMALRON.Label.ailments"}}
-
- Mortality :
- {{#each system.mortality.enabled as |mortality idx|}}
-
- {{/each}}
-
-
-
- {{#each system.ailments as |item id|}}
-
- {{item.label}}
-
- {{/each}}
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/chat-competence.hbs b/templates/chat-competence.hbs
new file mode 100644
index 0000000..6f39441
--- /dev/null
+++ b/templates/chat-competence.hbs
@@ -0,0 +1,154 @@
+
+
+
+
+ {{#if selectedCard}}
+
+
+
+ {{localize "HAMALRON.Label.cardUsed"}}
+
+
+
+
+ {{selectedCard.name}}
+ {{#if cardBonus}}
+
+ {{#if (eq cardSymboleMatch true)}}
+
+ {{localize "HAMALRON.Label.matchingSymbol"}}
+ {{else if isAtout}}
+
+ Atout
+ {{else}}
+
+ {{localize "HAMALRON.Label.differentSymbol"}}
+ {{/if}}
+
+ {{/if}}
+ {{#if isValet}}
+
+
+ Valet : Compensation en cas d'échec
+
+ {{/if}}
+ {{#if isCavalier}}
+
+
+ Cavalier : Échec transformé en égalité
+
+ {{/if}}
+ {{#if isReine}}
+
+
+ Reine : Effet exceptionnel et désagrément
+
+ {{/if}}
+ {{#if isRoi}}
+
+
+ Roi : Effet exceptionnel
+
+ {{/if}}
+
+
+
+ {{/if}}
+
+
+
+ {{localize "HAMALRON.Label.competenceModifier"}}
+ {{competenceModifier}}
+
+ {{#if cardBonus}}
+
+ {{localize "HAMALRON.Label.cardBonus"}}
+ +{{cardBonus}}
+
+ {{/if}}
+
+
+ {{localize "HAMALRON.Label.totalValue"}}
+ {{totalValue}}
+
+
+
+ {{#unless isSousTensionOppose}}
+
+
+
+ {{difficulty}}
+ {{localize "HAMALRON.Label.targetScore"}}: {{targetScore}}
+
+
+ {{/unless}}
+
+
+ {{#if isSousTensionOppose}}
+
+ {{else}}
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/templates/chat-tarot-draw.hbs b/templates/chat-tarot-draw.hbs
index 00aa17d..41a3929 100644
--- a/templates/chat-tarot-draw.hbs
+++ b/templates/chat-tarot-draw.hbs
@@ -1,46 +1,36 @@
-
+
-
-
-
-
-
-
-
-
- {{localize
- "HAMALRON.Tarot.FIELDS.symbole.label"
- }}:
- {{symboleLabel}}
-
-
-
- {{localize
- "HAMALRON.Tarot.FIELDS.valeur.label"
- }}:
- {{valeurLabel}}
-
-
-
- {{localize
- "HAMALRON.Tarot.FIELDS.type.label"
- }}:
- {{typeLabel}}
-
-
- {{#if card.description}}
-
-
{{localize
- "HAMALRON.Tarot.FIELDS.description.label"
- }}:
-
{{{card.description}}}
+
+
+
+
{{card.name}}
+
+
+
+ {{symboleLabel}}
+
+
+
+ {{valeurLabel}}
+
+
+
+ {{typeLabel}}
+
- {{/if}}
+
+
+ {{#if card.description}}
+
+
+
+
+ {{localize "HAMALRON.Tarot.FIELDS.description.label"}}
+
+
{{{card.description}}}
+
+
+ {{/if}}
\ No newline at end of file
diff --git a/templates/chat-tarot-tension.hbs b/templates/chat-tarot-tension.hbs
new file mode 100644
index 0000000..d7c5b86
--- /dev/null
+++ b/templates/chat-tarot-tension.hbs
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+ {{localize "HAMALRON.Label.difficulty"}}
+
+
{{difficulty.label}}
+
+
+
+
+ {{localize "HAMALRON.Label.cardValue"}}
+ {{cardValue}}
+
+
+ {{localize "HAMALRON.Label.tensionModifier"}}
+
+ {{#if (gt tensionBonus 0)}}+{{/if}}{{tensionBonus}}
+
+
+
+ {{localize "HAMALRON.Label.totalScore"}}
+ {{totalScore}}
+
+
+
+
diff --git a/templates/competence.hbs b/templates/competence.hbs
index 9bbd61c..6980fb4 100644
--- a/templates/competence.hbs
+++ b/templates/competence.hbs
@@ -17,7 +17,14 @@
value=system.carteSymbole
localize=true
}}
- {{formField systemFields.niveau value=system.niveau}}
+ {{formField systemFields.niveau value=system.niveau localize=true}}
+
+ {{#if (eq system.type "faction")}}
+ {{formField systemFields.faction value=system.faction localize=true}}
+ {{/if}}
+ {{#if (eq system.type "peuple")}}
+ {{formField systemFields.peuple value=system.peuple localize=true}}
+ {{/if}}
diff --git a/templates/personnage-biographie.hbs b/templates/personnage-biographie.hbs
index da0d2d1..563281c 100644
--- a/templates/personnage-biographie.hbs
+++ b/templates/personnage-biographie.hbs
@@ -5,6 +5,18 @@
>
+
+ {{localize "HAMALRON.Label.progression"}}
+
+
+
+
+
{{localize "HAMALRON.Label.biodata"}}
diff --git a/templates/personnage-main.hbs b/templates/personnage-main.hbs
index 54b476a..5a4df32 100644
--- a/templates/personnage-main.hbs
+++ b/templates/personnage-main.hbs
@@ -1,60 +1,190 @@
-
- {{!log "character-main" this}}
+
+ {{log "character-main context" this}}
+ {{log "isEditMode" isEditMode "isPlayMode" isPlayMode}}
{{localize "HAMALRON.Label.character"}}
-
+
-
+
+
+
+
-
-
- {{#each system.biodata as |bioField key|}}
- {{#if (eq key "age")}}
- {{formField systemFields.biodata.fields.age value=system.biodata.age rootId=partId disabled=isPlayMode}}
- {{/if}}
- {{#if (eq key "gender")}}
- {{formField systemFields.biodata.fields.gender value=system.biodata.gender rootId=partId disabled=isPlayMode}}
- {{/if}}
- {{/each}}
-
-
+
+ {{localize "HAMALRON.Label.cartesSucces"}}
+ {{log "cartesSucces data:" system.cartesSucces}}
+
+ {{#each system.cartesSucces as |carte symbole|}}
+ {{log "Processing carte:" symbole carte "isEditMode in loop:" ../isEditMode}}
+
+
+ {{carte.label}}
+
+
+ {{log "In stat-values, isEditMode:" ../isEditMode}}
+ {{#if ../isEditMode}}
+ {{log "Rendering input for carte"}}
+
+ {{else}}
+ {{log "Rendering span for carte"}}
+ {{carte.value}}
+ {{/if}}
+
+
+ {{/each}}
+
+
-
- {{localize "HAMALRON.Label.cartesSucces"}}
- {{#each system.cartesSucces as |carte symbole|}}
-
- {{carte.label}}
- {{formInput systemFields.cartesSucces.fields.[symbole].fields.value value=carte.value rootId=partId disabled=isPlayMode type="number" }}
- /
- {{formInput systemFields.cartesSucces.fields.[symbole].fields.max value=carte.max rootId=partId disabled=isPlayMode type="number" }}
-
- {{/each}}
-
-
-
- {{localize "HAMALRON.Label.resistances"}}
-
- {{#each system.resistances as |resistance symbole|}}
-
-
{{resistance.label}}
- {{formInput systemFields.resistances.fields.[symbole].fields.value value=resistance.value rootId=partId disabled=isPlayMode type="number" }}
-
/
- {{formInput systemFields.resistances.fields.[symbole].fields.max value=resistance.max rootId=partId disabled=isPlayMode type="number" }}
+
+ {{localize "HAMALRON.Label.resistances"}}
+
+ {{#each system.resistances as |resistance symbole|}}
+
+
{{resistance.label}}
+
+ {{#if ../isEditMode}}
+
+
/
+
+ {{else}}
+
+
+
+
{{resistance.value}}
+
/
+
{{resistance.max}}
+
+
+
+ {{/if}}
+
+
+ {{/each}}
+
+
- {{/each}}
-
\ No newline at end of file
diff --git a/templates/personnage-sortileges.hbs b/templates/personnage-sortileges.hbs
index 7a63925..19cf9dc 100644
--- a/templates/personnage-sortileges.hbs
+++ b/templates/personnage-sortileges.hbs
@@ -1,70 +1,143 @@
-
+
-
- {{localize "HAMALRON.Label.maleficas"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each maleficas as |item|}}
- {{!log 'weapon' this}}
-
+
+ {{localize "HAMALRON.Label.sortileges"}}{{#if isEditMode}}
+ {{/if}}
+
+
+ {{#each sortileges as |item|}}
+
-
-
-
-
{{upperFirst item.system.domain}}
-
{{getRomanLevel item.system.level}}
- {{#if item.system.hasDamage}}
-
-
- {{item.system.damage}}
- {{else}}
-
-
- {{/if}}
+
+
+
+
{{upperFirst
+ item.system.domain
+ }}
+
{{getRomanLevel
+ item.system.level
+ }}
+ {{#if item.system.hasDamage}}
+
+
+ {{item.system.damage}}
+ {{else}}
+
-
+ {{/if}}
-
+
+
+ {{/each}}
- {{/each}}
-
-
+
-
- {{localize "HAMALRON.Label.rituals"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each rituals as |item|}}
-
+
+ {{localize "HAMALRON.Label.rituals"}}{{#if isEditMode}}
+ {{/if}}
+
+
+ {{#each rituals as |item|}}
+
-
-
-
-
{{upperFirst item.system.ingredients}}
-
{{upperFirst item.system.difficulty}}
-
{{upperFirst item.system.threshold}}
-
{{upperFirst item.system.limit}}
+
+
+
+
{{upperFirst
+ item.system.ingredients
+ }}
+
{{upperFirst
+ item.system.difficulty
+ }}
+
{{upperFirst
+ item.system.threshold
+ }}
+
{{upperFirst
+ item.system.limit
+ }}
-
+
+
+ {{/each}}
- {{/each}}
-
-
-
+
+
\ No newline at end of file
diff --git a/templates/personnage-status.hbs b/templates/personnage-status.hbs
index 149b266..fb8cfec 100644
--- a/templates/personnage-status.hbs
+++ b/templates/personnage-status.hbs
@@ -1,44 +1,199 @@
-
+
-
- {{localize "HAMALRON.Label.progression"}}
-
- {{formField systemFields.progression value=system.progression type="number"}}
-
-
+ {{#if competencesCommunes.length}}
+
+
+
+ {{#each competencesCommunes as |item|}}
+
+
+
+
{{upperFirst
+ item.system.carteSymbole
+ }}
+
{{item.niveauName}} ({{item.niveauModificateur}})
-
- {{localize "HAMALRON.Label.competences"}}{{#if isEditMode}}
- {{/if}}
-
-
- {{#each perks as |item|}}
-
-
-
-
-
{{upperFirst item.system.type}}
-
{{upperFirst item.system.carteSymbole}}
-
{{item.system.niveau}}
-
-
+
+
+ {{/each}}
- {{/each}}
-
-
+
+ {{/if}}
-
-
-
+ {{#if competencesPeuple.length}}
+
+
+
+ {{#each competencesPeuple as |item|}}
+
+
+
+
{{upperFirst
+ item.system.carteSymbole
+ }}
+
{{item.niveauName}} ({{item.niveauModificateur}})
+
+
+
+ {{/each}}
+
+
+ {{/if}}
+
+ {{#if competencesFaction.length}}
+
+
+
+ {{#each competencesFaction as |item|}}
+
+
+
+
{{upperFirst
+ item.system.carteSymbole
+ }}
+
{{item.niveauName}} ({{item.niveauModificateur}})
+
+
+
+ {{/each}}
+
+
+ {{/if}}
+
+ {{#if isEditMode}}
+
+ {{/if}}
\ No newline at end of file
diff --git a/templates/personnage-tarot.hbs b/templates/personnage-tarot.hbs
index 4b7ed91..d75605a 100644
--- a/templates/personnage-tarot.hbs
+++ b/templates/personnage-tarot.hbs
@@ -5,13 +5,27 @@
>
-
{{localize "HAMALRON.Label.tarotHand"}}
-
+
- {{tarotCards.length}}
+ {{handSize}} / {{handLimit}}
{{localize "HAMALRON.Label.cards"}}
+
+
+ {{localize "HAMALRON.Label.drawCard"}}
+
+ {{#if isOverLimit}}
+
+
+ {{localize "HAMALRON.Label.mustDiscardCard"}}
+
+ {{/if}}
@@ -19,30 +33,30 @@
{{#each tarotCards as |card|}}
@@ -57,57 +74,45 @@
-
-
-
-
- {{localize "HAMALRON.Tarot.FIELDS.symbole.label"}}:
-
-
- {{localize
- (concat
- "HAMALRON.Tarot.FIELDS.symbole." card.system.symbole
- )
- }}
-
-
-
-
-
-
- {{localize "HAMALRON.Tarot.FIELDS.valeur.label"}}:
-
-
- {{localize
- (concat
- "HAMALRON.Tarot.FIELDS.valeur." card.system.valeur
- )
- }}
-
-
-
-
-
-
- {{localize "HAMALRON.Tarot.FIELDS.type.label"}}:
-
-
- {{localize
- (concat
- "HAMALRON.Tarot.FIELDS.type." card.system.type
- )
- }}
-
-
+
+
{{card.name}}
- {{#if card.system.description}}
-
-
- {{{card.enrichedDescription}}}
+
+
+
+
+ {{localize (concat "HAMALRON.Tarot.FIELDS.symbole." card.system.symbole)}}
+
+
+ {{tarotValue card.system.valeur}}
- {{/if}}
+
+
+
+ {{localize "HAMALRON.Label.discardAndDraw"}}
+
+
+ {{#if @root.isOverLimit}}
+ {{#if @root.isEditMode}}
+
+
+ {{localize "HAMALRON.Label.discard"}}
+
+ {{/if}}
+ {{/if}}
+
diff --git a/templates/roll-dialog.hbs b/templates/roll-dialog.hbs
index 7cbd583..017d657 100644
--- a/templates/roll-dialog.hbs
+++ b/templates/roll-dialog.hbs
@@ -1,40 +1,91 @@
-
+
-
+ {{#if (eq rollType "competence")}}
+
+ {{localize "HAMALRON.Label.competence"}}
- {{#if (eq rollType "stat")}}
- {{localize "HAMALRON.Label.stat"}}
- {{/if}}
+
+
+
+
{{actorName}}
+
-
{{localize rollItem.label}} : 3d6+{{rollItem.value}}
+
+
{{rollItem.name}}
+
+ {{localize
+ "HAMALRON.Label.symbole"
+ }}:
+ {{upperFirst rollItem.system.carteSymbole}}
+ {{localize
+ "HAMALRON.Label.niveau"
+ }}:
+ {{rollItem.system.niveau}}
+ ({{competenceModifier}})
+
+
+
+
- {{#if weapon}}
- Weapon : {{weapon.name}}
- {{/if}}
+
+ {{localize "HAMALRON.Label.selectTarotCard"}}
-
+
+ {{#if tarotCards}}
+ {{#each tarotCards as |card|}}
+
+
+
{{card.name}}
+ {{#if card.isSuccessCard}}
{{/if}}
+
+
+ {{/each}}
+ {{else}}
+
{{localize "HAMALRON.Notifications.noTarotCards"}}
+ {{/if}}
+
+
-
- Advantages & Disadvantages
+
+ {{localize "HAMALRON.Label.difficulty"}}
+
+ {{selectOptions
+ difficultyChoices
+ selected="soustension_oppose"
+ localize=false
+ }}
+
+
-
- {{selectOptions choiceAdvantages selected=nbAdvantages localize=true}}
-
-
- {{selectOptions choiceDisadvantages selected=nbDisadvantages localize=true}}
-
-
-
-
-
- Difficulty
-
-
-
-
- {{localize "HAMALRON.Label.formula"}}
- {{fullFormula}}
-
+
+ {{localize "HAMALRON.Label.total"}}
+
+ {{competenceModifier}}
+ + 0
+ =
+ {{competenceModifier}}
+
+
+ {{localize "HAMALRON.Label.targetScore"}}:
+ -
+
+
+ {{/if}}
{{localize "HAMALRON.Label.rollView"}}
diff --git a/templates/tarot-deck-manager.hbs b/templates/tarot-deck-manager.hbs
index 2d955df..2fe837b 100644
--- a/templates/tarot-deck-manager.hbs
+++ b/templates/tarot-deck-manager.hbs
@@ -8,9 +8,9 @@
{{deckCount}}
-
- {{localize "HAMALRON.TarotDeck.CardsDrawn"}}:
- {{drawnCount}}
+
+ {{localize "HAMALRON.TarotDeck.CardsInDiscard"}}:
+ {{discardCount}}
@@ -26,48 +26,31 @@
{{localize "HAMALRON.TarotDeck.ResetDeck"}}
-
-
-
- {{localize "HAMALRON.TarotDeck.DrawOne"}}
-
+
+
+ {{localize "HAMALRON.TarotDeck.CollectHands"}}
+
-
-
- {{localize "HAMALRON.TarotDeck.DrawThree"}}
-
+
+
+ {{localize "HAMALRON.TarotDeck.DistributeCards"}}
+
-
-
- {{localize "HAMALRON.TarotDeck.DrawFive"}}
-
-
-
+
+
+ {{localize "HAMALRON.TarotDeck.ShuffleDiscard"}}
+
- {{#if drawnCards.length}}
-
-
{{localize "HAMALRON.TarotDeck.RecentDraws"}}
-
- {{#each drawnCards}}
-
-
-
-
{{this.name}}
-
- {{lookup ../symboleLabel @index}}
- {{lookup ../valeurLabel @index}}
-
-
-
- {{/each}}
-
+
+
+ {{localize "HAMALRON.TarotDeck.DrawOne"}}
+
+
+
+
+ {{localize "HAMALRON.TarotDeck.DrawTension"}}
+
- {{else}}
-
-
-
{{localize "HAMALRON.TarotDeck.NoDrawsYet"}}
-
- {{/if}}
{{#unless hasCards}}
diff --git a/templates/tarot.hbs b/templates/tarot.hbs
index d01c457..74d9a5b 100644
--- a/templates/tarot.hbs
+++ b/templates/tarot.hbs
@@ -14,8 +14,8 @@
{{formField systemFields.type value=system.type localize=true}}
{{#unless (eq system.type "atout")}}
{{formField systemFields.symbole value=system.symbole localize=true}}
- {{formField systemFields.valeur value=system.valeur localize=true}}
{{/unless}}
+ {{formField systemFields.valeur value=system.valeur localize=true}}