14 Commits

Author SHA1 Message Date
uberwald 58478d56ea Amélioration du rendu des polices
Release Creation / build (release) Successful in 1m22s
2026-04-27 21:54:04 +02:00
uberwald a99eeaccba Corrections sur font, again v3
Release Creation / build (release) Successful in 1m35s
2026-04-27 17:40:59 +02:00
uberwald 2ab380786f Correction sur O dans police de titre, step2
Release Creation / build (release) Successful in 1m12s
2026-04-27 06:39:11 +02:00
uberwald c3ce628e24 Ameliorations CSS et font diverses
Release Creation / build (release) Successful in 1m25s
2026-04-26 22:44:23 +02:00
uberwald 8e5fb9aca1 Correction sur jauge de destin
Release Creation / build (release) Successful in 1m26s
2026-04-16 22:26:44 +02:00
uberwald 1b2a74969d Update READM.md 2026-04-16 08:39:52 +02:00
uberwald 98a6a41078 Ajout README.md 2026-04-15 11:53:52 +02:00
uberwald c73136b3c9 Ajout README.md 2026-04-15 11:41:44 +02:00
uberwald 49996104ce Roll and styles update
Release Creation / build (release) Failing after 1m17s
2026-04-15 02:16:51 +02:00
uberwald b3cf0b0aa1 Corrections après tests de combat
Release Creation / build (release) Failing after 1m34s
2026-04-14 18:59:09 +02:00
uberwald 63c0153860 FIx v13/v14
Release Creation / build (release) Failing after 1m17s
2026-04-14 00:56:25 +02:00
uberwald 8bfbdedf43 Upgrade compat 2026-04-13 17:33:06 +02:00
uberwald 6d2fca9fc2 Cleanup 2026-04-13 16:34:38 +02:00
uberwald b26ce2f114 Diverses corrections autour du combat 2026-04-13 16:23:31 +02:00
64 changed files with 835 additions and 503 deletions
+1 -1
View File
@@ -68,4 +68,4 @@ jobs:
manifest: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/latest/system.json' manifest: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/latest/system.json'
notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-celestopol-${{github.event.release.tag_name}}.zip' notes: 'https://www.uberwald.me/gitea/${{gitea.repository}}/releases/download/${{github.event.release.tag_name}}/fvtt-celestopol-${{github.event.release.tag_name}}.zip'
compatibility-minimum: '13' compatibility-minimum: '13'
compatibility-verified: '13' compatibility-verified: '14'
-87
View File
@@ -1,87 +0,0 @@
# Copilot Instructions — fvtt-celestopol
## Project Overview
This is a **Foundry VTT system** for **Célestopol 1922**, a French tabletop RPG set in an art-deco 1922 universe. The project targets FoundryVTT v13+ and is developed in French.
The reference rulebooks are in `__regles/` (gitignored):
- *Célestopol 1922 Livre de base* — core rulebook
- *Célestopol 1922 Fiches de prêts à jouer* — pre-generated character sheets
## Architecture
This system uses **FoundryVTT v13 DataModels + ApplicationV2** — NOT the legacy template.json / AppV1 approach.
```
fvtt-celestopol.mjs # Main entry point (Hooks.once("init"))
module/
config/system.mjs # All game constants (SYSTEM export)
models/ # TypeDataModel subclasses (character, npc, items)
documents/ # Actor, Item, ChatMessage, Roll wrappers
applications/sheets/ # AppV2 sheets (HandlebarsApplicationMixin)
lang/fr.json # French i18n (key prefix: CELESTOPOL.*)
styles/ # LESS source files
css/ # Compiled CSS (via gulp)
templates/ # Handlebars (.hbs) templates
assets/fonts/ # CopaseticNF art-deco font
assets/ui/ # Background images
assets/icons/ # Item icons
packs-system/ # Source files for compendium packs
```
## DataModels (no template.json)
- Extend `foundry.abstract.TypeDataModel`
- Schema in `static defineSchema()` using `foundry.data.fields.*`
- `prepareDerivedData()` for computed values
- Files: `module/models/character.mjs`, `npc.mjs`, `items.mjs`
## ApplicationV2 / Sheets
- Actor sheets: `HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2)`
- Item sheets: `HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2)`
- `static DEFAULT_OPTIONS` for config; `static PARTS` for templates
- `_prepareContext()` for base context; `_preparePartContext(partId, context)` for per-tab
- Edit/Play mode toggle via `_sheetMode` + `isPlayMode`/`isEditMode` getters
- Actions: `static #onXxx(event, target)` private static methods in `DEFAULT_OPTIONS.actions`
- `form: { submitOnChange: true }` enables live saving
## Roll Mechanics
- Pool of d6 dice: `nbDice = max(1, skillValue + woundMalus)`
- Formula: `{n}d6 [+ moonBonus + modifier]`
- Moon phase bonus: Nouvelle Lune=0, Croissants=+1, Gibbeuse=+2, Pleine Lune=+3
- Compare total vs difficulty threshold (normal=7)
- Wound malus: levels 1-2=0, 3-4=-1, 5-6=-2, 7=-3, 8=-999 (out)
- DialogV2 for roll configuration: `foundry.applications.api.DialogV2.wait(...)`
## Game Data (4 stats × 4 skills)
- **Âme**: Artifice, Attraction, Coercition, Faveur
- **Corps**: Échauffourée, Effacement, Mobilité, Prouesse
- **Cœur**: Appréciation, Arts, Inspiration, Traque
- **Esprit**: Instruction, Merveilleux technologique, Raisonnement, Traitement
**Tracks**: Blessures (8 niveaux), Destin (8), Spleen (8)
**Anomalies**: 9 types (none + 8)
**Factions**: 8 standard + 2 custom
## Build
```bash
npm install # Install dev deps
npx gulp css # Compile LESS → css/fvtt-celestopol.css (once)
npx gulp # Compile + watch
```
## Visual Style
- Font: **CopaseticNF** (Regular + Bold, in `assets/fonts/`) — art-deco style
- Header bg color: `rgb(12, 76, 12)` (dark green) with orange text (`#e07b00`)
- Sheet header texture: `assets/ui/fond_cadrille.jpg`
- CSS variables: `--cel-green`, `--cel-orange`, `--cel-font-title`, etc.
## Language
All in-game text, labels, and code comments should be in **French**. Code identifiers may be English. All i18n keys use the `CELESTOPOL.*` prefix (see `lang/fr.json`).
+1
View File
@@ -13,3 +13,4 @@ css/*.css
# Règles (PDFs privés) # Règles (PDFs privés)
__regles/ __regles/
*.pdf *.pdf
.github/
+84
View File
@@ -0,0 +1,84 @@
# Célestopol 1922 — Système FoundryVTT
Système [Foundry VTT](https://foundryvtt.com) pour **Célestopol 1922**, le jeu de rôle d'[Antre Monde Éditions](https://antremonde.fr).
Copyright 2025-2026 Antre Monde Editions All rights reserved
Celestopol 1922 is a game written by Emmanuel Chastellière and Julien Arnaud. The authors retain their moral rights to this work in both print and digital formats.
This system for FoundryVTT has been approved and authorized by Antre-Monde Edition
---
## ✨ Fonctionnalités
### Personnages joueurs (PJ)
- **4 attributs** (Âme, Corps, Cœur, Esprit) × **4 compétences** chacun (16 compétences au total)
- Gestion des **Blessures** (8 niveaux avec malus automatique aux jets)
- Suivi du **Destin** et du **Spleen** (jauges à 8 crans)
- **Anomalies** : 9 types, déclenchées sur certains résultats de dé
- **Factions** : 8 factions standard + 2 personnalisées, avec aspects liés
- **Équipement** : armes, armures, équipements génériques
- Onglets dédiés : Principal · Compétences · Factions · Équipement · Combat · Biographie
### Personnages non-joueurs (PNJ)
- Fiche simplifiée : compétences, blessures, équipement, biographie
### Items
- **Arme** : mêlée ou à distance, modificateurs de portée
- **Armure** : protection et malus éventuels
- **Aspect de faction** : lié à une faction, bonus / usage limité
- **Anomalie** : type, usages, description
- **Équipement** générique
### Mécanique de jet de désde démonstration
- **Pool de d6** : `max(1, compétence + malus_blessures)` dés
- **Bonus Phase de Lune** : automatique selon la phase en cours (0 à +3)
- **Modificateurs** : difficulté et bonus libres via DialogV2
- Seuil de succès standard : **7**
- Résultats spéciaux : **Brio** (+destin), **Contrecoup** (destin), **Triomphe** (+anomalie/spleen), **Catastrophe** (anomalie/+spleen)
### Dé de la Lune
- Jet de dé de lune indépendant (menu contextuel du token)
- 8 faces : Nouvelle Lune, Premiers Croissants, Dernier Croissant, Gibbeuses ×2, Pleine Lune, Lune de Feu, Lune Noire
- Sur certains résultats : **choix de contrepartie** via pop-up (perte d'anomalie, spleen, ou échec catastrophique)
- Carte de résultat avec boutons d'application directe
### Combat
- **Initiative Célestopol** : jet d'initiative avec dé spécial, insertion dans le tracker
- Attaque avec calcul automatique dommages / protection
- Chat de combat avec récapitulatif des dégâts et blessures appliqués
### Compendiums inclus
| Pack | Contenu |
| ------------ | ------------------------------ |
| Anomalies | Les 8 anomalies du jeu de base |
| Prétirés | 8 personnages prêts à jouer |
| Aides de jeu | Aide du système |
| Scènes | Scènes utiles |
## 🎨 Charte graphique
- Police de titre : **CopaseticNF** (Regular + Bold)
- Vert sombre en-tête : `#0c4c0c`
- Orange texte : `#e07b00`
- Fond parchemin : `#f0e8d4`
- Texture en-tête : `assets/ui/fond_cadrille.jpg`
---
## 👤 Auteur
**LeRatierBretonnien / Uberwald**
- Discord : `LeRatierBretonnien`
- Site : [uberwald.me](https://www.uberwald.me)
---
## 📜 Licence
Copyright 2025 Antre Monde Editions All rights reserved
Celestopol 1922 is a game written by Emmanuel Chastellière and Julien Arnaud. The authors retain their moral rights to this work in both print and digital formats.
This system for FoundryVTT has been approved and authorized by Antre-Monde Edition.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

+134 -2
View File
@@ -39,6 +39,7 @@ import {
} from "./module/applications/_module.mjs" } from "./module/applications/_module.mjs"
const DAMAGE_APPLICATION_FLAG = "damageApplication" const DAMAGE_APPLICATION_FLAG = "damageApplication"
const MOON_EFFECT_FLAG = "moonEffectApplied"
const FACTION_ASPECT_STATE_SETTING = "factionAspectState" const FACTION_ASPECT_STATE_SETTING = "factionAspectState"
const PREGENS_IMPORTED_SETTING = "pregensImported" const PREGENS_IMPORTED_SETTING = "pregensImported"
const WELCOME_SCENE_IMPORTED_SETTING = "welcomeSceneImported" const WELCOME_SCENE_IMPORTED_SETTING = "welcomeSceneImported"
@@ -173,6 +174,9 @@ Hooks.once("ready", async () => {
if (foundry.utils.hasProperty(changed, `flags.${SYSTEM_ID}.${DAMAGE_APPLICATION_FLAG}`)) { if (foundry.utils.hasProperty(changed, `flags.${SYSTEM_ID}.${DAMAGE_APPLICATION_FLAG}`)) {
_updateRenderedChatMessageState(message) _updateRenderedChatMessageState(message)
} }
if (foundry.utils.hasProperty(changed, `flags.${SYSTEM_ID}.${MOON_EFFECT_FLAG}`)) {
_updateRenderedMoonEffectState(message)
}
}) })
_activateExistingChatCards() _activateExistingChatCards()
@@ -548,8 +552,9 @@ function _activateExistingChatCards() {
document.querySelectorAll(".message[data-message-id]").forEach(messageEl => { document.querySelectorAll(".message[data-message-id]").forEach(messageEl => {
const messageId = messageEl.dataset.messageId const messageId = messageEl.dataset.messageId
const message = game.messages.get(messageId) const message = game.messages.get(messageId)
const root = messageEl.querySelector(".celestopol.chat-roll") if (!message) return
if (!message || !root) return const root = messageEl.querySelector(".celestopol.chat-roll, .celestopol-roll.moon-standalone-card")
if (!root) return
_activateChatCardListeners(message, root) _activateChatCardListeners(message, root)
}) })
} }
@@ -559,12 +564,19 @@ function _activateChatCardListeners(message, html) {
if (!root) return if (!root) return
_renderWeaponDamageState(message, root) _renderWeaponDamageState(message, root)
_renderMoonEffectState(message, root)
root.querySelectorAll('[data-action="apply-weapon-damage"]').forEach(button => { root.querySelectorAll('[data-action="apply-weapon-damage"]').forEach(button => {
if (button.dataset.bound === "true") return if (button.dataset.bound === "true") return
button.dataset.bound = "true" button.dataset.bound = "true"
button.addEventListener("click", event => _onApplyWeaponDamageClick(event, message)) button.addEventListener("click", event => _onApplyWeaponDamageClick(event, message))
}) })
root.querySelectorAll('[data-action="apply-moon-effect"]').forEach(button => {
if (button.dataset.bound === "true") return
button.dataset.bound = "true"
button.addEventListener("click", event => _onApplyMoonEffectClick(event, message))
})
} }
async function _onApplyWeaponDamageClick(event, message) { async function _onApplyWeaponDamageClick(event, message) {
@@ -746,6 +758,126 @@ async function _applyWeaponDamage({ actorId, actorUuid = null, incomingWounds, c
return { actorName: actor.name, appliedWounds, armorProtection } return { actorName: actor.name, appliedWounds, armorProtection }
} }
/* ─── Dé de la Lune — contreparties ─────────────────────────────────────── */
function _getMoonEffectState(message) {
return message?.getFlag(SYSTEM_ID, MOON_EFFECT_FLAG) ?? null
}
function _renderMoonEffectState(message, root) {
const state = _getMoonEffectState(message)
const actionsDiv = root.querySelector(".moon-effect-actions")
if (!actionsDiv) return
if (!state?.applied) return
const NEGATIVE_EFFECTS = new Set(["lose-anomaly", "gain-spleen", "lose-destin"])
// Désactiver tous les boutons et afficher le statut
actionsDiv.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = true })
let statusEl = actionsDiv.querySelector(".moon-effect-applied-status")
if (!statusEl) {
statusEl = document.createElement("span")
actionsDiv.append(statusEl)
}
statusEl.className = "moon-effect-applied-status" + (NEGATIVE_EFFECTS.has(state.effect) ? " is-negative" : "")
statusEl.textContent = state.effectLabel
? game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: state.effectLabel })
: game.i18n.localize("CELESTOPOL.Moon.effectApplied")
}
function _updateRenderedMoonEffectState(message) {
const msgEl = document.querySelector(`.message[data-message-id="${message.id}"]`)
if (!msgEl) return
const root = msgEl.querySelector(".celestopol.chat-roll, .celestopol-roll.moon-standalone-card")
if (!root) return
_renderMoonEffectState(message, root)
}
async function _onApplyMoonEffectClick(event, message) {
event.preventDefault()
const state = _getMoonEffectState(message)
if (state?.applied) return
const button = event.currentTarget
const effect = button.dataset.effect
const actionsDiv = button.closest(".moon-effect-actions")
const actorId = actionsDiv?.dataset.moonActorId ?? ""
const actorUuid = actionsDiv?.dataset.moonActorUuid ?? ""
// Désactiver immédiatement pour éviter les double-clics
actionsDiv?.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = true })
const actor = await CelestopolRoll.resolveActor({ actorId, actorUuid })
if (!actor) {
ui.notifications.warn(game.i18n.localize("CELESTOPOL.Moon.actorNotFound"))
actionsDiv?.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = false })
return
}
const effectLabel = await _applyMoonEffect(actor, effect)
if (effectLabel === null) {
actionsDiv?.querySelectorAll(".moon-effect-btn").forEach(btn => { btn.disabled = false })
return
}
await message.setFlag(SYSTEM_ID, MOON_EFFECT_FLAG, { applied: true, effect, effectLabel })
}
async function _applyMoonEffect(actor, effect) {
const i18n = key => game.i18n.localize(`CELESTOPOL.Moon.${key}`)
const anomaly = actor.items.find(i => i.type === "anomaly")
switch (effect) {
case "regain-anomaly": {
if (!anomaly) { ui.notifications.warn(i18n("noAnomaly")); return null }
const max = anomaly.system?.level ?? 0
const cur = anomaly.system?.usesRemaining ?? 0
if (cur >= max) { ui.notifications.warn(i18n("anomalyFull")); return null }
await anomaly.update({ "system.usesRemaining": Math.min(max, cur + 1) })
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectRegainAnomaly") }))
return i18n("effectRegainAnomaly")
}
case "lose-spleen": {
const cur = actor.system?.spleen?.lvl ?? 0
if (cur <= 0) { ui.notifications.warn(i18n("spleenEmpty")); return null }
await actor.update({ "system.spleen.lvl": Math.max(0, cur - 1) })
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectLoseSpleen") }))
return i18n("effectLoseSpleen")
}
case "gain-destin": {
const cur = actor.system?.destin?.lvl ?? 0
await actor.update({ "system.destin.lvl": Math.min(8, cur + 2) })
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectGainDestin") }))
return i18n("effectGainDestin")
}
case "lose-destin": {
const cur = actor.system?.destin?.lvl ?? 0
await actor.update({ "system.destin.lvl": Math.max(0, cur - 2) })
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectLoseDestin") }))
return i18n("effectLoseDestin")
}
case "lose-anomaly": {
if (!anomaly) { ui.notifications.warn(i18n("noAnomaly")); return null }
const cur = anomaly.system?.usesRemaining ?? 0
if (cur <= 0) { ui.notifications.warn(i18n("anomalyEmpty")); return null }
await anomaly.update({ "system.usesRemaining": Math.max(0, cur - 1) })
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectLoseAnomaly") }))
return i18n("effectLoseAnomaly")
}
case "gain-spleen": {
const cur = actor.system?.spleen?.lvl ?? 0
if (cur >= 8) { ui.notifications.warn(i18n("spleenFull")); return null }
await actor.update({ "system.spleen.lvl": Math.min(8, cur + 1) })
ui.notifications.info(game.i18n.format("CELESTOPOL.Moon.effectApplied", { label: i18n("effectGainSpleen") }))
return i18n("effectGainSpleen")
}
default:
return null
}
}
function _getDefaultFactionAspectState() { function _getDefaultFactionAspectState() {
return { return {
pointsMax: 8, pointsMax: 8,
+38 -3
View File
@@ -58,7 +58,25 @@
"instruction": "Instruction", "instruction": "Instruction",
"mtechnologique": "Merveilleux technologique", "mtechnologique": "Merveilleux technologique",
"raisonnement": "Raisonnement", "raisonnement": "Raisonnement",
"traitement": "Traitement" "traitement": "Traitement",
"tooltip": {
"artifice": "Art du badinage et de la conversation subtile. Permet de se glisser dans une discussion pour glaner des renseignements ou noyer des informations mensongères. Favorise la manipulation et l'incitation plutôt que la contrainte.",
"attraction": "Capacité à orienter les émotions d'un interlocuteur. Sert à plaire, séduire, mais aussi à passer inaperçu lors d'une soirée mondaine.",
"coercition": "Art d'intimider par le regard ou les mots. Couvre également la capacité à donner des ordres dans un contexte militaire ou hiérarchique.",
"faveur": "Rapport de force oral : convaincre, persuader, négocier. S'appuie sur un discours argumentatif pour imposer son point de vue ou emporter l'adhésion.",
"echauffouree": "Techniques de combat à mains nues, avec une arme improvisée, une arme blanche ou des armes à feu et à distance.",
"effacement": "Capacité à être discret et à ne pas se faire repérer. Couvre le camouflage et l'escamotage. Requiert souvent de demeurer immobile.",
"mobilite": "Réflexes et vivacité. Sert pour la conduite, le pilotage, l'équitation, et représente l'initiative d'un protagoniste.",
"prouesse": "Efforts sportifs et physiques : escalade, natation, sprint, force brute et endurance.",
"appreciation": "Observer son environnement de façon exhaustive. Permet de repérer des intrus, des pièges, des guets-apens et des indices.",
"arts": "Domaines artistiques au sens large : musique, littérature, théâtre, prestidigitation. Permet de captiver un auditoire ou de créer des œuvres.",
"inspiration": "Intuition et inconscient : écouter sa petite voix intérieure sans démarche logique préalable. Permet aussi de lire le comportement d'une personne.",
"traque": "Filer un individu ou un groupe, pister et s'orienter. Ouvre également vers les techniques de survie.",
"instruction": "Savoirs encyclopédiques : sciences humaines, sciences dures, sciences sociales et linguistique. Chaque tranche de 2 points permet de maîtriser une langue supplémentaire.",
"mtechnologique": "Technologies extraordinaires de Célestopol : mécanique, automates, ingénierie au sélénium, horlogerie, serrurerie et artisanat.",
"raisonnement": "Capacités cognitives : déduction froide, logique pragmatique, analyse des faits. Utile pour percevoir des liens dans une enquête.",
"traitement": "Techniques médicales et thérapeutiques : premiers secours, chirurgie, pharmacopée, psychanalyse et psychothérapie."
}
}, },
"Anomaly": { "Anomaly": {
"type": "Type d'anomalie", "type": "Type d'anomalie",
@@ -350,7 +368,22 @@
"mauvaiseFortune": "🔴 Mauvaise Fortune", "mauvaiseFortune": "🔴 Mauvaise Fortune",
"chanceInterpret": "Chance", "chanceInterpret": "Chance",
"narrativeInterpret": "Narratif", "narrativeInterpret": "Narratif",
"quantiteHint": "Valeur" "quantiteHint": "Valeur",
"applyChoose": "Choisissez la contrepartie :",
"effectNarrativeOnly": "(Narratif — sans effet mécanique)",
"effectRegainAnomaly": "🌟 Regain d'1 Anomalie",
"effectLoseSpleen": "💚 Perte d'1 Spleen",
"effectGainDestin": "⭐ Gain de 2 Destin",
"effectLoseDestin": "⭐ Perte de 2 Destin",
"effectLoseAnomaly": "❌ Perte d'1 Anomalie",
"effectGainSpleen": "💔 Gain d'1 Spleen",
"effectApplied": "Contrepartie appliquée : {label}",
"noAnomaly": "Ce personnage n'a pas d'anomalie",
"anomalyFull": "L'anomalie est déjà au maximum d'utilisations",
"anomalyEmpty": "L'anomalie n'a plus d'utilisation disponible",
"spleenEmpty": "Le Spleen est déjà à 0",
"spleenFull": "Le Spleen est déjà au maximum",
"actorNotFound": "Personnage introuvable"
}, },
"Difficulty": { "Difficulty": {
"unknown": "Aucun seuil", "unknown": "Aucun seuil",
@@ -449,7 +482,9 @@
"rangeLongue": "Longue portée", "rangeLongue": "Longue portée",
"type": "Type", "type": "Type",
"typeMelee": "Mêlée", "typeMelee": "Mêlée",
"typeDistance": "Distance" "typeDistance": "Distance",
"equip": "Équiper",
"unequip": "Retirer"
}, },
"Armure": { "Armure": {
"protection": "Protection", "protection": "Protection",
@@ -46,6 +46,7 @@ export default class CelestopolActorSheet extends HandlebarsApplicationMixin(fou
skillLevel: CelestopolActorSheet.#onSkillLevel, skillLevel: CelestopolActorSheet.#onSkillLevel,
factionLevel: CelestopolActorSheet.#onFactionLevel, factionLevel: CelestopolActorSheet.#onFactionLevel,
toggleArmure: CelestopolActorSheet.#onToggleArmure, toggleArmure: CelestopolActorSheet.#onToggleArmure,
toggleWeapon: CelestopolActorSheet.#onToggleWeapon,
}, },
} }
@@ -237,6 +238,13 @@ export default class CelestopolActorSheet extends HandlebarsApplicationMixin(fou
if (item?.type === "armure") await item.update({ "system.equipped": !item.system.equipped }) if (item?.type === "armure") await item.update({ "system.equipped": !item.system.equipped })
} }
static async #onToggleWeapon(_event, target) {
const uuid = target.closest('[data-item-uuid]')?.dataset.itemUuid
if (!uuid) return
const item = await fromUuid(uuid)
if (item?.type === "weapon") await item.update({ "system.equipped": !item.system.equipped })
}
static #onFactionLevel(_event, target) { static #onFactionLevel(_event, target) {
if (!this.isEditable) return if (!this.isEditable) return
const factionId = target.dataset.faction const factionId = target.dataset.faction
+16 -16
View File
@@ -31,28 +31,28 @@ export const STATS = {
/** Domaines groupées par attribut. */ /** Domaines groupées par attribut. */
export const SKILLS = { export const SKILLS = {
ame: { ame: {
artifice: { id: "artifice", label: "CELESTOPOL.Skill.artifice", stat: "ame", resThreshold: 5 }, artifice: { id: "artifice", label: "CELESTOPOL.Skill.artifice", tooltip: "CELESTOPOL.Skill.tooltip.artifice", stat: "ame", resThreshold: 5 },
attraction: { id: "attraction", label: "CELESTOPOL.Skill.attraction", stat: "ame", resThreshold: 2 }, attraction: { id: "attraction", label: "CELESTOPOL.Skill.attraction", tooltip: "CELESTOPOL.Skill.tooltip.attraction", stat: "ame", resThreshold: 2 },
coercition: { id: "coercition", label: "CELESTOPOL.Skill.coercition", stat: "ame", resThreshold: 3 }, coercition: { id: "coercition", label: "CELESTOPOL.Skill.coercition", tooltip: "CELESTOPOL.Skill.tooltip.coercition", stat: "ame", resThreshold: 3 },
faveur: { id: "faveur", label: "CELESTOPOL.Skill.faveur", stat: "ame", resThreshold: 6 }, faveur: { id: "faveur", label: "CELESTOPOL.Skill.faveur", tooltip: "CELESTOPOL.Skill.tooltip.faveur", stat: "ame", resThreshold: 6 },
}, },
corps: { corps: {
echauffouree: { id: "echauffouree", label: "CELESTOPOL.Skill.echauffouree", stat: "corps", resThreshold: 6 }, echauffouree: { id: "echauffouree", label: "CELESTOPOL.Skill.echauffouree", tooltip: "CELESTOPOL.Skill.tooltip.echauffouree", stat: "corps", resThreshold: 6 },
effacement: { id: "effacement", label: "CELESTOPOL.Skill.effacement", stat: "corps", resThreshold: 3 }, effacement: { id: "effacement", label: "CELESTOPOL.Skill.effacement", tooltip: "CELESTOPOL.Skill.tooltip.effacement", stat: "corps", resThreshold: 3 },
mobilite: { id: "mobilite", label: "CELESTOPOL.Skill.mobilite", stat: "corps", resThreshold: 2 }, mobilite: { id: "mobilite", label: "CELESTOPOL.Skill.mobilite", tooltip: "CELESTOPOL.Skill.tooltip.mobilite", stat: "corps", resThreshold: 2 },
prouesse: { id: "prouesse", label: "CELESTOPOL.Skill.prouesse", stat: "corps", resThreshold: 5 }, prouesse: { id: "prouesse", label: "CELESTOPOL.Skill.prouesse", tooltip: "CELESTOPOL.Skill.tooltip.prouesse", stat: "corps", resThreshold: 5 },
}, },
coeur: { coeur: {
appreciation: { id: "appreciation", label: "CELESTOPOL.Skill.appreciation", stat: "coeur", resThreshold: 6 }, appreciation: { id: "appreciation", label: "CELESTOPOL.Skill.appreciation", tooltip: "CELESTOPOL.Skill.tooltip.appreciation", stat: "coeur", resThreshold: 6 },
arts: { id: "arts", label: "CELESTOPOL.Skill.arts", stat: "coeur", resThreshold: 2 }, arts: { id: "arts", label: "CELESTOPOL.Skill.arts", tooltip: "CELESTOPOL.Skill.tooltip.arts", stat: "coeur", resThreshold: 2 },
inspiration: { id: "inspiration", label: "CELESTOPOL.Skill.inspiration", stat: "coeur", resThreshold: 3 }, inspiration: { id: "inspiration", label: "CELESTOPOL.Skill.inspiration", tooltip: "CELESTOPOL.Skill.tooltip.inspiration", stat: "coeur", resThreshold: 3 },
traque: { id: "traque", label: "CELESTOPOL.Skill.traque", stat: "coeur", resThreshold: 5 }, traque: { id: "traque", label: "CELESTOPOL.Skill.traque", tooltip: "CELESTOPOL.Skill.tooltip.traque", stat: "coeur", resThreshold: 5 },
}, },
esprit: { esprit: {
instruction: { id: "instruction", label: "CELESTOPOL.Skill.instruction", stat: "esprit", resThreshold: 2 }, instruction: { id: "instruction", label: "CELESTOPOL.Skill.instruction", tooltip: "CELESTOPOL.Skill.tooltip.instruction", stat: "esprit", resThreshold: 2 },
mtechnologique: { id: "mtechnologique", label: "CELESTOPOL.Skill.mtechnologique", stat: "esprit", resThreshold: 6 }, mtechnologique: { id: "mtechnologique", label: "CELESTOPOL.Skill.mtechnologique", tooltip: "CELESTOPOL.Skill.tooltip.mtechnologique", stat: "esprit", resThreshold: 6 },
raisonnement: { id: "raisonnement", label: "CELESTOPOL.Skill.raisonnement", stat: "esprit", resThreshold: 5 }, raisonnement: { id: "raisonnement", label: "CELESTOPOL.Skill.raisonnement", tooltip: "CELESTOPOL.Skill.tooltip.raisonnement", stat: "esprit", resThreshold: 5 },
traitement: { id: "traitement", label: "CELESTOPOL.Skill.traitement", stat: "esprit", resThreshold: 3 }, traitement: { id: "traitement", label: "CELESTOPOL.Skill.traitement", tooltip: "CELESTOPOL.Skill.tooltip.traitement", stat: "esprit", resThreshold: 3 },
}, },
} }
+42 -17
View File
@@ -320,6 +320,8 @@ export class CelestopolRoll extends Roll {
: null : null
const resolvedWeaponName = (isRangedDefense && selectedCombatTarget?.weaponName) ? selectedCombatTarget.weaponName : weaponName const resolvedWeaponName = (isRangedDefense && selectedCombatTarget?.weaponName) ? selectedCombatTarget.weaponName : weaponName
const resolvedWeaponDegats = (isRangedDefense && selectedCombatTarget?.weaponDegats) ? selectedCombatTarget.weaponDegats : weaponDegats const resolvedWeaponDegats = (isRangedDefense && selectedCombatTarget?.weaponDegats) ? selectedCombatTarget.weaponDegats : weaponDegats
// Dégâts de l'arme adverse en cas d'échec (arme équipée du PNJ ciblé en mêlée, arme distance en esquive)
const incomingWeaponDegats = selectedCombatTarget?.weaponDegats ?? resolvedWeaponDegats
const targetActorId = selectedCombatTarget?.id || "" const targetActorId = selectedCombatTarget?.id || ""
const targetActorUuid = selectedCombatTarget?.uuid || "" const targetActorUuid = selectedCombatTarget?.uuid || ""
const targetActorName = selectedCombatTarget?.name || "" const targetActorName = selectedCombatTarget?.name || ""
@@ -373,6 +375,7 @@ export class CelestopolRoll extends Roll {
weaponType, weaponType,
weaponName: resolvedWeaponName, weaponName: resolvedWeaponName,
weaponDegats: resolvedWeaponDegats, weaponDegats: resolvedWeaponDegats,
incomingWeaponDegats,
targetActorId, targetActorId,
targetActorUuid, targetActorUuid,
targetActorName, targetActorName,
@@ -383,7 +386,7 @@ export class CelestopolRoll extends Roll {
puiserRessources: effectivePuiser, puiserRessources: effectivePuiser,
nbDice: (!isResistance && useFortune) ? 1 : nbDice, nbDice: (!isResistance && useFortune) ? 1 : nbDice,
formula, formula,
rollMode: rollContext.visibility ?? "publicroll", rollMode: rollContext.visibility ?? "public",
rollMoonDie: effectiveMoon, rollMoonDie: effectiveMoon,
moonDieResult, moonDieResult,
moonFace, moonFace,
@@ -407,9 +410,9 @@ export class CelestopolRoll extends Roll {
} }
} }
// Mêlée échouée OU défense à distance échouée → le protagoniste subit les dégâts de l'arme PNJ // Mêlée échouée OU défense à distance échouée → le protagoniste (PJ uniquement) subit les dégâts de l'arme PNJ
if (isCombat && (weaponType === "melee" || isRangedDefense) && actor && roll.options.resultType === "failure") { if (isCombat && (weaponType === "melee" || isRangedDefense) && actor?.type === "character" && roll.options.resultType === "failure") {
const incomingWounds = this.getIncomingWounds(resolvedWeaponDegats) const incomingWounds = this.getIncomingWounds(roll.options.incomingWeaponDegats ?? resolvedWeaponDegats)
const protection = this.getActorArmorProtection(actor) const protection = this.getActorArmorProtection(actor)
const appliedWounds = incomingWounds === null const appliedWounds = incomingWounds === null
? 1 ? 1
@@ -555,6 +558,13 @@ export class CelestopolRoll extends Roll {
? Math.max(0, incomingWounds - selectedTargetProtection) ? Math.max(0, incomingWounds - selectedTargetProtection)
: null : null
// Type de l'acteur qui lance le jet (character | npc)
const rollingActor = await this.constructor.resolveActor({
actorUuid: this.options.actorUuid ?? null,
actorId: this.options.actorId ?? null,
})
const actorType = rollingActor?.type ?? this.options.actorType ?? null
// Libellé de difficulté : en combat "Corps PNJ : N", en opposition "vs ?", sinon "Seuil : 11" // Libellé de difficulté : en combat "Corps PNJ : N", en opposition "vs ?", sinon "Seuil : 11"
const difficultyLabel = this.options.isCombat const difficultyLabel = this.options.isCombat
? `${game.i18n.localize("CELESTOPOL.Combat.corpsPnj")} : ${threshold}` ? `${game.i18n.localize("CELESTOPOL.Combat.corpsPnj")} : ${threshold}`
@@ -600,6 +610,8 @@ export class CelestopolRoll extends Roll {
woundLabel, woundLabel,
isResistance: this.options.isResistance ?? false, isResistance: this.options.isResistance ?? false,
isCombat: this.options.isCombat ?? false, isCombat: this.options.isCombat ?? false,
actorType,
isNpcAttack: actorType === "npc",
weaponName: this.options.weaponName ?? null, weaponName: this.options.weaponName ?? null,
weaponDegats, weaponDegats,
weaponType: this.options.weaponType ?? null, weaponType: this.options.weaponType ?? null,
@@ -627,6 +639,10 @@ export class CelestopolRoll extends Roll {
moonResultClass: moonResultType?.cssClass ?? "", moonResultClass: moonResultType?.cssClass ?? "",
moonResultLabel: moonResultType ? game.i18n.localize(moonResultType.label) : "", moonResultLabel: moonResultType ? game.i18n.localize(moonResultType.label) : "",
moonResultDesc: moonResultType ? game.i18n.localize(moonResultType.desc) : "", moonResultDesc: moonResultType ? game.i18n.localize(moonResultType.desc) : "",
moonResultTypeId: moonResultType?.id ?? null,
moonActorId: (actorType === "character") ? (this.options.actorId ?? null) : null,
moonActorUuid: (actorType === "character") ? (this.options.actorUuid ?? null) : null,
moonActorIsCharacter: actorType === "character",
isPrivate, isPrivate,
tooltip: isPrivate ? "" : await this.getTooltip(), tooltip: isPrivate ? "" : await this.getTooltip(),
} }
@@ -634,11 +650,20 @@ export class CelestopolRoll extends Roll {
/** @override */ /** @override */
async toMessage(messageData = {}, { messageMode, rollMode, create = true } = {}) { async toMessage(messageData = {}, { messageMode, rollMode, create = true } = {}) {
if (rollMode) { const modernToLegacyRollMode = {
messageMode = Roll._mapLegacyRollMode(rollMode) public: CONST.DICE_ROLL_MODES.PUBLIC,
gm: CONST.DICE_ROLL_MODES.PRIVATE,
blind: CONST.DICE_ROLL_MODES.BLIND,
self: CONST.DICE_ROLL_MODES.SELF,
ic: CONST.DICE_ROLL_MODES.PUBLIC,
} }
messageMode ||= game.settings.get("core", "messageMode") let effectiveRollMode = rollMode ?? messageMode ?? game.settings.get("core", "rollMode") ?? CONST.DICE_ROLL_MODES.PUBLIC
if (!this._evaluated) await this.evaluate({ allowInteractive: messageMode !== "blind" }) effectiveRollMode = modernToLegacyRollMode[effectiveRollMode] ?? effectiveRollMode
if (!Object.values(CONST.DICE_ROLL_MODES).includes(effectiveRollMode)) {
effectiveRollMode = game.settings.get("core", "rollMode") ?? CONST.DICE_ROLL_MODES.PUBLIC
}
if (!this._evaluated) await this.evaluate({ allowInteractive: effectiveRollMode !== CONST.DICE_ROLL_MODES.BLIND })
const skillLocalized = this.skillLabel ? game.i18n.localize(this.skillLabel) : "" const skillLocalized = this.skillLabel ? game.i18n.localize(this.skillLabel) : ""
const statLocalized = this.options.statLabel const statLocalized = this.options.statLabel
@@ -650,7 +675,7 @@ export class CelestopolRoll extends Roll {
actorUuid: this.options.actorUuid ?? null, actorUuid: this.options.actorUuid ?? null,
actorId: this.options.actorId ?? null, actorId: this.options.actorId ?? null,
}) })
const content = await this.render({ isPrivate: messageMode !== "public" }) const content = await this.render({ isPrivate: effectiveRollMode !== CONST.DICE_ROLL_MODES.PUBLIC })
const chatData = foundry.utils.mergeObject({ const chatData = foundry.utils.mergeObject({
author: game.user.id, author: game.user.id,
content, content,
@@ -660,13 +685,9 @@ export class CelestopolRoll extends Roll {
speaker: speakerActor ? ChatMessage.getSpeaker({ actor: speakerActor }) : undefined, speaker: speakerActor ? ChatMessage.getSpeaker({ actor: speakerActor }) : undefined,
style: CONST.CHAT_MESSAGE_STYLES.OTHER, style: CONST.CHAT_MESSAGE_STYLES.OTHER,
}, messageData) }, messageData)
ChatMessage.applyRollMode(chatData, effectiveRollMode)
const cls = foundry.utils.getDocumentClass("ChatMessage") if (create) return ChatMessage.create(chatData)
const msg = new cls(chatData) return chatData
msg.applyMode(messageMode)
if (create) return cls.create(msg)
return msg.toObject()
} }
/** /**
@@ -681,6 +702,7 @@ export class CelestopolRoll extends Roll {
const resultType = face ? SYSTEM.MOON_RESULT_TYPES[face.result] ?? null : null const resultType = face ? SYSTEM.MOON_RESULT_TYPES[face.result] ?? null : null
const isGoodFortune = result <= 4 const isGoodFortune = result <= 4
const actorIsCharacter = actor?.type === "character"
const templateData = { const templateData = {
result, result,
moonFaceSymbol: face?.symbol ?? "", moonFaceSymbol: face?.symbol ?? "",
@@ -688,8 +710,12 @@ export class CelestopolRoll extends Roll {
moonResultLabel: resultType ? game.i18n.localize(resultType.label) : "", moonResultLabel: resultType ? game.i18n.localize(resultType.label) : "",
moonResultDesc: resultType ? game.i18n.localize(resultType.desc) : "", moonResultDesc: resultType ? game.i18n.localize(resultType.desc) : "",
moonResultClass: resultType?.cssClass ?? "", moonResultClass: resultType?.cssClass ?? "",
moonResultTypeId: resultType?.id ?? null,
isGoodFortune, isGoodFortune,
actorName: actor?.name ?? null, actorName: actor?.name ?? null,
moonActorIsCharacter: actorIsCharacter,
moonActorId: actorIsCharacter ? (actor.id ?? null) : null,
moonActorUuid: actorIsCharacter ? (actor.uuid ?? null) : null,
} }
const content = await foundry.applications.handlebars.renderTemplate( const content = await foundry.applications.handlebars.renderTemplate(
@@ -704,7 +730,6 @@ export class CelestopolRoll extends Roll {
await ChatMessage.create({ await ChatMessage.create({
content, content,
speaker, speaker,
rolls: [roll],
style: CONST.CHAT_MESSAGE_STYLES.OTHER, style: CONST.CHAT_MESSAGE_STYLES.OTHER,
}) })
} }
+32 -36
View File
@@ -13,8 +13,6 @@
import { SYSTEM } from "../config/system.mjs" import { SYSTEM } from "../config/system.mjs"
const WEAPON_DAMAGE_PRIORITY = { "0": 0, "1": 1, "2": 2, X: 3 }
export default class CelestopolCharacter extends foundry.abstract.TypeDataModel { export default class CelestopolCharacter extends foundry.abstract.TypeDataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields const fields = foundry.data.fields
@@ -233,7 +231,7 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
woundLevel: this.blessures.lvl, woundLevel: this.blessures.lvl,
difficulty: this.prefs.difficulty, difficulty: this.prefs.difficulty,
rollMoonDie: this.prefs.rollMoonDie ?? false, rollMoonDie: this.prefs.rollMoonDie ?? false,
destGaugeFull: this.destin.lvl > 0, destGaugeFull: this.destin.lvl >= 8,
fortuneValue: this.attributs.fortune.value, fortuneValue: this.attributs.fortune.value,
}) })
} }
@@ -275,40 +273,39 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
* Collecte les cibles de combat sur la scène active. * Collecte les cibles de combat sur la scène active.
* Pour un PJ attaquant, seules les cibles PNJ présentes sur la scène sont proposées. * Pour un PJ attaquant, seules les cibles PNJ présentes sur la scène sont proposées.
* @param {object} options * @param {object} options
* @param {boolean} [options.onlyRanged=false] * @param {boolean} [options.onlyRanged=false] - Filtrer sur les PNJ ayant une arme à distance équipée
* @param {boolean} [options.fallbackToAll=false] * @param {boolean} [options.fallbackToAll=false] - Revenir à tous les PNJ si aucune cible trouvée
* @param {boolean} [options.includeMeleeWeapon=false] - Inclure l'arme de mêlée équipée du PNJ (dégâts adverses)
* @returns {Array<{id:string, uuid:string, name:string, corps:number, weaponName?:string, weaponDegats?:string}>} * @returns {Array<{id:string, uuid:string, name:string, corps:number, weaponName?:string, weaponDegats?:string}>}
*/ */
_getCombatTargets({ onlyRanged = false, fallbackToAll = false } = {}) { _getCombatTargets({ onlyRanged = false, fallbackToAll = false, includeMeleeWeapon = false } = {}) {
const getBestRangedWeapon = actor => { const getEquippedWeapon = (actor, type) =>
const rangedWeapons = actor.itemTypes?.weapon?.filter(item => item.system.type === "distance") ?? [] actor.itemTypes?.weapon?.find(item => item.system.type === type && item.system.equipped) ?? null
if (!rangedWeapons.length) return null
return rangedWeapons.reduce((best, item) => {
if (!best) return item
const bestPriority = WEAPON_DAMAGE_PRIORITY[best.system.degats] ?? -1
const itemPriority = WEAPON_DAMAGE_PRIORITY[item.system.degats] ?? -1
if (itemPriority !== bestPriority) return itemPriority > bestPriority ? item : best
return item.name.localeCompare(best.name) < 0 ? item : best
}, null)
}
const toEntry = actor => ({ const toEntry = actor => {
const entry = {
id: actor.id, id: actor.id,
uuid: actor.uuid, uuid: actor.uuid,
name: actor.name, name: actor.name,
corps: actor.system.stats?.corps?.res ?? 0, corps: actor.system.stats?.corps?.res ?? 0,
...(onlyRanged ? (() => { }
const weapon = getBestRangedWeapon(actor) if (onlyRanged) {
return weapon ? { const weapon = getEquippedWeapon(actor, "distance")
weaponName: weapon.name, if (weapon) {
weaponDegats: weapon.system.degats, entry.weaponName = weapon.name
} : {} entry.weaponDegats = weapon.system.degats
})() : {}), }
}) } else if (includeMeleeWeapon) {
const weapon = getEquippedWeapon(actor, "melee")
entry.weaponDegats = weapon ? weapon.system.degats : "0"
}
return entry
}
const sceneTokens = canvas?.scene?.isView ? (canvas.tokens?.placeables ?? []) : [] const sceneTokens = canvas?.scene?.isView ? (canvas.tokens?.placeables ?? []) : []
const targets = [...new Map(sceneTokens const targets = [...new Map(sceneTokens
.filter(t => t.actor?.type === "npc" && t.actor.id !== this.parent.id) .filter(t => t.actor?.type === "npc" && t.actor.id !== this.parent.id)
.filter(t => !onlyRanged || getBestRangedWeapon(t.actor)) .filter(t => !onlyRanged || getEquippedWeapon(t.actor, "distance"))
.map(t => { .map(t => {
const actor = t.actor const actor = t.actor
return [actor.uuid, toEntry(actor)] return [actor.uuid, toEntry(actor)]
@@ -346,20 +343,19 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"), armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"),
woundLevel: this.blessures.lvl, woundLevel: this.blessures.lvl,
rollMoonDie: this.prefs.rollMoonDie ?? false, rollMoonDie: this.prefs.rollMoonDie ?? false,
destGaugeFull: this.destin.lvl > 0, destGaugeFull: this.destin.lvl >= 8,
fortuneValue: this.attributs.fortune.value, fortuneValue: this.attributs.fortune.value,
isCombat: true, isCombat: true,
isRangedDefense: false, isRangedDefense: false,
weaponType: item.system.type, weaponType: item.system.type,
weaponName: item.name, weaponName: item.name,
weaponDegats: item.system.degats, weaponDegats: item.system.degats,
availableTargets: this._getCombatTargets(), availableTargets: this._getCombatTargets({ includeMeleeWeapon: item.system.type === "melee" }),
}) })
} }
/** /**
* Lance une attaque de mêlée à mains nues. * Lance une attaque à mains nues (Échauffourée sans arme).
* @returns {Promise<import("../documents/roll.mjs").CelestopolRoll|null>}
*/ */
async rollUnarmedAttack() { async rollUnarmedAttack() {
const { CelestopolRoll } = await import("../documents/roll.mjs") const { CelestopolRoll } = await import("../documents/roll.mjs")
@@ -380,14 +376,14 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"), armorMalus: this.getArmorMalusForRoll("corps", "echauffouree"),
woundLevel: this.blessures.lvl, woundLevel: this.blessures.lvl,
rollMoonDie: this.prefs.rollMoonDie ?? false, rollMoonDie: this.prefs.rollMoonDie ?? false,
destGaugeFull: this.destin.lvl > 0, destGaugeFull: this.destin.lvl >= 8,
fortuneValue: this.attributs.fortune.value, fortuneValue: this.attributs.fortune.value,
isCombat: true, isCombat: true,
isRangedDefense: false, isRangedDefense: false,
weaponType: "melee", weaponType: "melee",
weaponName: game.i18n.localize("CELESTOPOL.Combat.unarmedAttack"), weaponName: game.i18n.localize("CELESTOPOL.Combat.unarmedAttack"),
weaponDegats: "0", weaponDegats: "0",
availableTargets: this._getCombatTargets(), availableTargets: this._getCombatTargets({ includeMeleeWeapon: true }),
}) })
} }
@@ -419,14 +415,14 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
armorMalus: this.getArmorMalusForRoll("corps", "mobilite"), armorMalus: this.getArmorMalusForRoll("corps", "mobilite"),
woundLevel: this.blessures.lvl, woundLevel: this.blessures.lvl,
rollMoonDie: this.prefs.rollMoonDie ?? false, rollMoonDie: this.prefs.rollMoonDie ?? false,
destGaugeFull: this.destin.lvl > 0, destGaugeFull: this.destin.lvl >= 8,
fortuneValue: this.attributs.fortune.value, fortuneValue: this.attributs.fortune.value,
isCombat: true, isCombat: true,
isRangedDefense: true, isRangedDefense: true,
weaponType: "distance", weaponType: "distance",
weaponName: item.name, weaponName: item.name,
weaponDegats: "0", weaponDegats: "0",
availableTargets: this._getCombatTargets(), availableTargets: this._getCombatTargets({ onlyRanged: true, fallbackToAll: true }),
}) })
} }
@@ -453,7 +449,7 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
armorMalus: this.getArmorMalusForRoll("corps", "mobilite"), armorMalus: this.getArmorMalusForRoll("corps", "mobilite"),
woundLevel: this.blessures.lvl, woundLevel: this.blessures.lvl,
rollMoonDie: this.prefs.rollMoonDie ?? false, rollMoonDie: this.prefs.rollMoonDie ?? false,
destGaugeFull: this.destin.lvl > 0, destGaugeFull: this.destin.lvl >= 8,
fortuneValue: this.attributs.fortune.value, fortuneValue: this.attributs.fortune.value,
isCombat: true, isCombat: true,
isRangedDefense: true, isRangedDefense: true,
+1
View File
@@ -85,6 +85,7 @@ export class CelestopolWeapon extends foundry.abstract.TypeDataModel {
choices: Object.keys(SYSTEM.WEAPON_DAMAGE_TYPES) }), choices: Object.keys(SYSTEM.WEAPON_DAMAGE_TYPES) }),
portee: new fields.StringField({ required: true, nullable: false, initial: "contact", portee: new fields.StringField({ required: true, nullable: false, initial: "contact",
choices: Object.keys(SYSTEM.WEAPON_RANGE_TYPES) }), choices: Object.keys(SYSTEM.WEAPON_RANGE_TYPES) }),
equipped: new fields.BooleanField({ initial: false }),
description: new fields.HTMLField({ required: true, textSearch: true }), description: new fields.HTMLField({ required: true, textSearch: true }),
} }
} }
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000062 MANIFEST-000089
+7 -8
View File
@@ -1,8 +1,7 @@
2026/04/13-13:11:31.249954 7f2a6b7fe6c0 Recovering log #60 2026/04/27-17:34:57.971923 7f57a57ee6c0 Recovering log #86
2026/04/13-13:11:31.302525 7f2a6b7fe6c0 Delete type=3 #58 2026/04/27-17:34:57.982802 7f57a57ee6c0 Delete type=3 #84
2026/04/13-13:11:31.302579 7f2a6b7fe6c0 Delete type=0 #60 2026/04/27-17:34:57.982897 7f57a57ee6c0 Delete type=0 #86
2026/04/13-14:20:41.118813 7f2a69ffb6c0 Level-0 table #65: started 2026/04/27-17:40:33.923146 7f57977fe6c0 Level-0 table #92: started
2026/04/13-14:20:41.118847 7f2a69ffb6c0 Level-0 table #65: 0 bytes OK 2026/04/27-17:40:33.923179 7f57977fe6c0 Level-0 table #92: 0 bytes OK
2026/04/13-14:20:41.156390 7f2a69ffb6c0 Delete type=0 #63 2026/04/27-17:40:33.960133 7f57977fe6c0 Delete type=0 #90
2026/04/13-14:20:41.210923 7f2a69ffb6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end) 2026/04/27-17:40:34.016282 7f57977fe6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
2026/04/13-14:20:41.272745 7f2a69ffb6c0 Manual compaction at level-1 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
+11 -8
View File
@@ -1,8 +1,11 @@
2026/04/13-13:10:44.862648 7ff582bff6c0 Recovering log #56 2026/04/26-21:30:37.725370 7f57a5fef6c0 Delete type=3 #1
2026/04/13-13:10:44.908015 7ff582bff6c0 Delete type=3 #54 2026/04/26-22:44:03.500717 7f57977fe6c0 Level-0 table #87: started
2026/04/13-13:10:44.908061 7ff582bff6c0 Delete type=0 #56 2026/04/26-22:44:03.500753 7f57977fe6c0 Level-0 table #87: 0 bytes OK
2026/04/13-13:10:47.939764 7ff580bfb6c0 Level-0 table #61: started 2026/04/26-22:44:03.506825 7f57977fe6c0 Delete type=0 #85
2026/04/13-13:10:47.939788 7ff580bfb6c0 Level-0 table #61: 0 bytes OK 2026/04/26-22:44:03.534971 7f57977fe6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 1 : 1
2026/04/13-13:10:47.972855 7ff580bfb6c0 Delete type=0 #59 2026/04/26-22:44:03.534983 7f57977fe6c0 Compacting 1@0 + 0@1 files
2026/04/13-13:10:47.973045 7ff580bfb6c0 Manual compaction at level-0 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.538403 7f57977fe6c0 Generated table #88@0: 6 keys, 5441 bytes
2026/04/13-13:10:48.030502 7ff580bfb6c0 Manual compaction at level-1 from '!journal!eNYstmPK0mMmVJYC' @ 72057594037927935 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.538450 7f57977fe6c0 Compacted 1@0 + 0@1 files => 5441 bytes
2026/04/26-22:44:03.544821 7f57977fe6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/04/26-22:44:03.545059 7f57977fe6c0 Delete type=2 #5
2026/04/26-22:44:03.555755 7f57977fe6c0 Manual compaction at level-0 from '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 1 : 1 .. '!journal.pages!eNYstmPK0mMmVJYC.r9h1ggd3G9hiqYJX' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000112 MANIFEST-000147
+14 -15
View File
@@ -1,15 +1,14 @@
2026/04/13-13:11:31.130509 7f2a6bfff6c0 Recovering log #109 2026/04/27-17:34:57.942157 7f5797fff6c0 Recovering log #144
2026/04/13-13:11:31.189864 7f2a6bfff6c0 Delete type=3 #107 2026/04/27-17:34:57.953303 7f5797fff6c0 Delete type=3 #142
2026/04/13-13:11:31.189928 7f2a6bfff6c0 Delete type=0 #109 2026/04/27-17:34:57.953395 7f5797fff6c0 Delete type=0 #144
2026/04/13-14:20:41.156517 7f2a69ffb6c0 Level-0 table #115: started 2026/04/27-17:40:33.795334 7f57977fe6c0 Level-0 table #150: started
2026/04/13-14:20:41.173655 7f2a69ffb6c0 Level-0 table #115: 3524 bytes OK 2026/04/27-17:40:33.811935 7f57977fe6c0 Level-0 table #150: 3524 bytes OK
2026/04/13-14:20:41.210761 7f2a69ffb6c0 Delete type=0 #113 2026/04/27-17:40:33.849036 7f57977fe6c0 Delete type=0 #148
2026/04/13-14:20:41.210932 7f2a69ffb6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) 2026/04/27-17:40:33.960338 7f57977fe6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 125 : 1
2026/04/13-14:20:41.210963 7f2a69ffb6c0 Manual compaction at level-1 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 97 : 1 2026/04/27-17:40:33.960357 7f57977fe6c0 Compacting 1@0 + 1@1 files
2026/04/13-14:20:41.210970 7f2a69ffb6c0 Compacting 1@1 + 1@2 files 2026/04/27-17:40:33.978560 7f57977fe6c0 Generated table #151@0: 9 keys, 6617 bytes
2026/04/13-14:20:41.229806 7f2a69ffb6c0 Generated table #116@1: 9 keys, 6617 bytes 2026/04/27-17:40:33.978605 7f57977fe6c0 Compacted 1@0 + 1@1 files => 6617 bytes
2026/04/13-14:20:41.229844 7f2a69ffb6c0 Compacted 1@1 + 1@2 files => 6617 bytes 2026/04/27-17:40:34.015833 7f57977fe6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/04/13-14:20:41.272334 7f2a69ffb6c0 compacted to: files[ 0 0 1 0 0 0 0 ] 2026/04/27-17:40:34.015983 7f57977fe6c0 Delete type=2 #146
2026/04/13-14:20:41.272481 7f2a69ffb6c0 Delete type=2 #111 2026/04/27-17:40:34.016171 7f57977fe6c0 Delete type=2 #150
2026/04/13-14:20:41.272658 7f2a69ffb6c0 Delete type=2 #115 2026/04/27-17:40:34.016294 7f57977fe6c0 Manual compaction at level-0 from '!items!null' @ 125 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
2026/04/13-14:20:41.365704 7f2a69ffb6c0 Manual compaction at level-1 from '!items!null' @ 97 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
+12 -15
View File
@@ -1,15 +1,12 @@
2026/04/13-13:10:44.750651 7ff581bfd6c0 Recovering log #104 2026/04/26-21:30:37.676414 7f57a4fed6c0 Delete type=3 #1
2026/04/13-13:10:44.797855 7ff581bfd6c0 Delete type=3 #102 2026/04/26-22:44:03.490255 7f57977fe6c0 Level-0 table #145: started
2026/04/13-13:10:44.797919 7ff581bfd6c0 Delete type=0 #104 2026/04/26-22:44:03.493705 7f57977fe6c0 Level-0 table #145: 3524 bytes OK
2026/04/13-13:10:47.796281 7ff580bfb6c0 Level-0 table #110: started 2026/04/26-22:44:03.500560 7f57977fe6c0 Delete type=0 #143
2026/04/13-13:10:47.824966 7ff580bfb6c0 Level-0 table #110: 3524 bytes OK 2026/04/26-22:44:03.524721 7f57977fe6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 121 : 1
2026/04/13-13:10:47.857042 7ff580bfb6c0 Delete type=0 #108 2026/04/26-22:44:03.524743 7f57977fe6c0 Compacting 2@0 + 0@1 files
2026/04/13-13:10:47.973011 7ff580bfb6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.528390 7f57977fe6c0 Generated table #146@0: 9 keys, 6617 bytes
2026/04/13-13:10:47.973057 7ff580bfb6c0 Manual compaction at level-1 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 93 : 1 2026/04/26-22:44:03.528448 7f57977fe6c0 Compacted 2@0 + 0@1 files => 6617 bytes
2026/04/13-13:10:47.973063 7ff580bfb6c0 Compacting 1@1 + 1@2 files 2026/04/26-22:44:03.534535 7f57977fe6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/04/13-13:10:47.995133 7ff580bfb6c0 Generated table #111@1: 9 keys, 6617 bytes 2026/04/26-22:44:03.534696 7f57977fe6c0 Delete type=2 #140
2026/04/13-13:10:47.995159 7ff580bfb6c0 Compacted 1@1 + 1@2 files => 6617 bytes 2026/04/26-22:44:03.534864 7f57977fe6c0 Delete type=2 #145
2026/04/13-13:10:48.030149 7ff580bfb6c0 compacted to: files[ 0 0 1 0 0 0 0 ] 2026/04/26-22:44:03.555737 7f57977fe6c0 Manual compaction at level-0 from '!items!null' @ 121 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
2026/04/13-13:10:48.030263 7ff580bfb6c0 Delete type=2 #106
2026/04/13-13:10:48.030388 7ff580bfb6c0 Delete type=2 #110
2026/04/13-13:10:48.030511 7ff580bfb6c0 Manual compaction at level-1 from '!items!null' @ 93 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
View File
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000023 MANIFEST-000050
+7 -8
View File
@@ -1,8 +1,7 @@
2026/04/13-13:11:31.193586 7f2a6b7fe6c0 Recovering log #21 2026/04/27-17:34:57.956196 7f57a57ee6c0 Recovering log #47
2026/04/13-13:11:31.247393 7f2a6b7fe6c0 Delete type=3 #19 2026/04/27-17:34:57.967031 7f57a57ee6c0 Delete type=3 #45
2026/04/13-13:11:31.247448 7f2a6b7fe6c0 Delete type=0 #21 2026/04/27-17:34:57.967119 7f57a57ee6c0 Delete type=0 #47
2026/04/13-14:20:41.081350 7f2a69ffb6c0 Level-0 table #26: started 2026/04/27-17:40:33.886478 7f57977fe6c0 Level-0 table #53: started
2026/04/13-14:20:41.081377 7f2a69ffb6c0 Level-0 table #26: 0 bytes OK 2026/04/27-17:40:33.886512 7f57977fe6c0 Level-0 table #53: 0 bytes OK
2026/04/13-14:20:41.118613 7f2a69ffb6c0 Delete type=0 #24 2026/04/27-17:40:33.922981 7f57977fe6c0 Delete type=0 #51
2026/04/13-14:20:41.210913 7f2a69ffb6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end) 2026/04/27-17:40:34.016271 7f57977fe6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
2026/04/13-14:20:41.210940 7f2a69ffb6c0 Manual compaction at level-1 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
+11 -8
View File
@@ -1,8 +1,11 @@
2026/04/13-13:10:44.800502 7ff582bff6c0 Recovering log #16 2026/04/26-21:30:37.703085 7f57a4fed6c0 Delete type=3 #1
2026/04/13-13:10:44.846821 7ff582bff6c0 Delete type=3 #14 2026/04/26-22:44:03.483917 7f57977fe6c0 Level-0 table #48: started
2026/04/13-13:10:44.846886 7ff582bff6c0 Delete type=0 #16 2026/04/26-22:44:03.483998 7f57977fe6c0 Level-0 table #48: 0 bytes OK
2026/04/13-13:10:47.902261 7ff580bfb6c0 Level-0 table #22: started 2026/04/26-22:44:03.490106 7f57977fe6c0 Delete type=0 #46
2026/04/13-13:10:47.902285 7ff580bfb6c0 Level-0 table #22: 0 bytes OK 2026/04/26-22:44:03.513451 7f57977fe6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at '!folders!MbFQgPdF6Gtbj5AU' @ 37 : 1
2026/04/13-13:10:47.939594 7ff580bfb6c0 Delete type=0 #20 2026/04/26-22:44:03.513463 7f57977fe6c0 Compacting 1@0 + 0@1 files
2026/04/13-13:10:47.973036 7ff580bfb6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.517217 7f57977fe6c0 Generated table #49@0: 36 keys, 35733 bytes
2026/04/13-13:10:48.030491 7ff580bfb6c0 Manual compaction at level-1 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.517247 7f57977fe6c0 Compacted 1@0 + 0@1 files => 35733 bytes
2026/04/26-22:44:03.523835 7f57977fe6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/04/26-22:44:03.523973 7f57977fe6c0 Delete type=2 #18
2026/04/26-22:44:03.555713 7f57977fe6c0 Manual compaction at level-0 from '!folders!MbFQgPdF6Gtbj5AU' @ 37 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
View File
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000062 MANIFEST-000092
+7 -8
View File
@@ -1,8 +1,7 @@
2026/04/13-13:11:31.305113 7f2a6a7fc6c0 Recovering log #60 2026/04/27-17:34:57.986104 7f5797fff6c0 Recovering log #89
2026/04/13-13:11:31.358709 7f2a6a7fc6c0 Delete type=3 #58 2026/04/27-17:34:57.996510 7f5797fff6c0 Delete type=3 #87
2026/04/13-13:11:31.358775 7f2a6a7fc6c0 Delete type=0 #60 2026/04/27-17:34:57.996596 7f5797fff6c0 Delete type=0 #89
2026/04/13-14:20:41.045418 7f2a69ffb6c0 Level-0 table #65: started 2026/04/27-17:40:33.849202 7f57977fe6c0 Level-0 table #95: started
2026/04/13-14:20:41.045487 7f2a69ffb6c0 Level-0 table #65: 0 bytes OK 2026/04/27-17:40:33.849252 7f57977fe6c0 Level-0 table #95: 0 bytes OK
2026/04/13-14:20:41.081154 7f2a69ffb6c0 Delete type=0 #63 2026/04/27-17:40:33.886306 7f57977fe6c0 Delete type=0 #93
2026/04/13-14:20:41.210899 7f2a69ffb6c0 Manual compaction at level-0 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end) 2026/04/27-17:40:34.016257 7f57977fe6c0 Manual compaction at level-0 from '!scenes!0iGCRqkdJKjmmbl4' @ 72057594037927935 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 0 : 0; will stop at (end)
2026/04/13-14:20:41.210948 7f2a69ffb6c0 Manual compaction at level-1 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end)
+11 -8
View File
@@ -1,8 +1,11 @@
2026/04/13-13:10:44.916572 7ff5813fc6c0 Recovering log #55 2026/04/26-21:30:37.754039 7f5797fff6c0 Delete type=3 #1
2026/04/13-13:10:44.960340 7ff5813fc6c0 Delete type=3 #53 2026/04/26-22:44:03.507044 7f57977fe6c0 Level-0 table #90: started
2026/04/13-13:10:44.960396 7ff5813fc6c0 Delete type=0 #55 2026/04/26-22:44:03.507095 7f57977fe6c0 Level-0 table #90: 0 bytes OK
2026/04/13-13:10:47.857212 7ff580bfb6c0 Level-0 table #61: started 2026/04/26-22:44:03.513200 7f57977fe6c0 Delete type=0 #88
2026/04/13-13:10:47.857237 7ff580bfb6c0 Level-0 table #61: 0 bytes OK 2026/04/26-22:44:03.545324 7f57977fe6c0 Manual compaction at level-0 from '!scenes!0iGCRqkdJKjmmbl4' @ 72057594037927935 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 0 : 0; will stop at '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 61 : 1
2026/04/13-13:10:47.902098 7ff580bfb6c0 Delete type=0 #59 2026/04/26-22:44:03.545342 7f57977fe6c0 Compacting 1@0 + 0@1 files
2026/04/13-13:10:47.973025 7ff580bfb6c0 Manual compaction at level-0 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.549127 7f57977fe6c0 Generated table #91@0: 4 keys, 1746 bytes
2026/04/13-13:10:48.030475 7ff580bfb6c0 Manual compaction at level-1 from '!scenes!Jr7lGxYk2RETlXRv' @ 72057594037927935 : 1 .. '!scenes.tokens.delta.items!Jr7lGxYk2RETlXRv.6urwC5SVcou6UOAG.CTg4yBE12iMee1RU.BYT1CrA37R3Og0nu' @ 0 : 0; will stop at (end) 2026/04/26-22:44:03.549142 7f57977fe6c0 Compacted 1@0 + 0@1 files => 1746 bytes
2026/04/26-22:44:03.555374 7f57977fe6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/04/26-22:44:03.555539 7f57977fe6c0 Delete type=2 #85
2026/04/26-22:44:03.555771 7f57977fe6c0 Manual compaction at level-0 from '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 61 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 0 : 0; will stop at (end)
Binary file not shown.
Binary file not shown.
View File
+44 -44
View File
@@ -24,7 +24,7 @@
min-width: 54px; min-width: 54px;
label { label {
font-size: 0.58em; font-size: 0.6em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
color: var(--cel-orange-light); color: var(--cel-orange-light);
@@ -34,12 +34,12 @@
.stat-value, .attr-display { .stat-value, .attr-display {
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.05em; font-size: 1.2em;
font-weight: bold; font-weight: bold;
line-height: 1.2; line-height: 1.2;
} }
.attr-sep { color: rgba(196,154,26,0.5); margin: 0 1px; font-size: 0.85em; } .attr-sep { color: rgba(196,154,26,0.5); margin: 0 1px; font-size: 0.8em; }
input.attr-val, input.attr-max { input.attr-val, input.attr-max {
width: 24px; width: 24px;
@@ -49,7 +49,7 @@
border-bottom: 1px solid var(--cel-orange-light); border-bottom: 1px solid var(--cel-orange-light);
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
} }
} }
@@ -60,7 +60,7 @@
.armor-malus-value { .armor-malus-value {
color: #e06040; color: #e06040;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.05em; font-size: 1.2em;
font-weight: bold; font-weight: bold;
} }
label { color: #e06040; opacity: 0.8; } label { color: #e06040; opacity: 0.8; }
@@ -92,7 +92,7 @@
.stat-name { .stat-name {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-weight: bold; font-weight: bold;
font-size: 1em; font-size: 1.1em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
} }
@@ -121,7 +121,7 @@
border: 1px solid var(--cel-orange); border: 1px solid var(--cel-orange);
border-radius: 4px; border-radius: 4px;
background: rgba(224, 123, 0, 0.08); background: rgba(224, 123, 0, 0.08);
font-size: 0.78em; font-size: 0.8em;
cursor: default; cursor: default;
.res-die-icon { .res-die-icon {
@@ -164,7 +164,7 @@
justify-content: space-between; justify-content: space-between;
padding: 3px 8px; padding: 3px 8px;
border-bottom: 1px solid rgba(122,92,32,0.18); border-bottom: 1px solid rgba(122,92,32,0.18);
font-size: 0.85em; font-size: 0.8em;
// Alternating cream-dark rows for legibility // Alternating cream-dark rows for legibility
&:nth-child(even) { background: var(--cel-cream-dark); } &:nth-child(even) { background: var(--cel-cream-dark); }
@@ -279,7 +279,7 @@
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
font-size: 1.1em; font-size: 1.2em;
letter-spacing: 0.04em; letter-spacing: 0.04em;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -293,7 +293,7 @@
height: 14px; height: 14px;
border-radius: 50%; border-radius: 50%;
border: 1px solid currentColor; border: 1px solid currentColor;
font-size: 0.65em; font-size: 0.7em;
font-family: var(--cel-font-body); font-family: var(--cel-font-body);
font-weight: bold; font-weight: bold;
text-transform: none; text-transform: none;
@@ -349,7 +349,7 @@
gap: 6px; gap: 6px;
padding: 4px 8px; padding: 4px 8px;
background: rgba(139,115,85,0.1); background: rgba(139,115,85,0.1);
font-size: 0.85em; font-size: 0.8em;
label { color: var(--cel-border); } label { color: var(--cel-border); }
input[type="number"] { width: 40px; .cel-input-std(); } input[type="number"] { width: 40px; .cel-input-std(); }
} }
@@ -380,7 +380,7 @@
.faction-aspect-summary-title { .faction-aspect-summary-title {
color: var(--cel-green); color: var(--cel-green);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1em; font-size: 1.1em;
letter-spacing: 0.04em; letter-spacing: 0.04em;
text-transform: uppercase; text-transform: uppercase;
line-height: 1.05; line-height: 1.05;
@@ -393,7 +393,7 @@
color: var(--cel-orange); color: var(--cel-orange);
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
font-size: 0.84em; font-size: 0.8em;
white-space: nowrap; white-space: nowrap;
} }
@@ -413,7 +413,7 @@
.label { .label {
display: block; display: block;
font-size: 0.66em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.03em; letter-spacing: 0.03em;
color: var(--cel-border); color: var(--cel-border);
@@ -423,7 +423,7 @@
.value { .value {
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.02em; font-size: 1.1em;
line-height: 1; line-height: 1;
} }
} }
@@ -448,7 +448,7 @@
.faction-aspect-active-title { .faction-aspect-active-title {
margin-bottom: 4px; margin-bottom: 4px;
color: var(--cel-border); color: var(--cel-border);
font-size: 0.68em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
line-height: 1.1; line-height: 1.1;
@@ -477,20 +477,20 @@
.name { .name {
color: var(--cel-green); color: var(--cel-green);
font-size: 0.88em; font-size: 0.9em;
} }
.value { .value {
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.9em; font-size: 1em;
} }
} }
.faction-aspect-empty { .faction-aspect-empty {
color: #666; color: #666;
font-style: italic; font-style: italic;
font-size: 0.84em; font-size: 0.8em;
} }
} }
@@ -505,7 +505,7 @@
background-image: url("../assets/ui/fond_cadrille.jpg"); background-image: url("../assets/ui/fond_cadrille.jpg");
background-blend-mode: soft-light; background-blend-mode: soft-light;
color: var(--cel-orange); color: var(--cel-orange);
th { padding: 5px 8px; font-family: var(--cel-font-title); font-size: 1.05em; letter-spacing: 0.06em; text-transform: uppercase; } th { padding: 5px 8px; font-family: var(--cel-font-title); font-size: 1.2em; letter-spacing: 0.06em; text-transform: uppercase; }
} }
.faction-row { .faction-row {
@@ -542,7 +542,7 @@
} }
.faction-count { .faction-count {
font-size: 0.85em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
color: var(--cel-orange); color: var(--cel-orange);
min-width: 16px; min-width: 16px;
@@ -569,7 +569,7 @@
border-bottom: 1px solid rgba(122,92,32,0.25); border-bottom: 1px solid rgba(122,92,32,0.25);
color: var(--cel-green); color: var(--cel-green);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.05em; font-size: 1.2em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
} }
@@ -578,7 +578,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
font-size: 0.88em; font-size: 0.9em;
} }
.factions-legend-row { .factions-legend-row {
@@ -634,7 +634,7 @@
} }
.item-tag { .item-tag {
font-size: 0.75em; font-size: 0.8em;
padding: 1px 7px; padding: 1px 7px;
border-radius: 10px; border-radius: 10px;
background: rgba(12,76,12,0.15); background: rgba(12,76,12,0.15);
@@ -661,7 +661,7 @@
justify-content: center; justify-content: center;
min-width: 20px; min-width: 20px;
min-height: 20px; min-height: 20px;
font-size: 1.08rem; font-size: 1.1rem;
line-height: 1; line-height: 1;
} }
} }
@@ -684,7 +684,7 @@
} }
.equip-empty { .equip-empty {
font-size: 0.85em; font-size: 0.8em;
font-style: italic; font-style: italic;
color: var(--cel-border); color: var(--cel-border);
padding: 4px 8px; padding: 4px 8px;
@@ -736,7 +736,7 @@
.biography-portrait-empty { .biography-portrait-empty {
padding: 14px; padding: 14px;
color: var(--cel-border); color: var(--cel-border);
font-size: 0.82em; font-size: 0.8em;
font-style: italic; font-style: italic;
text-align: center; text-align: center;
line-height: 1.5; line-height: 1.5;
@@ -769,7 +769,7 @@
border-radius: 4px; border-radius: 4px;
background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95)); background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95));
color: var(--cel-green); color: var(--cel-green);
font-size: 0.82em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
@@ -790,7 +790,7 @@
.biography-portrait-hint { .biography-portrait-hint {
margin: 0; margin: 0;
font-size: 0.78em; font-size: 0.8em;
font-style: italic; font-style: italic;
color: var(--cel-border); color: var(--cel-border);
} }
@@ -838,7 +838,7 @@
text-align: center; text-align: center;
.cel-input-std(); .cel-input-std();
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.1em; font-size: 1.2em;
font-weight: bold; font-weight: bold;
color: var(--cel-green); color: var(--cel-green);
} }
@@ -848,7 +848,7 @@
border-color: rgba(122,92,32,0.4); border-color: rgba(122,92,32,0.4);
.xp-depense-value { .xp-depense-value {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.1em; font-size: 1.2em;
font-weight: bold; font-weight: bold;
color: var(--cel-border); color: var(--cel-border);
} }
@@ -858,7 +858,7 @@
background: var(--cel-green); background: var(--cel-green);
border: 1px solid var(--cel-orange); border: 1px solid var(--cel-orange);
color: var(--cel-orange); color: var(--cel-orange);
font-size: 0.78em; font-size: 0.9em;
padding: 5px 12px; padding: 5px 12px;
cursor: pointer; cursor: pointer;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
@@ -875,14 +875,14 @@
.xp-log-table { .xp-log-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
font-size: 0.82em; font-size: 0.8em;
margin-bottom: 8px; margin-bottom: 8px;
thead tr { thead tr {
background: rgba(12,76,12,0.35); background: rgba(12,76,12,0.35);
th { th {
color: var(--cel-orange-light); color: var(--cel-orange-light);
font-size: 0.75em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
padding: 3px 6px; padding: 3px 6px;
@@ -918,7 +918,7 @@
.xp-ref { .xp-ref {
margin-top: 6px; margin-top: 6px;
summary { summary {
font-size: 0.78em; font-size: 0.8em;
color: var(--cel-orange-light); color: var(--cel-orange-light);
cursor: pointer; cursor: pointer;
letter-spacing: 0.03em; letter-spacing: 0.03em;
@@ -930,7 +930,7 @@
.xp-ref-table { .xp-ref-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
font-size: 0.82em; font-size: 0.8em;
margin-top: 6px; margin-top: 6px;
thead tr { thead tr {
@@ -941,7 +941,7 @@
} }
th { th {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.9em; font-size: 1em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
padding: 4px 8px; padding: 4px 8px;
@@ -987,7 +987,7 @@
.anomaly-block-title { .anomaly-block-title {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.85em; font-size: 0.9em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
color: var(--cel-orange); color: var(--cel-orange);
@@ -1000,7 +1000,7 @@
text-align: center; text-align: center;
color: var(--cel-border); color: var(--cel-border);
font-style: italic; font-style: italic;
font-size: 0.85em; font-size: 0.8em;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -1030,12 +1030,12 @@
flex: 1; flex: 1;
.anomaly-name { .anomaly-name {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1em; font-size: 1.1em;
color: var(--cel-orange); color: var(--cel-orange);
font-weight: bold; font-weight: bold;
} }
.anomaly-subtype { .anomaly-subtype {
font-size: 0.75em; font-size: 0.8em;
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
@@ -1057,7 +1057,7 @@
margin-bottom: 6px; margin-bottom: 6px;
.anomaly-level-label { .anomaly-level-label {
font-size: 0.72em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
opacity: 0.7; opacity: 0.7;
@@ -1085,7 +1085,7 @@
flex-wrap: wrap; flex-wrap: wrap;
.anomaly-uses-label { .anomaly-uses-label {
font-size: 0.72em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
opacity: 0.7; opacity: 0.7;
@@ -1110,7 +1110,7 @@
background: var(--cel-green); background: var(--cel-green);
border: 1px solid var(--cel-orange); border: 1px solid var(--cel-orange);
color: var(--cel-orange); color: var(--cel-orange);
font-size: 0.72em; font-size: 0.8em;
padding: 2px 8px; padding: 2px 8px;
cursor: pointer; cursor: pointer;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
+2 -2
View File
@@ -1,13 +1,13 @@
@font-face { @font-face {
font-family: "CopaseticNF"; font-family: "CopaseticNF";
src: url("../assets/fonts/CopaseticNF.otf") format("opentype"); src: url("../assets/fonts/CopaseticNF.woff");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
@font-face { @font-face {
font-family: "CopaseticNF"; font-family: "CopaseticNF";
src: url("../assets/fonts/CopaseticNF-Bold.otf") format("opentype"); src: url("../assets/fonts/CopaseticNF-Bold.woff");
font-weight: bold; font-weight: bold;
font-style: normal; font-style: normal;
} }
+9 -8
View File
@@ -16,6 +16,7 @@
--cel-border: #7a5c20; // bordure dorée --cel-border: #7a5c20; // bordure dorée
--cel-accent: #6b1e28; // bordeaux profond (échecs, accents) --cel-accent: #6b1e28; // bordeaux profond (échecs, accents)
--cel-text: #2f2413; // texte de corps sur fond clair (parchemin)
--cel-shadow: rgba(10,15,10,0.5); --cel-shadow: rgba(10,15,10,0.5);
@@ -84,7 +85,7 @@
border-bottom: 1px solid rgba(196,154,26,0.5); border-bottom: 1px solid rgba(196,154,26,0.5);
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.4em; font-size: 1.5em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.06em; letter-spacing: 0.06em;
padding: 2px 4px; padding: 2px 4px;
@@ -93,7 +94,7 @@
.actor-name { .actor-name {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.4em; font-size: 1.5em;
color: var(--cel-orange); color: var(--cel-orange);
letter-spacing: 0.06em; letter-spacing: 0.06em;
margin: 0; margin: 0;
@@ -119,7 +120,7 @@
gap: 4px; gap: 4px;
label { label {
font-size: 0.65em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.06em; letter-spacing: 0.06em;
color: var(--cel-orange-light); color: var(--cel-orange-light);
@@ -130,7 +131,7 @@
// Styles identiques play mode et edit mode // Styles identiques play mode et edit mode
span, span,
input[type="text"] { input[type="text"] {
font-size: 0.95em; font-size: 0.9em;
font-family: inherit; font-family: inherit;
font-style: italic; font-style: italic;
color: var(--cel-cream); color: var(--cel-cream);
@@ -172,14 +173,14 @@
min-width: 52px; min-width: 52px;
label { label {
font-size: 0.62em; font-size: 0.6em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em; letter-spacing: 0.08em;
color: var(--cel-orange-light); color: var(--cel-orange-light);
} }
.stat-value { .stat-value {
font-size: 1.4em; font-size: 1.5em;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
color: var(--cel-orange); color: var(--cel-orange);
font-weight: bold; font-weight: bold;
@@ -241,7 +242,7 @@
padding: 8px 16px; padding: 8px 16px;
color: rgba(240,232,212,0.8); color: rgba(240,232,212,0.8);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.85em; font-size: 0.9em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
cursor: pointer; cursor: pointer;
@@ -330,7 +331,7 @@
.wound-value { .wound-value {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.95em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
white-space: nowrap; white-space: nowrap;
line-height: 1.2; line-height: 1.2;
+20 -20
View File
@@ -22,7 +22,7 @@
.anomaly-section-title { .anomaly-section-title {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.78em; font-size: 0.9em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
color: var(--cel-green-dark, #0c4c0c); color: var(--cel-green-dark, #0c4c0c);
@@ -39,7 +39,7 @@
min-height: 60px; min-height: 60px;
padding: 4px 6px; padding: 4px 6px;
color: #1a1209; color: #1a1209;
font-size: 0.88em; font-size: 0.9em;
line-height: 1.5; line-height: 1.5;
.editor-content, .prosemirror { color: #1a1209; background: transparent; } .editor-content, .prosemirror { color: #1a1209; background: transparent; }
p { margin: 0 0 4px 0; color: #1a1209; } p { margin: 0 0 4px 0; color: #1a1209; }
@@ -77,7 +77,7 @@
border-bottom: 1px solid var(--cel-orange-light); border-bottom: 1px solid var(--cel-orange-light);
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.2em; font-size: 1.3em;
font-weight: bold; font-weight: bold;
padding: 2px 4px; padding: 2px 4px;
} }
@@ -114,7 +114,7 @@
background: transparent; background: transparent;
border: 1px solid var(--cel-orange-light); border: 1px solid var(--cel-orange-light);
color: var(--cel-orange); color: var(--cel-orange);
font-size: 0.85em; font-size: 0.8em;
option { background: var(--cel-green-dark); color: var(--cel-cream); } option { background: var(--cel-green-dark); color: var(--cel-cream); }
} }
} }
@@ -123,7 +123,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
label { color: var(--cel-orange-light); font-size: 0.75em; text-transform: uppercase; } label { color: var(--cel-orange-light); font-size: 0.8em; text-transform: uppercase; }
input[type="number"] { input[type="number"] {
width: 40px; width: 40px;
background: transparent; background: transparent;
@@ -147,7 +147,7 @@
padding: 5px 12px; padding: 5px 12px;
color: rgba(240,232,212,0.7); color: rgba(240,232,212,0.7);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.78em; font-size: 0.9em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
cursor: pointer; cursor: pointer;
@@ -186,7 +186,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
label { color: var(--cel-orange-light); font-size: 0.72em; text-transform: uppercase; } label { color: var(--cel-orange-light); font-size: 0.7em; text-transform: uppercase; }
input[type="number"] { input[type="number"] {
width: 44px; width: 44px;
background: transparent; background: transparent;
@@ -207,7 +207,7 @@
margin-bottom: 8px; margin-bottom: 8px;
label { label {
display: block; display: block;
font-size: 0.75em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
color: var(--cel-border); // #7a5c20 — contraste WCAG AA sur fond crème color: var(--cel-border); // #7a5c20 — contraste WCAG AA sur fond crème
@@ -228,7 +228,7 @@
.scores-stat-col { .scores-stat-col {
.scores-stat-name { .scores-stat-name {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.75em; font-size: 0.8em;
color: var(--cel-orange); // gold color: var(--cel-orange); // gold
text-transform: uppercase; text-transform: uppercase;
border-bottom: 1px solid var(--cel-border); border-bottom: 1px solid var(--cel-border);
@@ -266,7 +266,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
label { color: var(--cel-orange-light); font-size: 0.75em; text-transform: uppercase; } label { color: var(--cel-orange-light); font-size: 0.8em; text-transform: uppercase; }
.level-input, .anomaly-level-value { .level-input, .anomaly-level-value {
width: 38px; width: 38px;
background: transparent; background: transparent;
@@ -301,7 +301,7 @@
border: 1px solid rgba(196,154,26,0.4); border: 1px solid rgba(196,154,26,0.4);
color: var(--cel-orange); color: var(--cel-orange);
text-align: center; text-align: center;
font-size: 0.85em; font-size: 0.8em;
} }
} }
@@ -327,7 +327,7 @@
.anomaly-skills-label { .anomaly-skills-label {
color: var(--cel-orange-light, #c49a1a); color: var(--cel-orange-light, #c49a1a);
font-size: 0.72em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
margin-right: 2px; margin-right: 2px;
@@ -339,7 +339,7 @@
border: 1px solid rgba(196,154,26,0.55); border: 1px solid rgba(196,154,26,0.55);
border-radius: 3px; border-radius: 3px;
padding: 1px 7px; padding: 1px 7px;
font-size: 0.72em; font-size: 0.7em;
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
} }
} }
@@ -368,8 +368,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
label { font-size: 0.75em; color: var(--cel-orange-light); white-space: nowrap; } label { font-size: 0.8em; color: var(--cel-orange-light); white-space: nowrap; }
select { background: rgba(0,0,0,0.3); border: 1px solid var(--cel-orange); color: var(--cel-orange); font-family: var(--cel-font-title); border-radius: 3px; padding: 2px 4px; font-size: 0.85em; } select { background: rgba(0,0,0,0.3); border: 1px solid var(--cel-orange); color: var(--cel-orange); font-family: var(--cel-font-title); border-radius: 3px; padding: 2px 4px; font-size: 0.9em; }
} }
} }
.weapon-damage-badge { .weapon-damage-badge {
@@ -380,9 +380,9 @@
border: 1px solid var(--cel-orange); border: 1px solid var(--cel-orange);
border-radius: 6px; border-radius: 6px;
padding: 6px 12px; padding: 6px 12px;
.damage-label { font-size: 0.72em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; } .damage-label { font-size: 0.7em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; }
.damage-value { font-family: var(--cel-font-title); font-size: 1.6em; font-weight: bold; color: var(--cel-orange); min-width: 28px; text-align: center; } .damage-value { font-family: var(--cel-font-title); font-size: 1.8em; font-weight: bold; color: var(--cel-orange); min-width: 28px; text-align: center; }
.damage-hint { font-size: 0.78em; color: var(--cel-cream); font-style: italic; } .damage-hint { font-size: 0.8em; color: var(--cel-cream); font-style: italic; }
} }
} }
@@ -404,10 +404,10 @@
border-radius: 6px; border-radius: 6px;
padding: 8px 20px; padding: 8px 20px;
min-width: 110px; min-width: 110px;
label { font-size: 0.72em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; } label { font-size: 0.7em; text-transform: uppercase; color: var(--cel-orange-light); letter-spacing: 0.05em; }
.armure-stat-value { .armure-stat-value {
input[type="number"], span { input[type="number"], span {
font-family: var(--cel-font-title); font-size: 1.8em; font-weight: bold; color: var(--cel-orange); font-family: var(--cel-font-title); font-size: 2em; font-weight: bold; color: var(--cel-orange);
text-align: center; background: transparent; border: none; width: 40px; text-align: center; background: transparent; border: none; width: 40px;
} }
} }
+1 -1
View File
@@ -2,7 +2,7 @@
.cel-section-header() { .cel-section-header() {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.78em; font-size: 0.9em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.1em; letter-spacing: 0.1em;
// Gold instead of vivid green — Art Déco elegance // Gold instead of vivid green — Art Déco elegance
+21 -21
View File
@@ -14,12 +14,12 @@
color: var(--cel-orange); color: var(--cel-orange);
border-radius: 3px; border-radius: 3px;
padding: 2px 6px; padding: 2px 6px;
font-size: 0.85em; font-size: 0.8em;
} }
.npc-type-badge { .npc-type-badge {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.8em; font-size: 0.9em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
border-radius: 3px; border-radius: 3px;
@@ -65,14 +65,14 @@
.domain-label-primary { .domain-label-primary {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-weight: bold; font-weight: bold;
font-size: 1.1em; font-size: 1.2em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.06em; letter-spacing: 0.06em;
color: var(--cel-orange); color: var(--cel-orange);
} }
.domain-label-secondary { .domain-label-secondary {
font-size: 0.75em; font-size: 0.8em;
color: rgba(220,170,80,0.7); color: rgba(220,170,80,0.7);
font-style: italic; font-style: italic;
text-transform: uppercase; text-transform: uppercase;
@@ -88,7 +88,7 @@
input.domain-value-input { input.domain-value-input {
width: 40px; width: 40px;
.cel-input-std(); .cel-input-std();
font-size: 1.2em; font-size: 1.3em;
text-align: center; text-align: center;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
} }
@@ -116,7 +116,7 @@
.domain-value { .domain-value {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.4em; font-size: 1.5em;
font-weight: bold; font-weight: bold;
color: var(--cel-orange); color: var(--cel-orange);
min-width: 20px; min-width: 20px;
@@ -124,7 +124,7 @@
} }
.domain-value-base { .domain-value-base {
font-size: 0.75em; font-size: 0.8em;
color: rgba(220,170,80,0.6); color: rgba(220,170,80,0.6);
font-style: italic; font-style: italic;
} }
@@ -151,7 +151,7 @@
padding: 5px 10px; padding: 5px 10px;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-weight: bold; font-weight: bold;
font-size: 0.9em; font-size: 1em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.06em; letter-spacing: 0.06em;
border-bottom: 1px solid rgba(196,154,26,0.4); border-bottom: 1px solid rgba(196,154,26,0.4);
@@ -197,7 +197,7 @@
color: var(--cel-orange); color: var(--cel-orange);
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-weight: bold; font-weight: bold;
font-size: 0.9em; font-size: 1em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.06em; letter-spacing: 0.06em;
border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0;
@@ -222,13 +222,13 @@
.faction-name { .faction-name {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
color: var(--cel-orange); color: var(--cel-orange);
font-size: 0.95em; font-size: 1.1em;
} }
.faction-none { .faction-none {
font-style: italic; font-style: italic;
color: rgba(122,92,32,0.5); color: rgba(122,92,32,0.5);
font-size: 0.85em; font-size: 0.8em;
} }
} }
@@ -242,7 +242,7 @@
border-top: none; border-top: none;
border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;
label { font-size: 0.85em; color: var(--cel-brown); } label { font-size: 0.8em; color: var(--cel-brown); }
select { flex: 1; .cel-input-std(); } select { flex: 1; .cel-input-std(); }
} }
} }
@@ -269,7 +269,7 @@
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
font-size: 1.1em; font-size: 1.2em;
letter-spacing: 0.04em; letter-spacing: 0.04em;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -284,7 +284,7 @@
height: 14px; height: 14px;
border-radius: 50%; border-radius: 50%;
border: 1px solid currentColor; border: 1px solid currentColor;
font-size: 0.65em; font-size: 0.7em;
font-family: var(--cel-font-body); font-family: var(--cel-font-body);
font-weight: bold; font-weight: bold;
text-transform: none; text-transform: none;
@@ -340,7 +340,7 @@
gap: 6px; gap: 6px;
padding: 4px 8px; padding: 4px 8px;
background: rgba(139,115,85,0.1); background: rgba(139,115,85,0.1);
font-size: 0.85em; font-size: 0.8em;
label { color: var(--cel-border); } label { color: var(--cel-border); }
input[type="number"] { width: 40px; .cel-input-std(); } input[type="number"] { width: 40px; .cel-input-std(); }
} }
@@ -372,7 +372,7 @@
} }
.item-tag { .item-tag {
font-size: 0.75em; font-size: 0.8em;
padding: 1px 7px; padding: 1px 7px;
border-radius: 10px; border-radius: 10px;
background: rgba(12,76,12,0.15); background: rgba(12,76,12,0.15);
@@ -399,14 +399,14 @@
justify-content: center; justify-content: center;
min-width: 20px; min-width: 20px;
min-height: 20px; min-height: 20px;
font-size: 1.08rem; font-size: 1.1rem;
line-height: 1; line-height: 1;
} }
} }
} }
.equip-empty { .equip-empty {
font-size: 0.85em; font-size: 0.8em;
font-style: italic; font-style: italic;
color: var(--cel-border); color: var(--cel-border);
padding: 4px 8px; padding: 4px 8px;
@@ -465,7 +465,7 @@
.biography-portrait-empty { .biography-portrait-empty {
padding: 14px; padding: 14px;
color: var(--cel-border); color: var(--cel-border);
font-size: 0.82em; font-size: 0.8em;
font-style: italic; font-style: italic;
text-align: center; text-align: center;
line-height: 1.5; line-height: 1.5;
@@ -498,7 +498,7 @@
border-radius: 4px; border-radius: 4px;
background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95)); background: linear-gradient(180deg, rgba(255,255,255,0.82), rgba(233,223,201,0.95));
color: var(--cel-green); color: var(--cel-green);
font-size: 0.82em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
@@ -519,7 +519,7 @@
.biography-portrait-hint { .biography-portrait-hint {
margin: 0; margin: 0;
font-size: 0.78em; font-size: 0.8em;
font-style: italic; font-style: italic;
color: var(--cel-border); color: var(--cel-border);
} }
+201 -116
View File
@@ -30,7 +30,7 @@
.roll-actor { .roll-actor {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
color: var(--cel-orange-light, #ddb84a); color: var(--cel-orange-light, #ddb84a);
font-size: 0.78em; font-size: 0.9em;
letter-spacing: 0.07em; letter-spacing: 0.07em;
text-transform: uppercase; text-transform: uppercase;
opacity: 0.9; opacity: 0.9;
@@ -38,7 +38,7 @@
.roll-skill-line { .roll-skill-line {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1.25em; font-size: 1.4em;
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
margin-top: 2px; margin-top: 2px;
@@ -58,24 +58,24 @@
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
gap: 4px; gap: 4px;
font-size: 0.82em; font-size: 0.9em;
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
.dval, .nb-dice { .dval, .nb-dice {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1.7em; font-size: 2em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
} }
.dlabel { font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; } .dlabel { font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; }
.dminus { color: #f0a0a0; font-weight: bold; } .dminus { color: #f0a0a0; font-weight: bold; }
.deq { opacity: 0.55; } .deq { opacity: 0.55; }
.ddice { color: var(--cel-orange, #e07b00); } .ddice { color: var(--cel-orange, #e07b00); }
} }
.wound-info { .wound-info {
font-size: 0.73em; font-size: 0.8em;
color: #f0a0a0; color: #f0a0a0;
margin-top: 3px; margin-top: 3px;
} }
@@ -117,17 +117,17 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.65em; font-size: 0.7em;
color: white; color: white;
} }
} }
} }
.moon-icon { font-size: 1.2em; flex-shrink: 0; } .moon-icon { font-size: 1.3em; flex-shrink: 0; }
.moon-text { .moon-text {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 0.88em; font-size: 1em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
} }
} }
@@ -152,7 +152,7 @@
label { label {
flex: 0 0 110px; flex: 0 0 110px;
font-size: 0.78em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
@@ -165,8 +165,8 @@
padding: 3px 7px; padding: 3px 7px;
background: rgba(255,255,255,0.85); background: rgba(255,255,255,0.85);
font-family: inherit; font-family: inherit;
font-size: 0.85em; font-size: 0.9em;
color: #333; color: var(--cel-text, #2f2413);
&:focus { outline: 1px solid var(--cel-orange, #e07b00); } &:focus { outline: 1px solid var(--cel-orange, #e07b00); }
} }
@@ -233,7 +233,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.65em; font-size: 0.7em;
color: white; color: white;
} }
} }
@@ -242,7 +242,7 @@
} }
.destin-icon { .destin-icon {
font-size: 1.1em; font-size: 1.2em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -252,20 +252,20 @@
.destin-main { .destin-main {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 0.9em; font-size: 1.1em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
display: block; display: block;
} }
.destin-bonus { .destin-bonus {
font-size: 0.72em; font-size: 0.8em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
font-style: italic; font-style: italic;
} }
} }
.destin-count { .destin-count {
font-size: 0.75em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
background: rgba(196,154,26,0.2); background: rgba(196,154,26,0.2);
@@ -275,7 +275,7 @@
white-space: nowrap; white-space: nowrap;
&.no-destin { &.no-destin {
color: #888; color: rgba(0,0,0,0.45);
background: rgba(0,0,0,0.05); background: rgba(0,0,0,0.05);
border-color: rgba(0,0,0,0.1); border-color: rgba(0,0,0,0.1);
} }
@@ -283,7 +283,7 @@
} }
} }
.form-visibility label { color: #888; } .form-visibility label { color: rgba(0,0,0,0.45); }
.form-faction-aspect select { .form-faction-aspect select {
font-weight: bold; font-weight: bold;
@@ -326,7 +326,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.75em; font-size: 0.8em;
color: white; color: white;
} }
} }
@@ -338,13 +338,13 @@
flex: 1; flex: 1;
.puiser-main { .puiser-main {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 0.9em; font-size: 1.1em;
color: var(--cel-accent, #6b1e28); color: var(--cel-accent, #6b1e28);
display: block; display: block;
} }
.puiser-sub { .puiser-sub {
font-size: 0.7em; font-size: 0.7em;
color: #888; color: rgba(0,0,0,0.45);
font-style: italic; font-style: italic;
} }
} }
@@ -405,7 +405,7 @@
} }
.fortune-icon { .fortune-icon {
font-size: 1.1em; font-size: 1.2em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -414,12 +414,12 @@
flex: 1; flex: 1;
.fortune-main { .fortune-main {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 0.9em; font-size: 1.1em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
display: block; display: block;
} }
.fortune-bonus { .fortune-bonus {
font-size: 0.72em; font-size: 0.8em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
font-style: italic; font-style: italic;
} }
@@ -459,7 +459,7 @@
.preview-formula { .preview-formula {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1.6em; font-size: 1.9em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
letter-spacing: 0.04em; letter-spacing: 0.04em;
@@ -469,6 +469,90 @@
// ─── Chat message ───────────────────────────────────────────────────────────── // ─── Chat message ─────────────────────────────────────────────────────────────
// ── Contreparties dé de lune (partagé : chat-roll + moon-standalone-card) ──
.celestopol.chat-roll,
.celestopol-roll.moon-standalone-card {
.moon-effect-actions {
padding: 6px 10px 8px;
border-top: 2px solid rgba(122,92,32,0.18);
background: rgba(12,76,12,0.04);
border-radius: 0 0 3px 3px;
.moon-effect-label {
display: block;
font-family: var(--cel-font-title);
font-size: 0.8em;
font-weight: bold;
color: var(--cel-border, #7a5c20);
text-transform: uppercase;
letter-spacing: 0.07em;
margin-bottom: 6px;
}
.moon-effect-buttons {
display: flex;
flex-wrap: wrap;
gap: 5px;
align-items: center;
}
.moon-effect-btn {
font-family: var(--cel-font-title);
font-size: 0.9em;
font-weight: bold;
padding: 4px 11px;
border-radius: 4px;
cursor: pointer;
transition: filter 0.12s, opacity 0.12s;
line-height: 1.4;
letter-spacing: 0.02em;
// Positif par défaut : vert jade / or
background: var(--cel-green, #1b3828);
color: var(--cel-orange-light, #ddb84a);
border: 1px solid rgba(196,154,26,0.35);
&:hover:not(:disabled) { filter: brightness(1.18); }
&:disabled { opacity: 0.55; cursor: not-allowed; }
&.moon-effect-negative {
background: var(--cel-accent, #6b1e28);
color: var(--cel-cream, #f0e8d4);
border-color: rgba(139,30,46,0.4);
&:hover:not(:disabled) { filter: brightness(1.12); }
}
}
.moon-effect-narrative {
font-size: 0.8em;
color: var(--cel-border, #7a5c20);
font-style: italic;
align-self: center;
padding-left: 2px;
}
.moon-effect-applied-status {
display: inline-flex;
align-items: center;
gap: 4px;
margin-top: 6px;
font-size: 0.9em;
font-family: var(--cel-font-title);
font-style: italic;
padding: 3px 9px;
border-radius: 3px;
color: var(--cel-green, #1b3828);
background: rgba(12,76,12,0.09);
border: 1px solid rgba(12,76,12,0.22);
&.is-negative {
color: var(--cel-accent, #6b1e28);
background: rgba(107,30,40,0.09);
border-color: rgba(107,30,40,0.25);
}
}
}
}
.celestopol.chat-roll { .celestopol.chat-roll {
border: 1px solid var(--cel-border, #7a5c20); border: 1px solid var(--cel-border, #7a5c20);
border-radius: 3px; border-radius: 3px;
@@ -506,11 +590,11 @@
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
letter-spacing: 0.05em; letter-spacing: 0.05em;
font-size: 0.92em; font-size: 1.1em;
} }
.skill-info { .skill-info {
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
font-size: 0.77em; font-size: 0.8em;
font-style: italic; font-style: italic;
.stat-lbl { color: var(--cel-orange-light, #ddb84a); } .stat-lbl { color: var(--cel-orange-light, #ddb84a); }
.sep { margin: 0 2px; opacity: 0.5; } .sep { margin: 0 2px; opacity: 0.5; }
@@ -540,10 +624,10 @@
border-radius: 4px; border-radius: 4px;
background: white; background: white;
font-weight: bold; font-weight: bold;
font-size: 1.05em; font-size: 1.2em;
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
box-shadow: 1px 1px 2px rgba(0,0,0,0.12); box-shadow: 1px 1px 2px rgba(0,0,0,0.12);
color: #222; color: var(--cel-text, #2f2413);
&.max { &.max {
background: var(--cel-green, #0c4c0c); background: var(--cel-green, #0c4c0c);
@@ -569,15 +653,15 @@
padding: 5px 10px 4px; padding: 5px 10px 4px;
background: var(--cel-cream, #f0e8d4); background: var(--cel-cream, #f0e8d4);
border-top: 1px solid rgba(122,92,32,0.2); border-top: 1px solid rgba(122,92,32,0.2);
font-size: 0.83em; font-size: 0.9em;
color: #555; color: #555;
.fl-label { color: #999; font-size: 0.88em; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 2px; } .fl-label { color: rgba(0,0,0,0.4); font-size: 0.9em; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 2px; }
.fl-ndice { color: var(--cel-green, #0c4c0c); font-weight: bold; } .fl-ndice { color: var(--cel-green, #0c4c0c); font-weight: bold; }
.fl-sum { font-weight: bold; color: #333; } .fl-sum { font-weight: bold; color: var(--cel-text, #2f2413); }
.fl-total { .fl-total {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1.5em; font-size: 1.7em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
@@ -588,8 +672,8 @@
.fl-asp { color: var(--cel-orange, #e07b00); font-weight: bold; } .fl-asp { color: var(--cel-orange, #e07b00); font-weight: bold; }
.fl-faction { color: var(--cel-green, #0c4c0c); font-weight: bold; } .fl-faction { color: var(--cel-green, #0c4c0c); font-weight: bold; }
.fl-sep { font-weight: bold; color: var(--cel-border, #7a5c20); margin: 0 2px; } .fl-sep { font-weight: bold; color: var(--cel-border, #7a5c20); margin: 0 2px; }
.fl-eq { color: #aaa; } .fl-eq { color: rgba(0,0,0,0.35); }
.fl-op { color: #aaa; } .fl-op { color: rgba(0,0,0,0.35); }
} }
// ── Seuil et marge ── // ── Seuil et marge ──
@@ -600,22 +684,22 @@
padding: 5px 12px 6px; padding: 5px 12px 6px;
background: var(--cel-cream, #f0e8d4); background: var(--cel-cream, #f0e8d4);
border-top: 1px solid rgba(122,92,32,0.2); border-top: 1px solid rgba(122,92,32,0.2);
font-size: 0.82em; font-size: 0.9em;
.vs-wrap { .vs-wrap {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
gap: 5px; gap: 5px;
} }
.vs-label { color: #aaa; text-transform: uppercase; font-size: 0.8em; } .vs-label { color: rgba(0,0,0,0.35); text-transform: uppercase; font-size: 0.8em; }
.diff-label{ font-style: italic; color: var(--cel-green, #0c4c0c); } .diff-label{ font-style: italic; color: var(--cel-green, #0c4c0c); }
.diff-val { color: #888; } .diff-val { color: rgba(0,0,0,0.45); }
.margin-badge { .margin-badge {
padding: 2px 10px; padding: 2px 10px;
border-radius: 12px; border-radius: 12px;
font-weight: bold; font-weight: bold;
font-size: 1.05em; font-size: 1.2em;
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
letter-spacing: 0.05em; letter-spacing: 0.05em;
@@ -635,7 +719,7 @@
// ── Destin utilisé ── // ── Destin utilisé ──
.used-info { .used-info {
text-align: center; text-align: center;
font-size: 0.77em; font-size: 0.8em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
padding: 3px 8px; padding: 3px 8px;
background: rgba(196,154,26,0.1); background: rgba(196,154,26,0.1);
@@ -673,7 +757,7 @@
} }
.damage-header { .damage-header {
font-size: 0.72em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em; letter-spacing: 0.08em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
@@ -690,13 +774,13 @@
.damage-value { .damage-value {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1.9em; font-size: 2.2em;
line-height: 1; line-height: 1;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
} }
.damage-unit { .damage-unit {
font-size: 0.82em; font-size: 0.9em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
font-weight: bold; font-weight: bold;
} }
@@ -704,7 +788,7 @@
.damage-breakdown, .damage-breakdown,
.damage-note { .damage-note {
margin-top: 6px; margin-top: 6px;
font-size: 0.76em; font-size: 0.8em;
line-height: 1.4; line-height: 1.4;
color: #5c4630; color: #5c4630;
} }
@@ -730,7 +814,7 @@
background: var(--cel-green, #0c4c0c); background: var(--cel-green, #0c4c0c);
color: var(--cel-orange-light, #ddb84a); color: var(--cel-orange-light, #ddb84a);
padding: 4px 10px; padding: 4px 10px;
font-size: 0.78em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
@@ -745,7 +829,7 @@
margin-top: 8px; margin-top: 8px;
padding: 6px 8px; padding: 6px 8px;
border-radius: 4px; border-radius: 4px;
font-size: 0.76em; font-size: 0.8em;
line-height: 1.4; line-height: 1.4;
&.is-applied { &.is-applied {
@@ -787,7 +871,7 @@
font-family: var(--cel-font-body, serif); font-family: var(--cel-font-body, serif);
.moon-die-face { .moon-die-face {
font-size: 1.8em; font-size: 1.9em;
line-height: 1; line-height: 1;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -800,7 +884,7 @@
} }
.moon-die-phase { .moon-die-phase {
font-size: 0.72em; font-size: 0.8em;
opacity: 0.75; opacity: 0.75;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
@@ -808,14 +892,14 @@
.moon-die-type { .moon-die-type {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.06em; letter-spacing: 0.06em;
text-transform: uppercase; text-transform: uppercase;
} }
.moon-die-desc { .moon-die-desc {
font-size: 0.72em; font-size: 0.8em;
font-style: italic; font-style: italic;
opacity: 0.85; opacity: 0.85;
line-height: 1.3; line-height: 1.3;
@@ -852,13 +936,13 @@
border-top: 2px solid rgba(0,0,0,0.1); border-top: 2px solid rgba(0,0,0,0.1);
.result-icon { .result-icon {
font-size: 0.85em; font-size: 0.9em;
opacity: 0.85; opacity: 0.85;
letter-spacing: 0.15em; letter-spacing: 0.15em;
} }
.result-label { font-size: 1.2em; line-height: 1.2; } .result-label { font-size: 1.3em; line-height: 1.2; }
.result-desc { .result-desc {
font-size: 0.65em; font-size: 0.7em;
letter-spacing: 0.08em; letter-spacing: 0.08em;
margin-top: 2px; margin-top: 2px;
opacity: 0.8; opacity: 0.8;
@@ -919,22 +1003,22 @@
.welcome-mark { .welcome-mark {
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-size: 1.05em; font-size: 1.1em;
line-height: 1; line-height: 1;
} }
.welcome-title { .welcome-title {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-size: 0.98em; font-size: 1.1em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
} }
.welcome-body { .welcome-body {
padding: 9px 11px 10px; padding: 9px 11px 10px;
color: #3f3623; color: var(--cel-text, #2f2413);
font-size: 0.84em; font-size: 0.9em;
line-height: 1.45; line-height: 1.45;
p { p {
@@ -954,7 +1038,7 @@
display: block; display: block;
margin-bottom: 2px; margin-bottom: 2px;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
font-size: 0.72em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
@@ -997,27 +1081,27 @@
.portrait-message-mark { .portrait-message-mark {
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-size: 1.05em; font-size: 1.1em;
line-height: 1; line-height: 1;
} }
.portrait-message-title { .portrait-message-title {
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-size: 0.98em; font-size: 1.1em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
} }
.portrait-message-body { .portrait-message-body {
padding: 9px 11px 10px; padding: 9px 11px 10px;
color: #3f3623; color: var(--cel-text, #2f2413);
} }
.portrait-message-name { .portrait-message-name {
margin-bottom: 8px; margin-bottom: 8px;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
font-size: 0.84em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.04em; letter-spacing: 0.04em;
text-transform: uppercase; text-transform: uppercase;
@@ -1100,7 +1184,7 @@
&:hover { &:hover {
border-color: var(--cel-orange, #e07b00); border-color: var(--cel-orange, #e07b00);
background: linear-gradient(180deg, rgba(224,123,0,0.18), rgba(224,123,0,0.06)); background: linear-gradient(180deg, rgba(224,123,0,0.18), rgba(224,123,0,0.06));
color: #7a3e00; color: var(--cel-border, #7a5c20);
} }
} }
} }
@@ -1124,7 +1208,7 @@
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
font-size: 0.88em; font-size: 1em;
} }
.faction-aspect-points { .faction-aspect-points {
@@ -1146,7 +1230,7 @@
border: 1px solid rgba(122,92,32,0.18); border: 1px solid rgba(122,92,32,0.18);
strong { strong {
font-size: 0.72em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
@@ -1155,14 +1239,14 @@
em { em {
font-style: normal; font-style: normal;
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 1.05em; font-size: 1.2em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
line-height: 1; line-height: 1;
} }
} }
.faction-aspect-source-line { .faction-aspect-source-line {
font-size: 0.78em; font-size: 0.8em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
} }
@@ -1171,7 +1255,7 @@
border-left: 3px solid #b84a2e; border-left: 3px solid #b84a2e;
border-radius: 4px; border-radius: 4px;
background: rgba(184, 74, 46, 0.08); background: rgba(184, 74, 46, 0.08);
color: #8b3e2b; color: var(--cel-accent, #6b1e28);
font-size: 0.8em; font-size: 0.8em;
} }
@@ -1190,7 +1274,7 @@
background: rgba(12, 76, 12, 0.08); background: rgba(12, 76, 12, 0.08);
border: 1px solid rgba(12, 76, 12, 0.18); border: 1px solid rgba(12, 76, 12, 0.18);
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
font-size: 0.72em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
} }
@@ -1204,7 +1288,7 @@
label { label {
display: block; display: block;
margin-bottom: 2px; margin-bottom: 2px;
font-size: 0.68em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
@@ -1219,13 +1303,13 @@
border-radius: 3px; border-radius: 3px;
padding: 2px 6px; padding: 2px 6px;
background: rgba(255,255,255,0.9); background: rgba(255,255,255,0.9);
font-size: 0.78em; font-size: 0.8em;
color: #2f2413; color: var(--cel-text, #2f2413);
box-sizing: border-box; box-sizing: border-box;
} }
select option { select option {
color: #2f2413; color: var(--cel-text, #2f2413);
background: #fffaf0; background: #fffaf0;
} }
} }
@@ -1251,7 +1335,7 @@
background: rgba(224,123,0,0.12); background: rgba(224,123,0,0.12);
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 0.72em; font-size: 0.8em;
line-height: 1; line-height: 1;
cursor: help; cursor: help;
vertical-align: middle; vertical-align: middle;
@@ -1273,7 +1357,7 @@
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
margin-bottom: 4px; margin-bottom: 4px;
font-size: 0.82em; font-size: 0.9em;
} }
} }
@@ -1281,7 +1365,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
font-size: 0.74em; font-size: 0.8em;
} }
.faction-aspect-active-list { .faction-aspect-active-list {
@@ -1298,8 +1382,8 @@
padding: 3px 6px; padding: 3px 6px;
border-radius: 4px; border-radius: 4px;
background: rgba(255,255,255,0.7); background: rgba(255,255,255,0.7);
color: #2f2413; color: var(--cel-text, #2f2413);
font-size: 0.76em; font-size: 0.8em;
&.is-relevant { &.is-relevant {
border-left: 3px solid var(--cel-green, #0c4c0c); border-left: 3px solid var(--cel-green, #0c4c0c);
@@ -1307,20 +1391,20 @@
} }
.faction-aspect-active-name { .faction-aspect-active-name {
color: #2f2413; color: var(--cel-text, #2f2413);
font-weight: 600; font-weight: 600;
} }
.faction-aspect-active-value { .faction-aspect-active-value {
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
font-size: 0.92em; font-size: 1.1em;
} }
.faction-aspect-empty { .faction-aspect-empty {
color: #666; color: rgba(0,0,0,0.5);
font-style: italic; font-style: italic;
font-size: 0.74em; font-size: 0.8em;
} }
.faction-aspect-remove-block { .faction-aspect-remove-block {
@@ -1349,7 +1433,7 @@
border-left: 3px solid #c0392b; border-left: 3px solid #c0392b;
border-radius: 4px; border-radius: 4px;
color: #f0c0c0; color: #f0c0c0;
font-size: 0.85em; font-size: 0.9em;
.wound-icon { font-size: 1em; } .wound-icon { font-size: 1em; }
} }
} }
@@ -1358,7 +1442,7 @@
.celestopol.chat-roll { .celestopol.chat-roll {
.roll-result-banner.tie { .roll-result-banner.tie {
background: #3a2e1a; background: #3a2e1a;
color: #d4b870; color: var(--cel-orange-light, #ddb84a);
border-top: 2px solid #7a6230; border-top: 2px solid #7a6230;
border-bottom: 2px solid #7a6230; border-bottom: 2px solid #7a6230;
text-shadow: 0 1px 2px rgba(0,0,0,0.6); text-shadow: 0 1px 2px rgba(0,0,0,0.6);
@@ -1369,12 +1453,12 @@
align-items: center; align-items: center;
gap: 0.3em; gap: 0.3em;
margin-bottom: 1px; margin-bottom: 1px;
font-size: 0.85em; font-size: 0.9em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
.weapon-icon-small { font-size: 0.9em; } .weapon-icon-small { font-size: 0.9em; }
.weapon-degats-small { .weapon-degats-small {
font-weight: bold; font-weight: bold;
color: #f0c060; color: var(--cel-border, #7a5c20);
} }
} }
} }
@@ -1391,15 +1475,15 @@
.weapon-icon { font-size: 1em; } .weapon-icon { font-size: 1em; }
.weapon-degats { .weapon-degats {
font-weight: bold; font-weight: bold;
color: #f0c060; color: var(--cel-border, #7a5c20);
font-size: 0.85em; font-size: 0.9em;
} }
} }
.form-corps-pnj { .form-corps-pnj {
.corps-pnj-input { .corps-pnj-input {
width: 70px; width: 70px;
font-size: 1.1em; font-size: 1.3em;
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
@@ -1420,7 +1504,7 @@
label { label {
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
font-size: 0.85em; font-size: 0.9em;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
@@ -1435,7 +1519,7 @@
border: 1px solid rgba(196, 154, 26, 0.5); border: 1px solid rgba(196, 154, 26, 0.5);
border-radius: 3px; border-radius: 3px;
padding: 2px 4px; padding: 2px 4px;
font-size: 0.85em; font-size: 0.9em;
max-width: 200px; max-width: 200px;
} }
} }
@@ -1451,7 +1535,7 @@
align-items: center; align-items: center;
gap: 6px; gap: 6px;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-size: 0.88em; font-size: 0.9em;
font-style: italic; font-style: italic;
i { opacity: 0.8; } i { opacity: 0.8; }
@@ -1465,14 +1549,14 @@
padding: 4px 8px; padding: 4px 8px;
label { label {
color: #e08060; color: var(--cel-accent, #6b1e28);
font-size: 0.85em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
i { color: #e08060; } i { color: var(--cel-accent, #6b1e28); }
} }
select { select {
@@ -1482,13 +1566,13 @@
border: 1px solid rgba(200, 100, 60, 0.4); border: 1px solid rgba(200, 100, 60, 0.4);
border-radius: 3px; border-radius: 3px;
padding: 2px 4px; padding: 2px 4px;
font-size: 0.85em; font-size: 0.9em;
} }
} }
.form-threshold-fixed { .form-threshold-fixed {
.threshold-value { .threshold-value {
font-size: 1.2em; font-size: 1.4em;
font-weight: bold; font-weight: bold;
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
@@ -1514,7 +1598,7 @@
input[type="checkbox"] { flex-shrink: 0; } input[type="checkbox"] { flex-shrink: 0; }
.opposition-icon { .opposition-icon {
font-size: 1.2em; font-size: 1.3em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
} }
@@ -1525,14 +1609,14 @@
.opposition-main { .opposition-main {
font-weight: bold; font-weight: bold;
font-size: 0.9em; font-size: 1.1em;
font-family: var(--cel-font-title, "CopaseticNF", serif); font-family: var(--cel-font-title, "CopaseticNF", serif);
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
} }
.opposition-sub { .opposition-sub {
font-size: 0.75em; font-size: 0.8em;
opacity: 0.7; color: #8a7060;
font-style: italic; font-style: italic;
} }
} }
@@ -1567,7 +1651,7 @@
.moon-standalone-title { .moon-standalone-title {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
color: var(--cel-green-dark, #0c4c0c); color: var(--cel-green-dark, #0c4c0c);
text-transform: uppercase; text-transform: uppercase;
@@ -1575,7 +1659,7 @@
} }
.moon-standalone-actor { .moon-standalone-actor {
font-size: 0.85em; font-size: 0.9em;
color: var(--cel-text, #333); color: var(--cel-text, #333);
font-style: italic; font-style: italic;
} }
@@ -1604,7 +1688,7 @@
.moon-standalone-phase { .moon-standalone-phase {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.95em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
color: var(--cel-text, #333); color: var(--cel-text, #333);
} }
@@ -1617,8 +1701,8 @@
&.moon-triomphe { border-left-color: var(--cel-green, #0c4c0c); } &.moon-triomphe { border-left-color: var(--cel-green, #0c4c0c); }
&.moon-brio { border-left-color: var(--cel-border, #7a5c20); } &.moon-brio { border-left-color: var(--cel-border, #7a5c20); }
&.moon-contrecoup { border-left-color: #c07800; } &.moon-contrecoup { border-left-color: var(--cel-orange, #c49a1a); }
&.moon-catastrophe{ border-left-color: #8b1e2e; } &.moon-catastrophe{ border-left-color: var(--cel-accent, #6b1e28); }
} }
.moon-interpret-row { .moon-interpret-row {
@@ -1627,15 +1711,15 @@
gap: 8px; gap: 8px;
.moon-interpret-label { .moon-interpret-label {
font-size: 0.72em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
color: #888; color: rgba(0,0,0,0.45);
white-space: nowrap; white-space: nowrap;
} }
.moon-fortune { .moon-fortune {
font-size: 0.85em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
border-radius: 3px; border-radius: 3px;
padding: 1px 8px; padding: 1px 8px;
@@ -1648,7 +1732,7 @@
&.mauvaise-fortune { &.mauvaise-fortune {
background: rgba(139, 30, 46, 0.1); background: rgba(139, 30, 46, 0.1);
color: #8b1e2e; color: var(--cel-accent, #6b1e28);
border: 1px solid rgba(139,30,46,0.3); border: 1px solid rgba(139,30,46,0.3);
} }
} }
@@ -1659,6 +1743,7 @@
margin-top: 2px; margin-top: 2px;
padding: 6px 8px; padding: 6px 8px;
} }
} }
// ── Message d'initiative ────────────────────────────────────────────────────── // ── Message d'initiative ──────────────────────────────────────────────────────
@@ -1698,11 +1783,11 @@
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
letter-spacing: 0.05em; letter-spacing: 0.05em;
font-size: 0.92em; font-size: 1.1em;
} }
.skill-info { .skill-info {
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
font-size: 0.77em; font-size: 0.8em;
font-style: italic; font-style: italic;
} }
} }
@@ -1730,19 +1815,19 @@
} }
.initiative-icon { .initiative-icon {
font-size: 1.1em; font-size: 1.2em;
opacity: 0.9; opacity: 0.9;
font-style: normal; font-style: normal;
} }
.initiative-score { .initiative-score {
font-size: 2.4em; font-size: 2.5em;
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
} }
.initiative-detail { .initiative-detail {
font-size: 0.65em; font-size: 0.7em;
opacity: 0.75; opacity: 0.75;
font-style: italic; font-style: italic;
font-family: var(--cel-font-body, serif); font-family: var(--cel-font-body, serif);
+24 -24
View File
@@ -16,7 +16,7 @@
{{#each (lookup ../skills statId) as |skill skillId|}} {{#each (lookup ../skills statId) as |skill skillId|}}
{{#if @root.isEditMode}} {{#if @root.isEditMode}}
<div class="skill-row edit-mode" data-stat-id="{{statId}}" data-skill-id="{{skillId}}"> <div class="skill-row edit-mode" data-stat-id="{{statId}}" data-skill-id="{{skillId}}">
<span class="skill-name">{{localize skill.label}}</span> <span class="skill-name" data-tooltip="{{localize skill.tooltip}}">{{localize skill.label}}</span>
<div class="skill-checkboxes-container"> <div class="skill-checkboxes-container">
<div class="skill-checkboxes"> <div class="skill-checkboxes">
{{#each (range 8) as |lvl|}} {{#each (range 8) as |lvl|}}
@@ -31,7 +31,7 @@
{{else}} {{else}}
<div class="skill-row rollable" data-stat-id="{{statId}}" data-skill-id="{{skillId}}" <div class="skill-row rollable" data-stat-id="{{statId}}" data-skill-id="{{skillId}}"
title="{{localize 'CELESTOPOL.Roll.clickToRoll'}}"> title="{{localize 'CELESTOPOL.Roll.clickToRoll'}}">
<span class="skill-name">{{localize skill.label}}</span> <span class="skill-name" data-tooltip="{{localize skill.tooltip}}">{{localize skill.label}}</span>
<div class="skill-checkboxes-container"> <div class="skill-checkboxes-container">
<div class="skill-checkboxes"> <div class="skill-checkboxes">
{{#each (range 8) as |lvl|}} {{#each (range 8) as |lvl|}}
@@ -49,8 +49,29 @@
{{/each}} {{/each}}
</div> </div>
{{!-- Items : Anomalie (unique), Aspects, Attributs --}} {{!-- Items : Aspects, Anomalie --}}
<div class="items-section"> <div class="items-section">
{{!-- Aspects --}}
<div class="items-group">
<div class="items-header">
<span>{{localize "CELESTOPOL.Item.aspects"}}</span>
{{#if isEditMode}}
<a data-action="createAspect" title="{{localize 'CELESTOPOL.Item.newAspect'}}"><i class="fas fa-plus"></i></a>
{{/if}}
</div>
{{#each aspects as |item|}}
<div class="item-row" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
<img src="{{item.img}}" class="item-icon" alt="{{item.name}}">
<span class="item-name">{{item.name}}</span>
<span class="item-value">{{item.system.valeur}}</span>
<div class="item-controls">
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
</div>
</div>
{{/each}}
</div>
{{!-- Anomalie : bloc proéminent unique --}} {{!-- Anomalie : bloc proéminent unique --}}
<div class="anomaly-block"> <div class="anomaly-block">
<div class="anomaly-block-header"> <div class="anomaly-block-header">
@@ -124,26 +145,5 @@
{{/if}} {{/if}}
</div> </div>
{{!-- Aspects --}}
<div class="items-group">
<div class="items-header">
<span>{{localize "CELESTOPOL.Item.aspects"}}</span>
{{#if isEditMode}}
<a data-action="createAspect" title="{{localize 'CELESTOPOL.Item.newAspect'}}"><i class="fas fa-plus"></i></a>
{{/if}}
</div>
{{#each aspects as |item|}}
<div class="item-row" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
<img src="{{item.img}}" class="item-icon" alt="{{item.name}}">
<span class="item-name">{{item.name}}</span>
<span class="item-value">{{item.system.valeur}}</span>
<div class="item-controls">
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
</div>
</div>
{{/each}}
</div>
</div> </div>
</div> </div>
+25 -4
View File
@@ -16,8 +16,8 @@
</span> </span>
{{/if}} {{/if}}
<span class="skill-info"> <span class="skill-info">
{{#if statLabel}}<span class="stat-lbl">{{statLabel}}</span><span class="sep"> </span>{{/if}} {{#if statLabel}}<span class="stat-lbl">{{localize statLabel}}</span><span class="sep"> </span>{{/if}}
<span class="skill-lbl">{{skillLabel}}</span> <span class="skill-lbl">{{localize skillLabel}}</span>
</span> </span>
{{#if woundLabel}}<span class="wound-info">⚠ {{woundLabel}}</span>{{/if}} {{#if woundLabel}}<span class="wound-info">⚠ {{woundLabel}}</span>{{/if}}
</div> </div>
@@ -122,7 +122,7 @@
</div> </div>
{{/if}} {{/if}}
{{!-- Résultat du Dé de la Lune (narratif) --}} {{!-- Résultat du Dé de la Lune (narratif + choix de contrepartie) --}}
{{#if hasMoonDie}} {{#if hasMoonDie}}
<div class="moon-die-result {{moonResultClass}}"> <div class="moon-die-result {{moonResultClass}}">
<span class="moon-die-face">{{moonFaceSymbol}}</span> <span class="moon-die-face">{{moonFaceSymbol}}</span>
@@ -132,6 +132,27 @@
<span class="moon-die-desc">{{moonResultDesc}}</span> <span class="moon-die-desc">{{moonResultDesc}}</span>
</div> </div>
</div> </div>
{{#if moonActorIsCharacter}}
<div class="moon-effect-actions" data-moon-actor-id="{{moonActorId}}" data-moon-actor-uuid="{{moonActorUuid}}">
<span class="moon-effect-label">{{localize "CELESTOPOL.Moon.applyChoose"}}</span>
<div class="moon-effect-buttons">
{{#if (eq moonResultTypeId "triomphe")}}
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="regain-anomaly">{{localize "CELESTOPOL.Moon.effectRegainAnomaly"}}</button>
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="lose-spleen">{{localize "CELESTOPOL.Moon.effectLoseSpleen"}}</button>
{{else if (eq moonResultTypeId "brio")}}
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="gain-destin">{{localize "CELESTOPOL.Moon.effectGainDestin"}}</button>
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
{{else if (eq moonResultTypeId "contrecoup")}}
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-destin">{{localize "CELESTOPOL.Moon.effectLoseDestin"}}</button>
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
{{else if (eq moonResultTypeId "catastrophe")}}
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-anomaly">{{localize "CELESTOPOL.Moon.effectLoseAnomaly"}}</button>
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="gain-spleen">{{localize "CELESTOPOL.Moon.effectGainSpleen"}}</button>
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
{{/if}}
</div>
</div>
{{/if}}
{{/if}} {{/if}}
{{!-- Bandeau résultat --}} {{!-- Bandeau résultat --}}
@@ -162,7 +183,7 @@
<span class="result-label">{{localize "CELESTOPOL.Roll.failure"}}</span> <span class="result-label">{{localize "CELESTOPOL.Roll.failure"}}</span>
{{#if isCombat}} {{#if isCombat}}
{{#if (eq weaponType "melee")}} {{#if (eq weaponType "melee")}}
<span class="result-desc">{{localize "CELESTOPOL.Combat.failureHit"}}</span> {{#unless isNpcAttack}}<span class="result-desc">{{localize "CELESTOPOL.Combat.failureHit"}}</span>{{/unless}}
{{else if isRangedDefense}} {{else if isRangedDefense}}
<span class="result-desc">{{localize "CELESTOPOL.Combat.rangedDefenseFailure"}}</span> <span class="result-desc">{{localize "CELESTOPOL.Combat.rangedDefenseFailure"}}</span>
{{else}} {{else}}
+23
View File
@@ -36,4 +36,27 @@
</div> </div>
</div> </div>
{{!-- Choix de la contrepartie --}}
{{#if moonActorIsCharacter}}
<div class="moon-effect-actions" data-moon-actor-id="{{moonActorId}}" data-moon-actor-uuid="{{moonActorUuid}}">
<span class="moon-effect-label">{{localize "CELESTOPOL.Moon.applyChoose"}}</span>
<div class="moon-effect-buttons">
{{#if (eq moonResultTypeId "triomphe")}}
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="regain-anomaly">{{localize "CELESTOPOL.Moon.effectRegainAnomaly"}}</button>
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="lose-spleen">{{localize "CELESTOPOL.Moon.effectLoseSpleen"}}</button>
{{else if (eq moonResultTypeId "brio")}}
<button type="button" class="moon-effect-btn" data-action="apply-moon-effect" data-effect="gain-destin">{{localize "CELESTOPOL.Moon.effectGainDestin"}}</button>
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
{{else if (eq moonResultTypeId "contrecoup")}}
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-destin">{{localize "CELESTOPOL.Moon.effectLoseDestin"}}</button>
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
{{else if (eq moonResultTypeId "catastrophe")}}
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="lose-anomaly">{{localize "CELESTOPOL.Moon.effectLoseAnomaly"}}</button>
<button type="button" class="moon-effect-btn moon-effect-negative" data-action="apply-moon-effect" data-effect="gain-spleen">{{localize "CELESTOPOL.Moon.effectGainSpleen"}}</button>
<span class="moon-effect-narrative">{{localize "CELESTOPOL.Moon.effectNarrativeOnly"}}</span>
{{/if}}
</div>
</div>
{{/if}}
</div> </div>
+6 -1
View File
@@ -9,7 +9,7 @@
{{/if}} {{/if}}
</div> </div>
{{#each weapons as |item|}} {{#each weapons as |item|}}
<div class="item-row weapon" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true"> <div class="item-row weapon {{#if item.system.equipped}}is-equipped{{/if}}" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}" data-drag="true">
<img src="{{item.img}}" class="item-icon"> <img src="{{item.img}}" class="item-icon">
<span class="item-name">{{item.name}}</span> <span class="item-name">{{item.name}}</span>
<span class="item-tag type">{{#if (eq item.system.type "melee")}}{{localize "CELESTOPOL.Weapon.typeMelee"}}{{else}}{{localize "CELESTOPOL.Weapon.typeDistance"}}{{/if}}</span> <span class="item-tag type">{{#if (eq item.system.type "melee")}}{{localize "CELESTOPOL.Weapon.typeMelee"}}{{else}}{{localize "CELESTOPOL.Weapon.typeDistance"}}{{/if}}</span>
@@ -18,6 +18,11 @@
{{#unless ../isEditMode}} {{#unless ../isEditMode}}
<a data-action="attack" data-item-id="{{item.id}}" title="{{localize 'CELESTOPOL.Combat.attack'}}"><i class="fas fa-khanda"></i></a> <a data-action="attack" data-item-id="{{item.id}}" title="{{localize 'CELESTOPOL.Combat.attack'}}"><i class="fas fa-khanda"></i></a>
{{/unless}} {{/unless}}
<a data-action="toggleWeapon" data-item-uuid="{{item.uuid}}"
title="{{#if item.system.equipped}}{{localize 'CELESTOPOL.Weapon.unequip'}}{{else}}{{localize 'CELESTOPOL.Weapon.equip'}}{{/if}}"
class="equip-toggle {{#if item.system.equipped}}equipped{{/if}}">
<i class="fas fa-khanda"></i>
</a>
<a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a> <a data-action="edit" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
{{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}} {{#if ../isEditMode}}<a data-action="delete" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>{{/if}}
</div> </div>
+3 -3
View File
@@ -220,9 +220,9 @@
<div class="form-row-line form-visibility"> <div class="form-row-line form-visibility">
<label for="visibility">{{localize "CELESTOPOL.Roll.visibility"}}</label> <label for="visibility">{{localize "CELESTOPOL.Roll.visibility"}}</label>
<select id="visibility" name="visibility"> <select id="visibility" name="visibility">
<option value="publicroll">{{localize "CELESTOPOL.Roll.visibilityPublic"}}</option> <option value="public">{{localize "CELESTOPOL.Roll.visibilityPublic"}}</option>
<option value="gmroll">{{localize "CELESTOPOL.Roll.visibilityGM"}}</option> <option value="gm">{{localize "CELESTOPOL.Roll.visibilityGM"}}</option>
<option value="selfroll">{{localize "CELESTOPOL.Roll.visibilitySelf"}}</option> <option value="self">{{localize "CELESTOPOL.Roll.visibilitySelf"}}</option>
</select> </select>
</div> </div>