6 Commits

Author SHA1 Message Date
uberwald adf9b0b2e6 Réglage de la difficulté par défaut
Release Creation / build (release) Successful in 1m16s
2026-05-29 19:26:31 +02:00
uberwald 5c2a364832 Réglage de la difficulté par défaut
Release Creation / build (release) Successful in 1m13s
2026-05-29 18:28:09 +02:00
uberwald ec0e522145 Add ranged attacks for monsters
Release Creation / build (release) Successful in 1m13s
2026-04-29 22:24:42 +02:00
uberwald 8123b53f75 Import de personnages du précédent système
Release Creation / build (release) Successful in 1m21s
2026-04-27 22:29:49 +02:00
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
56 changed files with 4215 additions and 270 deletions
+87
View File
@@ -0,0 +1,87 @@
# 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`).
+368
View File
@@ -0,0 +1,368 @@
#!/usr/bin/env python3
"""
convert-old-system.py
Convertit les fichiers JSON d'acteurs exportés de l'ancien système Célestopol 1922
(system id: celestopol1922) vers le format du nouveau système (fvtt-celestopol).
Usage:
python3 convert-old-system.py <fichier.json> [fichier2.json ...]
Le fichier converti est écrit à côté du fichier source sous le nom :
<nom>-converted.json
"""
import json
import os
import re
import sys
import uuid
# ─── Mapping des types d'anomalies (préfixe "CEL1922.opt." → clé nouveau système) ─────
ANOMALY_TYPE_MAP = {
"none": "none",
"entropie": "entropie",
"communicationaveclesmorts": "communicationaveclesmorts",
"illusion": "illusion",
"suggestion": "suggestion",
"tarotdivinatoire": "tarotdivinatoire",
"telekinesie": "telekinesie",
"telepathie": "telepathie",
"voyageastral": "voyageastral",
}
# Clé anomaly vide → "none"
VALID_ANOMALY_TYPES = set(ANOMALY_TYPE_MAP.values())
# ─── Domaines (stats) ──────────────────────────────────────────────────────────────────
STATS = ["ame", "corps", "coeur", "esprit"]
# Compétences par domaine (dans l'ordre du nouveau système)
SKILLS = {
"ame": ["artifice", "attraction", "coercition", "faveur"],
"corps": ["echauffouree", "effacement", "mobilite", "prouesse"],
"coeur": ["appreciation", "arts", "inspiration", "traque"],
"esprit": ["instruction", "mtechnologique", "raisonnement", "traitement"],
}
def make_id():
"""Génère un identifiant Foundry-compatible (16 chars hex)."""
return uuid.uuid4().hex[:16]
def strip_prefix(label: str) -> str:
"""Extrait la clé depuis 'CEL1922.opt.<clé>'."""
return label.split(".")[-1]
def resolve_anomaly_type(old_system: dict) -> str:
"""
Résout le type d'anomalie depuis l'ancien système.
old_system.anomaly est un int (index dans anomalytypes[]).
"""
anomalytypes = old_system.get("skill", {}).get("anomalytypes", [])
idx = old_system.get("anomaly", 0)
try:
idx = int(idx)
except (ValueError, TypeError):
idx = 0
if idx == 0 or not anomalytypes:
return "none"
if idx < len(anomalytypes):
raw = strip_prefix(anomalytypes[idx])
return ANOMALY_TYPE_MAP.get(raw, "none")
return "none"
def resolve_anomaly_type_from_name(item_name: str) -> str:
"""
Infère le type d'anomalie depuis le nom de l'item (ex: 'Entropie 1''entropie').
Fallback si le mapping par index est insuffisant.
"""
# Normalise : minuscules, retire accents, retire espaces et chiffres
name_clean = item_name.lower().strip()
name_clean = re.sub(r"\s*\d+\s*$", "", name_clean).strip() # retire le niveau en fin
name_clean = re.sub(r"\s+", "", name_clean) # retire tous les espaces
# Normalisation des accents courants
replacements = [
("é", "e"), ("è", "e"), ("ê", "e"), ("ë", "e"),
("à", "a"), ("â", "a"), ("ä", "a"),
("î", "i"), ("ï", "i"),
("ô", "o"), ("ö", "o"),
("û", "u"), ("ù", "u"), ("ü", "u"),
("ç", "c"),
]
for src, dst in replacements:
name_clean = name_clean.replace(src, dst)
for key in ANOMALY_TYPE_MAP:
if key == "none":
continue
if key in name_clean or name_clean in key:
return key
return "none"
def convert_stats_character(old_skill: dict, warnings: list) -> dict:
"""Convertit system.skill (ancien) → system.stats (nouveau) pour un PJ."""
stats = {}
for stat in STATS:
old_stat = old_skill.get(stat, {})
new_stat = {
"label": stat,
"res": int(old_stat.get("res", 0) or 0),
}
for skill in SKILLS[stat]:
old_sk = old_stat.get(skill, {})
val = old_sk.get("value", 0)
try:
val = int(val) if val is not None else 0
except (ValueError, TypeError):
warnings.append(f"Valeur de compétence invalide pour {stat}.{skill}: {val!r} → 0")
val = 0
new_stat[skill] = {"label": skill, "value": val}
stats[stat] = new_stat
return stats
def convert_stats_npc(old_skill: dict, warnings: list) -> dict:
"""Convertit system.skill (ancien) → system.stats (nouveau) pour un PNJ."""
stats = {}
for stat in STATS:
old_stat = old_skill.get(stat, {})
res = int(old_stat.get("res", 0) or 0)
stats[stat] = {
"label": stat,
"res": res,
"actuel": res, # actuel = res par défaut
}
return stats
def convert_attributs(old_attributs: dict) -> dict:
"""Convertit les attributs du vieux format plat vers SchemaField {value, max}."""
return {
"entregent": {
"value": int(old_attributs.get("entregent", 0) or 0),
"max": int(old_attributs.get("entregentmax", 0) or 0),
},
"fortune": {
"value": int(old_attributs.get("fortune", 0) or 0),
"max": int(old_attributs.get("fortunemax", 0) or 0),
},
"reve": {
"value": int(old_attributs.get("reve", 0) or 0),
"max": int(old_attributs.get("revemax", 0) or 0),
},
"vision": {
"value": int(old_attributs.get("vision", 0) or 0),
"max": int(old_attributs.get("visionmax", 0) or 0),
},
}
def convert_item(item: dict, warnings: list) -> dict | None:
"""
Convertit un item de l'ancien format vers le nouveau.
Retourne None si l'item doit être ignoré (type inconnu sans données utiles).
"""
old_type = item.get("type", "")
old_sys = item.get("system", {})
name = item.get("name", "Sans nom")
new_item = {
"_id": make_id(),
"name": name,
"img": item.get("img", "icons/svg/item-bag.svg"),
"effects": [],
"flags": {},
"sort": 0,
}
if old_type == "anomaly":
level = 0
try:
level = int(old_sys.get("value", 1) or 1)
except (ValueError, TypeError):
level = 1
level = max(1, min(4, level))
# Résolution du subtype : l'ancien système le stocke mal ("weapon"), on l'infère du nom
subtype = resolve_anomaly_type_from_name(name)
if subtype == "none":
warnings.append(f"Impossible de déterminer le type d'anomalie depuis '{name}', 'none' utilisé")
new_item["type"] = "anomaly"
new_item["system"] = {
"subtype": subtype,
"level": level,
"usesRemaining": level,
"technique": old_sys.get("technique", "") or "",
"narratif": old_sys.get("narratif", "") or "",
}
elif old_type == "aspect":
valeur = 0
try:
valeur = int(old_sys.get("value", 0) or 0)
except (ValueError, TypeError):
valeur = 0
new_item["type"] = "aspect"
new_item["system"] = {
"valeur": valeur,
"description": old_sys.get("narratif", "") or old_sys.get("technique", "") or "",
}
elif old_type == "item":
old_subtype = (old_sys.get("subtype") or "").lower().strip()
damage = old_sys.get("damage", "") or ""
protect = old_sys.get("protection", "") or ""
if old_subtype == "weapon" or (damage and not protect):
new_item["type"] = "weapon"
new_item["system"] = {
"type": "melee",
"degats": "0",
"portee": "contact",
"equipped": False,
"description": old_sys.get("technique", "") or old_sys.get("narratif", "") or "",
}
if damage:
warnings.append(f"Item '{name}' : valeur damage='{damage}' non convertie automatiquement, à saisir manuellement")
elif old_subtype == "armor" or (protect and not damage):
new_item["type"] = "armure"
new_item["system"] = {
"protection": 1,
"malus": 1,
"equipped": False,
"description": old_sys.get("technique", "") or old_sys.get("narratif", "") or "",
}
if protect:
warnings.append(f"Item '{name}' : valeur protection='{protect}' non convertie automatiquement, à saisir manuellement")
else:
# Équipement générique
new_item["type"] = "equipment"
new_item["system"] = {
"description": old_sys.get("technique", "") or old_sys.get("narratif", "") or "",
}
else:
warnings.append(f"Type d'item inconnu '{old_type}' pour '{name}', ignoré")
return None
return new_item
def convert_actor(old: dict) -> tuple[dict, list[str]]:
"""Convertit un acteur complet. Retourne (new_actor, warnings)."""
warnings = []
actor_type = old.get("type", "character")
old_sys = old.get("system", {})
old_skill = old_sys.get("skill", {})
new_sys = {}
# ── Champs communs ──────────────────────────────────────────────────────────────
new_sys["concept"] = old_sys.get("concept", "") or ""
new_sys["description"] = old_sys.get("description", "") or "" # gardé dans metier/concept
new_sys["metier"] = old_sys.get("metier", "") or old_sys.get("concept", "") or ""
new_sys["faction"] = old_sys.get("faction", "") or ""
# ── Blessures / Destin / Spleen ─────────────────────────────────────────────────
new_sys["blessures"] = {"lvl": int(old_sys.get("blessures", {}).get("lvl", 0) or 0)}
new_sys["destin"] = {"lvl": int(old_sys.get("destin", {}).get("lvl", 0) or 0)}
new_sys["spleen"] = {"lvl": int(old_sys.get("spleen", {}).get("lvl", 0) or 0)}
# ── Stats ───────────────────────────────────────────────────────────────────────
if actor_type == "character":
new_sys["stats"] = convert_stats_character(old_skill, warnings)
# Anomalie : type depuis l'index, niveau depuis anomalyval
anomaly_type = resolve_anomaly_type(old_sys)
anomaly_val = int(old_sys.get("anomalyval", 0) or 0)
new_sys["anomaly"] = {"type": anomaly_type, "value": anomaly_val}
# Attributs
new_sys["attributs"] = convert_attributs(old_sys.get("attributs", {}))
# Biographie → historique
new_sys["historique"] = old_sys.get("description", "") or ""
new_sys["descriptionPhysique"] = ""
new_sys["descriptionPsychologique"] = ""
new_sys["initiative"] = 0
# Factions (vide)
new_sys["factions"] = old_sys.get("factions", {})
elif actor_type == "npc":
new_sys["stats"] = convert_stats_npc(old_skill, warnings)
new_sys["npcType"] = old_sys.get("npcType", "standard") or "standard"
new_sys["historique"] = old_sys.get("description", "") or ""
# ── Items ───────────────────────────────────────────────────────────────────────
new_items = []
for item in old.get("items", []):
converted = convert_item(item, warnings)
if converted:
new_items.append(converted)
new_actor = {
"_id": make_id(),
"name": old.get("name", "Personnage sans nom"),
"type": actor_type,
"img": old.get("img", "icons/svg/mystery-man.svg"),
"system": new_sys,
"items": new_items,
"effects": [],
"folder": None,
"flags": {},
"prototypeToken": old.get("prototypeToken", {}),
}
return new_actor, warnings
def convert_file(path: str) -> None:
"""Lit path, convertit, écrit <base>-converted.json."""
print(f"\n{'' * 60}")
print(f"Traitement : {path}")
with open(path, "r", encoding="utf-8") as f:
old = json.load(f)
new_actor, warnings = convert_actor(old)
for w in warnings:
print(f"{w}")
base, _ = os.path.splitext(path)
out_path = f"{base}-converted.json"
with open(out_path, "w", encoding="utf-8") as f:
json.dump(new_actor, f, ensure_ascii=False, indent=2)
print(f" ✓ Écrit : {out_path}")
print(f" type={new_actor['type']} items={len(new_actor['items'])} avertissements={len(warnings)}")
def main():
if len(sys.argv) < 2:
print("Usage: python3 convert-old-system.py <fichier.json> [fichier2.json ...]")
sys.exit(1)
for path in sys.argv[1:]:
if not os.path.isfile(path):
print(f"Fichier introuvable : {path}", file=sys.stderr)
continue
convert_file(path)
print(f"\n{'' * 60}")
print("Conversion terminée.")
if __name__ == "__main__":
main()
@@ -0,0 +1,143 @@
{
"_id": "e9e583fc41454c90",
"name": "Ajax",
"type": "npc",
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Avatar.webp?1719437847752",
"system": {
"concept": "",
"description": "",
"metier": "",
"faction": "",
"blessures": {
"lvl": 0
},
"destin": {
"lvl": 0
},
"spleen": {
"lvl": 0
},
"stats": {
"ame": {
"label": "ame",
"res": 0,
"actuel": 0
},
"corps": {
"label": "corps",
"res": 0,
"actuel": 0
},
"coeur": {
"label": "coeur",
"res": 0,
"actuel": 0
},
"esprit": {
"label": "esprit",
"res": 0,
"actuel": 0
}
},
"npcType": "standard",
"historique": ""
},
"items": [],
"effects": [],
"folder": null,
"flags": {},
"prototypeToken": {
"name": "Ajax",
"displayName": 0,
"actorLink": false,
"appendNumber": false,
"prependAdjective": false,
"texture": {
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Token.webp?1719437847752",
"scaleX": 1,
"scaleY": 1,
"offsetX": 0,
"offsetY": 0,
"rotation": 0,
"anchorX": 0.5,
"anchorY": 0.5,
"fit": "contain",
"tint": "#ffffff",
"alphaThreshold": 0.75
},
"width": 1,
"height": 1,
"lockRotation": false,
"rotation": 0,
"alpha": 1,
"disposition": -1,
"displayBars": 0,
"bar1": {
"attribute": null
},
"bar2": {
"attribute": null
},
"light": {
"alpha": 0.5,
"angle": 360,
"bright": 0,
"coloration": 1,
"dim": 0,
"attenuation": 0.5,
"luminosity": 0.5,
"saturation": 0,
"contrast": 0,
"shadows": 0,
"animation": {
"type": null,
"speed": 5,
"intensity": 5,
"reverse": false
},
"darkness": {
"min": 0,
"max": 1
},
"negative": false,
"priority": 0,
"color": null
},
"sight": {
"enabled": true,
"range": 30,
"angle": 360,
"visionMode": "basic",
"color": null,
"attenuation": 0.1,
"brightness": 0,
"saturation": 0,
"contrast": 0
},
"detectionModes": [],
"flags": {},
"randomImg": false,
"occludable": {
"radius": 0
},
"ring": {
"enabled": false,
"colors": {
"ring": null,
"background": null
},
"effects": 1,
"subject": {
"scale": 1,
"texture": null
}
},
"turnMarker": {
"mode": 1,
"animation": null,
"src": null,
"disposition": false
},
"movementAction": null
}
}
@@ -0,0 +1,459 @@
{
"folder": "fbRXVyFLLyOpuiTd",
"name": "Ajax",
"type": "npc",
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Avatar.webp?1719437847752",
"system": {
"concept": "",
"anomaly": "0",
"anomalyval": 0,
"anomalymax": "0",
"initiative": 0,
"description": "",
"prefs": {
"typeofthrow": {
"check": true,
"choice": "0"
}
},
"prompt": {
"typeofthrow": {
"check": true,
"choice": "0"
},
"configure": {
"numberofdice": 0,
"aspect": 0,
"bonus": 0,
"bonusauspiciousdice": 0,
"typeofthrow": 0,
"aspectskill": 0,
"bonusmalusskill": 0,
"aspectspeciality": 0,
"rolldifficulty": 0,
"bonusmalusspeciality": 0
}
},
"skill": {
"skilltypes": [
"CEL1922.opt.ame",
"CEL1922.opt.attraction",
"CEL1922.opt.artifice",
"CEL1922.opt.coercition",
"CEL1922.opt.faveur",
"CEL1922.opt.corps",
"CEL1922.opt.echauffouree",
"CEL1922.opt.effacement",
"CEL1922.opt.prouesse",
"CEL1922.opt.mobilite",
"CEL1922.opt.coeur",
"CEL1922.opt.appreciation",
"CEL1922.opt.arts",
"CEL1922.opt.inspiration",
"CEL1922.opt.traque",
"CEL1922.opt.esprit",
"CEL1922.opt.instruction",
"CEL1922.opt.mtechnologique",
"CEL1922.opt.raisonnement",
"CEL1922.opt.traitement"
],
"moondicetypes": [
"CEL1922.opt.nouvellelune",
"CEL1922.opt.premiercroissant",
"CEL1922.opt.premierquartier",
"CEL1922.opt.lunegibbeuse",
"CEL1922.opt.lunevoutee",
"CEL1922.opt.derniercroissant",
"CEL1922.opt.dernierquartier",
"CEL1922.opt.pleinelune"
],
"woundstypes": [
"CEL1922.opt.none",
"CEL1922.opt.anodin",
"CEL1922.opt.derisoire",
"CEL1922.opt.negligeable",
"CEL1922.opt.superficiel",
"CEL1922.opt.leger",
"CEL1922.opt.modere",
"CEL1922.opt.grave",
"CEL1922.opt.dramatique"
],
"woundsmalus": [
0,
0,
0,
-1,
-1,
-2,
-2,
-3,
-999
],
"woundsrecup": [
"CEL1922.opt.none",
"CEL1922.1 minute",
"CEL1922.1 minute",
"CEL1922.10 minutes",
"CEL1922.10 minutes",
"CEL1922.30 minutes",
"CEL1922.30 minutes",
"CEL1922.1 day",
"CEL1922.Out of Fiction"
],
"destinytypes": [
"CEL1922.opt.none",
"CEL1922.opt.libel1",
"CEL1922.opt.libel2",
"CEL1922.opt.libel3",
"CEL1922.opt.libel4",
"CEL1922.opt.libel5",
"CEL1922.opt.libel6",
"CEL1922.opt.libel7",
"CEL1922.opt.libel8"
],
"spleentypes": [
"CEL1922.opt.none",
"CEL1922.opt.libel1",
"CEL1922.opt.libel2",
"CEL1922.opt.libel3",
"CEL1922.opt.libel4",
"CEL1922.opt.libel5",
"CEL1922.opt.libel6",
"CEL1922.opt.libel7",
"CEL1922.opt.libel8"
],
"anomalytypes": [
"CEL1922.opt.none",
"CEL1922.opt.entropie",
"CEL1922.opt.communicationaveclesmorts",
"CEL1922.opt.illusion",
"CEL1922.opt.suggestion",
"CEL1922.opt.tarotdivinatoire",
"CEL1922.opt.telekinesie",
"CEL1922.opt.telepathie",
"CEL1922.opt.voyageastral"
],
"ame": {
"res": 0,
"actuel": 0,
"artifice": {
"value": 0
},
"attraction": {
"value": 0
},
"coercition": {
"value": 0
},
"faveur": {
"value": 0
}
},
"corps": {
"res": 0,
"actuel": 0,
"echauffouree": {
"value": 0
},
"effacement": {
"value": 0
},
"prouesse": {
"value": 0
},
"mobilite": {
"value": 0
}
},
"coeur": {
"res": 0,
"actuel": 0,
"appreciation": {
"value": 0
},
"arts": {
"value": 0
},
"inspiration": {
"value": 0
},
"traque": {
"value": 0
}
},
"esprit": {
"res": 0,
"actuel": 0,
"instruction": {
"value": 0
},
"mtechnologique": {
"value": 0
},
"raisonnement": {
"value": 0
},
"traitement": {
"value": 0
}
},
"aspecttypes": [
"CEL1922.opt.none",
"CEL1922.opt.aspect1",
"CEL1922.opt.aspect2",
"CEL1922.opt.aspect3",
"CEL1922.opt.aspect4",
"CEL1922.opt.aspect5",
"CEL1922.opt.aspect6",
"CEL1922.opt.aspect7",
"CEL1922.opt.aspect8"
]
},
"blessures": {
"lvl": 0,
"blessure_1": {
"check": false,
"bonus": 0,
"malus": 0
},
"blessure_2": {
"check": false,
"bonus": 0,
"malus": 0
},
"blessure_3": {
"check": false,
"bonus": 0,
"malus": -1
},
"blessure_4": {
"check": false,
"bonus": 0,
"malus": -1
},
"blessure_5": {
"check": false,
"bonus": 0,
"malus": -2
},
"blessure_6": {
"check": false,
"bonus": 0,
"malus": -2
},
"blessure_7": {
"check": false,
"bonus": 0,
"malus": -3
},
"blessure_8": {
"check": false,
"bonus": 0,
"malus": -999
}
},
"destin": {
"lvl": 0,
"destin_1": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_2": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_3": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_4": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_5": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_6": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_7": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_8": {
"check": false,
"bonus": 0,
"malus": 0
}
},
"spleen": {
"lvl": 0,
"spleen_1": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_2": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_3": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_4": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_5": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_6": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_7": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_8": {
"check": false,
"bonus": 0,
"malus": 0
}
}
},
"prototypeToken": {
"name": "Ajax",
"displayName": 0,
"actorLink": false,
"appendNumber": false,
"prependAdjective": false,
"texture": {
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/ajax.Token.webp?1719437847752",
"scaleX": 1,
"scaleY": 1,
"offsetX": 0,
"offsetY": 0,
"rotation": 0,
"anchorX": 0.5,
"anchorY": 0.5,
"fit": "contain",
"tint": "#ffffff",
"alphaThreshold": 0.75
},
"width": 1,
"height": 1,
"lockRotation": false,
"rotation": 0,
"alpha": 1,
"disposition": -1,
"displayBars": 0,
"bar1": {
"attribute": null
},
"bar2": {
"attribute": null
},
"light": {
"alpha": 0.5,
"angle": 360,
"bright": 0,
"coloration": 1,
"dim": 0,
"attenuation": 0.5,
"luminosity": 0.5,
"saturation": 0,
"contrast": 0,
"shadows": 0,
"animation": {
"type": null,
"speed": 5,
"intensity": 5,
"reverse": false
},
"darkness": {
"min": 0,
"max": 1
},
"negative": false,
"priority": 0,
"color": null
},
"sight": {
"enabled": true,
"range": 30,
"angle": 360,
"visionMode": "basic",
"color": null,
"attenuation": 0.1,
"brightness": 0,
"saturation": 0,
"contrast": 0
},
"detectionModes": [],
"flags": {},
"randomImg": false,
"occludable": {
"radius": 0
},
"ring": {
"enabled": false,
"colors": {
"ring": null,
"background": null
},
"effects": 1,
"subject": {
"scale": 1,
"texture": null
}
},
"turnMarker": {
"mode": 1,
"animation": null,
"src": null,
"disposition": false
},
"movementAction": null
},
"items": [],
"effects": [],
"flags": {},
"_stats": {
"systemId": "celestopol1922",
"systemVersion": "0.0.7bêta",
"coreVersion": "13.348",
"createdTime": 1719437808862,
"modifiedTime": 1719437944369,
"lastModifiedBy": "6VFjkRpqiseDFIh9",
"compendiumSource": null,
"duplicateSource": null,
"exportSource": {
"worldId": "celestopol-1922",
"uuid": "Actor.QcGcXhb9FvHCb3uf",
"coreVersion": "13.351",
"systemId": "celestopol1922",
"systemVersion": "1.2.0"
}
},
"ownership": {
"default": 0
}
}
@@ -0,0 +1,296 @@
{
"_id": "04f6df7b17f747c6",
"name": "BAO WANG",
"type": "character",
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/systems/celestopol1922/images/pj/bao_wang.png?1719410935795",
"system": {
"concept": "LESCROC",
"description": "<h1>BAO WANG : LESCROC </h1><p></p><p><span class=\"fontstyle0\">Ancien employé du casino flottant la Libellule, Bao Wang officiait comme videur.</span></p><p></p><p><span class=\"fontstyle0\">Après une adolescence de petite frappe dans les faubourgs de Shanghai, il parvint à sintroduire dans un obus-traversier pour rejoindre Célestopol, autant attiré par les perspectives offertes par la cité lunaire que par le besoin de se faire oublier des services de police de sa ville natale.</span></p><p></p><p><span class=\"fontstyle0\">Problème : Bao répugne à se battre et préfère largement la finesse à la violence. De son ancienne vie, il conserve un goût prononcé pour le jeu et la gente féminine. Par ailleurs, Bao a également un certain penchant pour les cabarets clandestins dans lesquels il aime à se travestir à loccasion. Cest dans lun de ces lieux interlopes de la cité que le jeune Chinois a rencontré Ernest. Ils ont sympathisé et le vétéran a su voir un certain potentiel chez Bao. Ce dernier, passablement désœuvré et fauché, accepta sans trop y croire dintégrer lagence du Lys blanc.</span></p><p></p><p><span class=\"fontstyle0\">Son sens de la débrouillardise et son passé houleux parfois bien utile lui octroient des compétences uniques et font désormais de lui un agent indispensable. Le jeune homme sinvestit dailleurs sincèrement dans son travail. Toujours tiré à quatre épingles, Bao est reconnu parmi ses coéquipiers comme le plus nonchalant du groupe.</span> <br style=\"font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;orphans:2;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;widows:2;word-spacing:0px;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px\" /></p>",
"metier": "LESCROC",
"faction": "",
"blessures": {
"lvl": 0
},
"destin": {
"lvl": 0
},
"spleen": {
"lvl": 0
},
"stats": {
"ame": {
"label": "ame",
"res": 2,
"artifice": {
"label": "artifice",
"value": 4
},
"attraction": {
"label": "attraction",
"value": 2
},
"coercition": {
"label": "coercition",
"value": 2
},
"faveur": {
"label": "faveur",
"value": 2
}
},
"corps": {
"label": "corps",
"res": 4,
"echauffouree": {
"label": "echauffouree",
"value": 0
},
"effacement": {
"label": "effacement",
"value": 4
},
"mobilite": {
"label": "mobilite",
"value": 2
},
"prouesse": {
"label": "prouesse",
"value": 2
}
},
"coeur": {
"label": "coeur",
"res": 0,
"appreciation": {
"label": "appreciation",
"value": 2
},
"arts": {
"label": "arts",
"value": 0
},
"inspiration": {
"label": "inspiration",
"value": 1
},
"traque": {
"label": "traque",
"value": 3
}
},
"esprit": {
"label": "esprit",
"res": 0,
"instruction": {
"label": "instruction",
"value": 1
},
"mtechnologique": {
"label": "mtechnologique",
"value": 2
},
"raisonnement": {
"label": "raisonnement",
"value": 1
},
"traitement": {
"label": "traitement",
"value": 2
}
}
},
"anomaly": {
"type": "entropie",
"value": 1
},
"attributs": {
"entregent": {
"value": 0,
"max": 0
},
"fortune": {
"value": 0,
"max": 0
},
"reve": {
"value": 0,
"max": 0
},
"vision": {
"value": 0,
"max": 0
}
},
"historique": "<h1>BAO WANG : LESCROC </h1><p></p><p><span class=\"fontstyle0\">Ancien employé du casino flottant la Libellule, Bao Wang officiait comme videur.</span></p><p></p><p><span class=\"fontstyle0\">Après une adolescence de petite frappe dans les faubourgs de Shanghai, il parvint à sintroduire dans un obus-traversier pour rejoindre Célestopol, autant attiré par les perspectives offertes par la cité lunaire que par le besoin de se faire oublier des services de police de sa ville natale.</span></p><p></p><p><span class=\"fontstyle0\">Problème : Bao répugne à se battre et préfère largement la finesse à la violence. De son ancienne vie, il conserve un goût prononcé pour le jeu et la gente féminine. Par ailleurs, Bao a également un certain penchant pour les cabarets clandestins dans lesquels il aime à se travestir à loccasion. Cest dans lun de ces lieux interlopes de la cité que le jeune Chinois a rencontré Ernest. Ils ont sympathisé et le vétéran a su voir un certain potentiel chez Bao. Ce dernier, passablement désœuvré et fauché, accepta sans trop y croire dintégrer lagence du Lys blanc.</span></p><p></p><p><span class=\"fontstyle0\">Son sens de la débrouillardise et son passé houleux parfois bien utile lui octroient des compétences uniques et font désormais de lui un agent indispensable. Le jeune homme sinvestit dailleurs sincèrement dans son travail. Toujours tiré à quatre épingles, Bao est reconnu parmi ses coéquipiers comme le plus nonchalant du groupe.</span> <br style=\"font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;orphans:2;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;widows:2;word-spacing:0px;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px\" /></p>",
"descriptionPhysique": "",
"descriptionPsychologique": "",
"initiative": 0,
"factions": {
"pinkerton": 0,
"police": 0,
"okhrana": 0,
"lunanovatek": 0,
"oto": 0,
"syndicats": 0,
"vorovskoymir": 0,
"cour": 0,
"perso": 0,
"libel": "",
"perso2": 0,
"libel2": ""
}
},
"items": [
{
"_id": "23315ed101e248c8",
"name": "Entropie 1",
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
"effects": [],
"flags": {},
"sort": 0,
"type": "anomaly",
"system": {
"subtype": "entropie",
"level": 1,
"usesRemaining": 1,
"technique": "<p><span class=\"fontstyle0\">Bao peut relancer le dé de la Lune une fois lors dun même scénario et choisit de conserver le résultat quil préfère (cette faculté ne fonctionne pas sur les tests de chance).</span></p>",
"narratif": "<p><span class=\"fontstyle0\">Bao peut influer sur le hasard de manière mineure. </span><span class=\"fontstyle2\">Exemple : <em>avoir une bonne main en jouant au poker à la distribution, que le feu soit au vert en tournant au coin de la rue, etc.</em></span></p>"
}
},
{
"_id": "4edb4b80b9514a7b",
"name": "Belle gueule 2",
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
"effects": [],
"flags": {},
"sort": 0,
"type": "aspect",
"system": {
"valeur": 2,
"description": ""
}
},
{
"_id": "153b0a094ca4462e",
"name": "Aime le jeu 1",
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
"effects": [],
"flags": {},
"sort": 0,
"type": "aspect",
"system": {
"valeur": 1,
"description": ""
}
},
{
"_id": "cbdc76f66bd041a0",
"name": "Nouvel Équipement",
"img": "https://assets.forge-vtt.com/bazaar/core/icons/svg/item-bag.svg",
"effects": [],
"flags": {},
"sort": 0,
"type": "equipment",
"system": {
"description": ""
}
}
],
"effects": [],
"folder": null,
"flags": {},
"prototypeToken": {
"name": "BAO WANG",
"displayName": 0,
"actorLink": false,
"appendNumber": false,
"prependAdjective": false,
"texture": {
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/bao_wang.Token.webp?1719410935795",
"scaleX": 1,
"scaleY": 1,
"offsetX": 0,
"offsetY": 0,
"rotation": 0,
"tint": "#ffffff",
"anchorX": 0.5,
"anchorY": 0.5,
"fit": "contain",
"alphaThreshold": 0.75
},
"width": 1,
"height": 1,
"lockRotation": false,
"rotation": 0,
"alpha": 1,
"disposition": -1,
"displayBars": 0,
"bar1": {
"attribute": null
},
"bar2": {
"attribute": null
},
"light": {
"alpha": 0.5,
"angle": 360,
"bright": 0,
"coloration": 1,
"dim": 0,
"attenuation": 0.5,
"luminosity": 0.5,
"saturation": 0,
"contrast": 0,
"shadows": 0,
"animation": {
"type": null,
"speed": 5,
"intensity": 5,
"reverse": false
},
"darkness": {
"min": 0,
"max": 1
},
"color": null,
"negative": false,
"priority": 0
},
"sight": {
"enabled": false,
"range": 0,
"angle": 360,
"visionMode": "basic",
"attenuation": 0.1,
"brightness": 0,
"saturation": 0,
"contrast": 0,
"color": null
},
"detectionModes": [],
"flags": {},
"randomImg": false,
"occludable": {
"radius": 0
},
"ring": {
"enabled": false,
"colors": {
"ring": null,
"background": null
},
"effects": 1,
"subject": {
"scale": 1,
"texture": null
}
},
"turnMarker": {
"mode": 1,
"animation": null,
"src": null,
"disposition": false
},
"movementAction": null
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,143 @@
{
"_id": "fabe178df844475b",
"name": "Citoyen",
"type": "npc",
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Avatar.webp?1719438184882",
"system": {
"concept": "",
"description": "",
"metier": "",
"faction": "",
"blessures": {
"lvl": 0
},
"destin": {
"lvl": 0
},
"spleen": {
"lvl": 0
},
"stats": {
"ame": {
"label": "ame",
"res": 0,
"actuel": 0
},
"corps": {
"label": "corps",
"res": 0,
"actuel": 0
},
"coeur": {
"label": "coeur",
"res": 0,
"actuel": 0
},
"esprit": {
"label": "esprit",
"res": 0,
"actuel": 0
}
},
"npcType": "standard",
"historique": ""
},
"items": [],
"effects": [],
"folder": null,
"flags": {},
"prototypeToken": {
"name": "Citoyen",
"displayName": 0,
"actorLink": false,
"appendNumber": false,
"prependAdjective": false,
"texture": {
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Token.webp?1719438184882",
"scaleX": 1,
"scaleY": 1,
"offsetX": 0,
"offsetY": 0,
"rotation": 0,
"anchorX": 0.5,
"anchorY": 0.5,
"fit": "contain",
"tint": "#ffffff",
"alphaThreshold": 0.75
},
"width": 1,
"height": 1,
"lockRotation": false,
"rotation": 0,
"alpha": 1,
"disposition": -1,
"displayBars": 0,
"bar1": {
"attribute": null
},
"bar2": {
"attribute": null
},
"light": {
"alpha": 0.5,
"angle": 360,
"bright": 0,
"coloration": 1,
"dim": 0,
"attenuation": 0.5,
"luminosity": 0.5,
"saturation": 0,
"contrast": 0,
"shadows": 0,
"animation": {
"type": null,
"speed": 5,
"intensity": 5,
"reverse": false
},
"darkness": {
"min": 0,
"max": 1
},
"negative": false,
"priority": 0,
"color": null
},
"sight": {
"enabled": true,
"range": 30,
"angle": 360,
"visionMode": "basic",
"color": null,
"attenuation": 0.1,
"brightness": 0,
"saturation": 0,
"contrast": 0
},
"detectionModes": [],
"flags": {},
"randomImg": false,
"occludable": {
"radius": 0
},
"ring": {
"enabled": false,
"colors": {
"ring": null,
"background": null
},
"effects": 1,
"subject": {
"scale": 1,
"texture": null
}
},
"turnMarker": {
"mode": 1,
"animation": null,
"src": null,
"disposition": false
},
"movementAction": null
}
}
@@ -0,0 +1,459 @@
{
"folder": "5aDs3Gbi2cHy35X9",
"name": "Citoyen",
"type": "npc",
"img": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Avatar.webp?1719438184882",
"system": {
"concept": "",
"anomaly": "0",
"anomalyval": 0,
"anomalymax": "0",
"initiative": 0,
"description": "",
"prefs": {
"typeofthrow": {
"check": true,
"choice": "0"
}
},
"prompt": {
"typeofthrow": {
"check": true,
"choice": "0"
},
"configure": {
"numberofdice": 0,
"aspect": 0,
"bonus": 0,
"bonusauspiciousdice": 0,
"typeofthrow": 0,
"aspectskill": 0,
"bonusmalusskill": 0,
"aspectspeciality": 0,
"rolldifficulty": 0,
"bonusmalusspeciality": 0
}
},
"skill": {
"skilltypes": [
"CEL1922.opt.ame",
"CEL1922.opt.attraction",
"CEL1922.opt.artifice",
"CEL1922.opt.coercition",
"CEL1922.opt.faveur",
"CEL1922.opt.corps",
"CEL1922.opt.echauffouree",
"CEL1922.opt.effacement",
"CEL1922.opt.prouesse",
"CEL1922.opt.mobilite",
"CEL1922.opt.coeur",
"CEL1922.opt.appreciation",
"CEL1922.opt.arts",
"CEL1922.opt.inspiration",
"CEL1922.opt.traque",
"CEL1922.opt.esprit",
"CEL1922.opt.instruction",
"CEL1922.opt.mtechnologique",
"CEL1922.opt.raisonnement",
"CEL1922.opt.traitement"
],
"moondicetypes": [
"CEL1922.opt.nouvellelune",
"CEL1922.opt.premiercroissant",
"CEL1922.opt.premierquartier",
"CEL1922.opt.lunegibbeuse",
"CEL1922.opt.lunevoutee",
"CEL1922.opt.derniercroissant",
"CEL1922.opt.dernierquartier",
"CEL1922.opt.pleinelune"
],
"woundstypes": [
"CEL1922.opt.none",
"CEL1922.opt.anodin",
"CEL1922.opt.derisoire",
"CEL1922.opt.negligeable",
"CEL1922.opt.superficiel",
"CEL1922.opt.leger",
"CEL1922.opt.modere",
"CEL1922.opt.grave",
"CEL1922.opt.dramatique"
],
"woundsmalus": [
0,
0,
0,
-1,
-1,
-2,
-2,
-3,
-999
],
"woundsrecup": [
"CEL1922.opt.none",
"CEL1922.1 minute",
"CEL1922.1 minute",
"CEL1922.10 minutes",
"CEL1922.10 minutes",
"CEL1922.30 minutes",
"CEL1922.30 minutes",
"CEL1922.1 day",
"CEL1922.Out of Fiction"
],
"destinytypes": [
"CEL1922.opt.none",
"CEL1922.opt.libel1",
"CEL1922.opt.libel2",
"CEL1922.opt.libel3",
"CEL1922.opt.libel4",
"CEL1922.opt.libel5",
"CEL1922.opt.libel6",
"CEL1922.opt.libel7",
"CEL1922.opt.libel8"
],
"spleentypes": [
"CEL1922.opt.none",
"CEL1922.opt.libel1",
"CEL1922.opt.libel2",
"CEL1922.opt.libel3",
"CEL1922.opt.libel4",
"CEL1922.opt.libel5",
"CEL1922.opt.libel6",
"CEL1922.opt.libel7",
"CEL1922.opt.libel8"
],
"anomalytypes": [
"CEL1922.opt.none",
"CEL1922.opt.entropie",
"CEL1922.opt.communicationaveclesmorts",
"CEL1922.opt.illusion",
"CEL1922.opt.suggestion",
"CEL1922.opt.tarotdivinatoire",
"CEL1922.opt.telekinesie",
"CEL1922.opt.telepathie",
"CEL1922.opt.voyageastral"
],
"ame": {
"res": 0,
"actuel": 0,
"artifice": {
"value": 0
},
"attraction": {
"value": 0
},
"coercition": {
"value": 0
},
"faveur": {
"value": 0
}
},
"corps": {
"res": 0,
"actuel": 0,
"echauffouree": {
"value": 0
},
"effacement": {
"value": 0
},
"prouesse": {
"value": 0
},
"mobilite": {
"value": 0
}
},
"coeur": {
"res": 0,
"actuel": 0,
"appreciation": {
"value": 0
},
"arts": {
"value": 0
},
"inspiration": {
"value": 0
},
"traque": {
"value": 0
}
},
"esprit": {
"res": 0,
"actuel": 0,
"instruction": {
"value": 0
},
"mtechnologique": {
"value": 0
},
"raisonnement": {
"value": 0
},
"traitement": {
"value": 0
}
},
"aspecttypes": [
"CEL1922.opt.none",
"CEL1922.opt.aspect1",
"CEL1922.opt.aspect2",
"CEL1922.opt.aspect3",
"CEL1922.opt.aspect4",
"CEL1922.opt.aspect5",
"CEL1922.opt.aspect6",
"CEL1922.opt.aspect7",
"CEL1922.opt.aspect8"
]
},
"blessures": {
"lvl": 0,
"blessure_1": {
"check": false,
"bonus": 0,
"malus": 0
},
"blessure_2": {
"check": false,
"bonus": 0,
"malus": 0
},
"blessure_3": {
"check": false,
"bonus": 0,
"malus": -1
},
"blessure_4": {
"check": false,
"bonus": 0,
"malus": -1
},
"blessure_5": {
"check": false,
"bonus": 0,
"malus": -2
},
"blessure_6": {
"check": false,
"bonus": 0,
"malus": -2
},
"blessure_7": {
"check": false,
"bonus": 0,
"malus": -3
},
"blessure_8": {
"check": false,
"bonus": 0,
"malus": -999
}
},
"destin": {
"lvl": 0,
"destin_1": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_2": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_3": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_4": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_5": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_6": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_7": {
"check": false,
"bonus": 0,
"malus": 0
},
"destin_8": {
"check": false,
"bonus": 0,
"malus": 0
}
},
"spleen": {
"lvl": 0,
"spleen_1": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_2": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_3": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_4": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_5": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_6": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_7": {
"check": false,
"bonus": 0,
"malus": 0
},
"spleen_8": {
"check": false,
"bonus": 0,
"malus": 0
}
}
},
"prototypeToken": {
"name": "Citoyen",
"displayName": 0,
"actorLink": false,
"appendNumber": false,
"prependAdjective": false,
"texture": {
"src": "https://assets.forge-vtt.com/630dd9fa56bd61d804eb1dec/tokenizer/celestopol/citoyen.Token.webp?1719438184882",
"scaleX": 1,
"scaleY": 1,
"offsetX": 0,
"offsetY": 0,
"rotation": 0,
"anchorX": 0.5,
"anchorY": 0.5,
"fit": "contain",
"tint": "#ffffff",
"alphaThreshold": 0.75
},
"width": 1,
"height": 1,
"lockRotation": false,
"rotation": 0,
"alpha": 1,
"disposition": -1,
"displayBars": 0,
"bar1": {
"attribute": null
},
"bar2": {
"attribute": null
},
"light": {
"alpha": 0.5,
"angle": 360,
"bright": 0,
"coloration": 1,
"dim": 0,
"attenuation": 0.5,
"luminosity": 0.5,
"saturation": 0,
"contrast": 0,
"shadows": 0,
"animation": {
"type": null,
"speed": 5,
"intensity": 5,
"reverse": false
},
"darkness": {
"min": 0,
"max": 1
},
"negative": false,
"priority": 0,
"color": null
},
"sight": {
"enabled": true,
"range": 30,
"angle": 360,
"visionMode": "basic",
"color": null,
"attenuation": 0.1,
"brightness": 0,
"saturation": 0,
"contrast": 0
},
"detectionModes": [],
"flags": {},
"randomImg": false,
"occludable": {
"radius": 0
},
"ring": {
"enabled": false,
"colors": {
"ring": null,
"background": null
},
"effects": 1,
"subject": {
"scale": 1,
"texture": null
}
},
"turnMarker": {
"mode": 1,
"animation": null,
"src": null,
"disposition": false
},
"movementAction": null
},
"items": [],
"effects": [],
"flags": {},
"_stats": {
"systemId": "celestopol1922",
"systemVersion": "0.0.7bêta",
"coreVersion": "13.348",
"createdTime": 1719438039685,
"modifiedTime": 1719438184895,
"lastModifiedBy": "6VFjkRpqiseDFIh9",
"compendiumSource": null,
"duplicateSource": null,
"exportSource": {
"worldId": "celestopol-1922",
"uuid": "Actor.H4qPWYC8kbacuBfm",
"coreVersion": "13.351",
"systemId": "celestopol1922",
"systemVersion": "1.2.0"
}
},
"ownership": {
"default": 0
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

+305
View File
@@ -43,6 +43,7 @@ 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"
const DEFAULT_ROLL_THRESHOLD_SETTING = "defaultRollThreshold"
/* ─── Init hook ──────────────────────────────────────────────────────────── */ /* ─── Init hook ──────────────────────────────────────────────────────────── */
@@ -65,8 +66,10 @@ Hooks.once("init", () => {
// Expose SYSTEM constants + utilities globales // Expose SYSTEM constants + utilities globales
game.celestopol = { game.celestopol = {
SYSTEM, SYSTEM,
DEFAULT_ROLL_THRESHOLD_SETTING,
rollMoonStandalone: (actor = null) => CelestopolRoll.rollMoonStandalone(actor), rollMoonStandalone: (actor = null) => CelestopolRoll.rollMoonStandalone(actor),
manageFactionAspects: (actor = null) => _manageFactionAspects(actor), manageFactionAspects: (actor = null) => _manageFactionAspects(actor),
resetFactionAspects: () => _resetFactionAspects(),
getFactionAspectState: () => _getFactionAspectState(), getFactionAspectState: () => _getFactionAspectState(),
getFactionAspectSummary: (actor = null) => _getFactionAspectSummary(actor), getFactionAspectSummary: (actor = null) => _getFactionAspectSummary(actor),
getFactionDisplayLabel: (value) => _getFactionDisplayLabel(value), getFactionDisplayLabel: (value) => _getFactionDisplayLabel(value),
@@ -356,11 +359,269 @@ function _registerHandlebarsHelpers() {
return false return false
}) })
// Helper : récupérer un setting système par son nom
Handlebars.registerHelper("getSetting", (settingName) => {
return game.settings.get(SYSTEM_ID, settingName)
})
Handlebars.registerHelper("let", function(value, options) { Handlebars.registerHelper("let", function(value, options) {
return options.fn({ value }) return options.fn({ value })
}) })
} }
/* ─── Migration depuis l'ancien système ─────────────────────────────────── */
/** Mapping des types d'anomalies ancien→nouveau */
const _OLD_ANOMALY_TYPES = [
"none", "entropie", "communicationaveclesmorts", "illusion",
"suggestion", "tarotdivinatoire", "telekinesie", "telepathie", "voyageastral",
]
const _OLD_SKILLS = {
ame: ["artifice", "attraction", "coercition", "faveur"],
corps: ["echauffouree", "effacement", "mobilite", "prouesse"],
coeur: ["appreciation", "arts", "inspiration", "traque"],
esprit: ["instruction", "mtechnologique", "raisonnement", "traitement"],
}
/** Infère le type d'anomalie depuis le nom de l'item (ex: "Entropie 1" → "entropie"). */
function _anomalyTypeFromName(name) {
let n = name.toLowerCase().replace(/\s*\d+\s*$/, "").replace(/\s+/g, "")
const accents = [["é","e"],["è","e"],["ê","e"],["ë","e"],["à","a"],["â","a"],
["î","i"],["ï","i"],["ô","o"],["û","u"],["ù","u"],["ü","u"],["ç","c"]]
for (const [s,d] of accents) n = n.replaceAll(s, d)
return _OLD_ANOMALY_TYPES.find(k => k !== "none" && (k.includes(n) || n.includes(k))) ?? "none"
}
/** Convertit les stats d'un PJ (skill → stats). */
function _convertStatsCharacter(oldSkill) {
const stats = {}
for (const stat of ["ame","corps","coeur","esprit"]) {
const os = oldSkill[stat] ?? {}
const ns = { label: stat, res: Number(os.res ?? 0) }
for (const sk of _OLD_SKILLS[stat]) {
const val = Number(os[sk]?.value ?? 0) || 0
ns[sk] = { label: sk, value: val }
}
stats[stat] = ns
}
return stats
}
/** Convertit les stats d'un PNJ (skill → stats avec actuel). */
function _convertStatsNPC(oldSkill) {
const stats = {}
for (const stat of ["ame","corps","coeur","esprit"]) {
const res = Number(oldSkill[stat]?.res ?? 0)
stats[stat] = { label: stat, res, actuel: res }
}
return stats
}
/** Convertit les attributs du format plat vers {value, max}. */
function _convertAttributs(a = {}) {
return {
entregent: { value: Number(a.entregent ?? 0), max: Number(a.entregentmax ?? 0) },
fortune: { value: Number(a.fortune ?? 0), max: Number(a.fortunemax ?? 0) },
reve: { value: Number(a.reve ?? 0), max: Number(a.revemax ?? 0) },
vision: { value: Number(a.vision ?? 0), max: Number(a.visionmax ?? 0) },
}
}
/** Convertit un item de l'ancien format. Retourne null si ignoré. */
function _convertItem(item, warnings) {
const os = item.system ?? {}
const name = item.name ?? "Sans nom"
const base = {
name,
img: item.img ?? "icons/svg/item-bag.svg",
effects: [],
flags: {},
sort: 0,
}
if (item.type === "anomaly") {
const level = Math.max(1, Math.min(4, Number(os.value ?? 1) || 1))
const subtype = _anomalyTypeFromName(name)
if (subtype === "none")
warnings.push(`Impossible de déterminer le type d'anomalie depuis "${name}"`)
return { ...base, type: "anomaly", system: {
subtype, level, usesRemaining: level,
technique: os.technique ?? "", narratif: os.narratif ?? "",
}}
}
if (item.type === "aspect") {
return { ...base, type: "aspect", system: {
valeur: Number(os.value ?? 0) || 0,
description: os.narratif ?? os.technique ?? "",
}}
}
if (item.type === "item") {
const sub = (os.subtype ?? "").toLowerCase()
if (sub === "weapon") {
if (os.damage) warnings.push(`"${name}" : dégâts "${os.damage}" à saisir manuellement`)
return { ...base, type: "weapon", system: {
type: "melee", degats: "0", portee: "contact", equipped: false,
description: os.technique ?? os.narratif ?? "",
}}
}
if (sub === "armor") {
if (os.protection) warnings.push(`"${name}" : protection "${os.protection}" à saisir manuellement`)
return { ...base, type: "armure", system: {
protection: 1, malus: 1, equipped: false,
description: os.technique ?? os.narratif ?? "",
}}
}
return { ...base, type: "equipment", system: {
description: os.technique ?? os.narratif ?? "",
}}
}
warnings.push(`Type d'item inconnu "${item.type}" pour "${name}", ignoré`)
return null
}
/** Convertit un acteur complet de l'ancien format vers le nouveau. */
function _convertOldActor(old) {
const warnings = []
const os = old.system ?? {}
const osk = os.skill ?? {}
const type = old.type ?? "character"
// Anomalie : résolution depuis l'index stocké dans os.anomaly
const anomalyIdx = Number(os.anomaly ?? 0)
const anomalyTypes = osk.anomalytypes ?? _OLD_ANOMALY_TYPES.map(k => `CEL1922.opt.${k}`)
const rawAnomalyKey = (anomalyTypes[anomalyIdx] ?? "").split(".").pop() ?? "none"
const anomalyType = _OLD_ANOMALY_TYPES.includes(rawAnomalyKey) ? rawAnomalyKey : "none"
const sys = {
concept: os.concept ?? "",
metier: os.metier ?? os.concept ?? "",
faction: os.faction ?? "",
blessures: { lvl: Number(os.blessures?.lvl ?? 0) },
destin: { lvl: Number(os.destin?.lvl ?? 0) },
spleen: { lvl: Number(os.spleen?.lvl ?? 0) },
}
if (type === "character") {
sys.stats = _convertStatsCharacter(osk)
sys.anomaly = { type: anomalyType, value: Number(os.anomalyval ?? 0) }
sys.attributs = _convertAttributs(os.attributs)
sys.historique = os.description ?? ""
sys.descriptionPhysique = ""
sys.descriptionPsychologique = ""
sys.initiative = 0
sys.factions = os.factions ?? {}
} else {
sys.stats = _convertStatsNPC(osk)
sys.npcType = os.npcType ?? "standard"
sys.historique = os.description ?? ""
}
const items = (old.items ?? []).map(it => _convertItem(it, warnings)).filter(Boolean)
const actor = {
name: old.name ?? "Personnage sans nom",
type,
img: old.img ?? "icons/svg/mystery-man.svg",
system: sys,
items,
effects: [],
folder: null,
flags: {},
prototypeToken: old.prototypeToken ?? {},
}
return { actor, warnings }
}
/** Ouvre la dialog DialogV2 de migration et gère l'import de l'acteur. */
async function _openMigrationDialog() {
const content = `
<div class="cel-migration-dialog" style="padding:0.5em 0">
<p style="margin-bottom:0.8em">${game.i18n.localize("CELESTOPOL.Migration.instructions")}</p>
<div style="display:flex;gap:0.5em;align-items:center">
<label style="font-weight:bold;white-space:nowrap">
${game.i18n.localize("CELESTOPOL.Migration.fileLabel")}
</label>
<input type="file" id="cel-migration-file" accept=".json" style="flex:1">
</div>
</div>`
await foundry.applications.api.DialogV2.wait({
window: { title: game.i18n.localize("CELESTOPOL.Migration.title") },
classes: ["fvtt-celestopol"],
content,
buttons: [
{
label: game.i18n.localize("CELESTOPOL.Migration.importBtn"),
icon: "fas fa-file-import",
action: "import",
default: true,
callback: (_event, _btn, dialog) => {
const fileInput = dialog.element.querySelector("#cel-migration-file")
return fileInput?.files?.[0] ?? null
},
},
{
label: game.i18n.localize("Cancel"),
icon: "fas fa-times",
action: "cancel",
callback: () => null,
},
],
submit: async (result) => {
if (!result) return
const text = await result.text()
let old
try { old = JSON.parse(text) }
catch {
ui.notifications.error(game.i18n.localize("CELESTOPOL.Migration.errorParse"))
return
}
const { actor, warnings } = _convertOldActor(old)
try {
const created = await Actor.create(actor)
ui.notifications.info(game.i18n.format("CELESTOPOL.Migration.success", {
name: created.name, count: actor.items.length,
}))
if (warnings.length) {
console.warn(`Célestopol Migration | ${created.name} — avertissements :`)
warnings.forEach(w => console.warn(" ⚠", w))
ui.notifications.warn(game.i18n.format("CELESTOPOL.Migration.warnings", { count: warnings.length }))
}
} catch(err) {
console.error("Célestopol Migration | Échec de création de l'acteur :", err)
ui.notifications.error(game.i18n.localize("CELESTOPOL.Migration.errorCreate"))
}
},
})
}
/**
* Classe de menu de paramètre pour la migration.
* Étend ApplicationV2 (requis par registerMenu) mais surcharge render()
* pour déclencher directement la dialog de migration.
*/
class CelestopolMigrationMenu extends foundry.applications.api.ApplicationV2 {
static DEFAULT_OPTIONS = {
id: "celestopol-migration",
window: { title: "CELESTOPOL.Migration.title" },
classes: ["fvtt-celestopol"],
position: { width: 480 },
}
/** Surcharge : ignore le rendu AppV2 et ouvre directement la dialog. */
async render(...args) {
await _openMigrationDialog()
return this
}
}
/* ─── Settings ───────────────────────────────────────────────────────────── */ /* ─── Settings ───────────────────────────────────────────────────────────── */
function _registerSettings() { function _registerSettings() {
@@ -372,6 +633,22 @@ function _registerSettings() {
type: Boolean, type: Boolean,
default: false, default: false,
}) })
// Seuil de difficulté par défaut pour les jets normaux (hors combat)
game.settings.register(SYSTEM_ID, DEFAULT_ROLL_THRESHOLD_SETTING, {
name: "CELESTOPOL.Setting.defaultRollThreshold.name",
hint: "CELESTOPOL.Setting.defaultRollThreshold.hint",
scope: "world",
config: true,
type: Number,
default: 11,
range: {
min: 1,
max: 30,
step: 1,
},
})
// Suivi de l'import des anomalies (caché) // Suivi de l'import des anomalies (caché)
game.settings.register(SYSTEM_ID, "anomaliesImported", { game.settings.register(SYSTEM_ID, "anomaliesImported", {
scope: "world", scope: "world",
@@ -397,6 +674,16 @@ function _registerSettings() {
type: Boolean, type: Boolean,
default: false, default: false,
}) })
// Entrée de menu : migration depuis l'ancien système
game.settings.registerMenu(SYSTEM_ID, "migrateOldSystem", {
name: "CELESTOPOL.Setting.migrateOldSystem.name",
hint: "CELESTOPOL.Setting.migrateOldSystem.hint",
label: "CELESTOPOL.Setting.migrateOldSystem.label",
icon: "fas fa-file-import",
type: CelestopolMigrationMenu,
restricted: true,
})
} }
async function _createWelcomeChatMessage() { async function _createWelcomeChatMessage() {
@@ -955,6 +1242,24 @@ async function _setFactionAspectState(state) {
return cleanState return cleanState
} }
async function _resetFactionAspects() {
if (!game.user.isGM) {
ui.notifications.warn(game.i18n.localize("CELESTOPOL.FactionAspect.gmOnly"))
return
}
const confirmed = await foundry.applications.api.DialogV2.confirm({
window: { title: game.i18n.localize("CELESTOPOL.FactionAspect.resetTitle") },
content: `<p>${game.i18n.localize("CELESTOPOL.FactionAspect.resetConfirm")}</p>`,
yes: { label: game.i18n.localize("CELESTOPOL.FactionAspect.resetConfirmYes"), icon: "fas fa-redo" },
no: { label: game.i18n.localize("Cancel"), icon: "fas fa-times" },
rejectClose: false,
})
if (!confirmed) return
const state = _getFactionAspectState()
await _setFactionAspectState({ ...state, activatedAspects: [] })
ui.notifications.info(game.i18n.localize("CELESTOPOL.FactionAspect.resetSuccess"))
}
function _refreshFactionAspectSheets() { function _refreshFactionAspectSheets() {
for (const actor of game.actors.contents) { for (const actor of game.actors.contents) {
if (actor.type !== "character") continue if (actor.type !== "character") continue
+25 -1
View File
@@ -189,7 +189,12 @@
"renforts": "Renforts", "renforts": "Renforts",
"renseignements": "Renseignements", "renseignements": "Renseignements",
"ressources": "Ressources", "ressources": "Ressources",
"surveillance": "Surveillance" "surveillance": "Surveillance",
"resetButton": "Réinitialiser",
"resetTitle": "Réinitialiser les Aspects de faction",
"resetConfirm": "Voulez-vous réinitialiser tous les Aspects de faction mobilisés ? Cette action efface la réserve de scénario en cours.",
"resetConfirmYes": "Réinitialiser",
"resetSuccess": "Aspects de faction réinitialisés pour le nouveau scénario."
}, },
"Track": { "Track": {
"blessures": "Blessures", "blessures": "Blessures",
@@ -448,8 +453,27 @@
"rollMoonDieByDefault": { "rollMoonDieByDefault": {
"name": "Lancer le dé de la lune par défaut", "name": "Lancer le dé de la lune par défaut",
"hint": "Cocher automatiquement 'Lancer le dé de la lune' dans les fenêtres de jet" "hint": "Cocher automatiquement 'Lancer le dé de la lune' dans les fenêtres de jet"
},
"defaultRollThreshold": {
"name": "Seuil de difficulté par défaut",
"hint": "Valeur du seuil utilisée par défaut pour les jets de compétence hors combat"
},
"migrateOldSystem": {
"name": "Migration depuis l'ancien système",
"hint": "Importer un personnage exporté depuis l'ancien système Célestopol 1922 (celestopol1922).",
"label": "Migrer un personnage…"
} }
}, },
"Migration": {
"title": "Migration ancien système Célestopol",
"instructions": "Sélectionnez un fichier JSON exporté depuis l'ancien système Célestopol 1922. Le personnage sera converti et créé automatiquement dans la liste des acteurs.",
"fileLabel": "Fichier JSON :",
"importBtn": "Convertir et importer",
"success": "'{name}' importé avec succès ({count} item(s)).",
"warnings": "{count} avertissement(s) — consultez la console (F12) pour le détail.",
"errorParse": "Impossible de lire le fichier JSON. Vérifiez qu'il s'agit bien d'un export Célestopol valide.",
"errorCreate": "Échec de la création de l'acteur. Consultez la console (F12) pour le détail."
},
"Welcome": { "Welcome": {
"title": "Bienvenue dans Célestopol 1922", "title": "Bienvenue dans Célestopol 1922",
"intro": "Bienvenue dans le système FoundryVTT de Célestopol 1922.", "intro": "Bienvenue dans le système FoundryVTT de Célestopol 1922.",
@@ -32,6 +32,7 @@ export default class CelestopolCharacterSheet extends CelestopolActorSheet {
supprimerXpLog: CelestopolCharacterSheet.#onSupprimerXpLog, supprimerXpLog: CelestopolCharacterSheet.#onSupprimerXpLog,
rollMoonDie: CelestopolCharacterSheet.#onRollMoonDie, rollMoonDie: CelestopolCharacterSheet.#onRollMoonDie,
manageFactionAspects: CelestopolCharacterSheet.#onManageFactionAspects, manageFactionAspects: CelestopolCharacterSheet.#onManageFactionAspects,
resetFactionAspects: CelestopolCharacterSheet.#onResetFactionAspects,
}, },
} }
@@ -245,6 +246,10 @@ export default class CelestopolCharacterSheet extends CelestopolActorSheet {
await game.celestopol?.manageFactionAspects(this.document) await game.celestopol?.manageFactionAspects(this.document)
} }
static async #onResetFactionAspects() {
await game.celestopol?.resetFactionAspects()
}
/** Ouvre un dialogue pour dépenser de l'XP. */ /** Ouvre un dialogue pour dépenser de l'XP. */
static async #onDepenseXp() { static async #onDepenseXp() {
const actor = this.document const actor = this.document
+10 -7
View File
@@ -294,12 +294,13 @@ export class CelestopolRoll extends Roll {
if (!rollContext) return null if (!rollContext) return null
// En combat : Corps PNJ = seuil direct ; sinon seuil fixe = 11 // En combat : Corps PNJ = seuil direct ; sinon seuil configurable via setting
const corpsPnj = isCombat ? (parseInt(rollContext.corpsPnj ?? 7) || 7) : null const corpsPnj = isCombat ? (parseInt(rollContext.corpsPnj ?? 7) || 7) : null
const difficulty = isCombat ? "combat" : "standard" const difficulty = isCombat ? "combat" : "standard"
const defaultThreshold = game.settings.get(game.celestopol.SYSTEM.id, game.celestopol.DEFAULT_ROLL_THRESHOLD_SETTING)
const diffConfig = isCombat const diffConfig = isCombat
? { value: corpsPnj, label: "CELESTOPOL.Combat.corpsPnj" } ? { value: corpsPnj, label: "CELESTOPOL.Combat.corpsPnj" }
: { value: 11, label: "CELESTOPOL.Roll.threshold" } : { value: defaultThreshold, label: "CELESTOPOL.Roll.threshold" }
const autoSuccess = rollContext.modifier === "auto" const autoSuccess = rollContext.modifier === "auto"
const modifier = autoSuccess ? 0 : (parseInt(rollContext.modifier ?? 0) || 0) const modifier = autoSuccess ? 0 : (parseInt(rollContext.modifier ?? 0) || 0)
const aspectMod = parseInt(rollContext.aspectModifier ?? 0) || 0 const aspectMod = parseInt(rollContext.aspectModifier ?? 0) || 0
@@ -464,7 +465,7 @@ export class CelestopolRoll extends Roll {
/** /**
* Détermine succès/échec selon la marge (total seuil). * Détermine succès/échec selon la marge (total seuil).
* Seuil : 11 pour les tests normaux, Corps PNJ pour le combat. * Seuil : configurable via setting pour les tests normaux, Corps PNJ pour le combat.
* Pas de succès/échec critique — seul le Dé de la Lune produit des résultats exceptionnels. * Pas de succès/échec critique — seul le Dé de la Lune produit des résultats exceptionnels.
*/ */
computeResult() { computeResult() {
@@ -479,9 +480,10 @@ export class CelestopolRoll extends Roll {
this.options.margin = null this.options.margin = null
return return
} }
const defaultThreshold = game.settings.get(game.celestopol.SYSTEM.id, game.celestopol.DEFAULT_ROLL_THRESHOLD_SETTING)
const threshold = this.options.isCombat const threshold = this.options.isCombat
? (this.options.difficultyValue ?? 0) ? (this.options.difficultyValue ?? 0)
: 11 : defaultThreshold
if (threshold === 0) { if (threshold === 0) {
this.options.resultType = "unknown" this.options.resultType = "unknown"
this.options.margin = null this.options.margin = null
@@ -510,9 +512,10 @@ export class CelestopolRoll extends Roll {
const resultType = this.resultType const resultType = this.resultType
const diceResults = this.dice[0]?.results?.map(r => r.result) ?? [] const diceResults = this.dice[0]?.results?.map(r => r.result) ?? []
const diceSum = diceResults.reduce((a, b) => a + b, 0) const diceSum = diceResults.reduce((a, b) => a + b, 0)
const defaultThreshold = game.settings.get(game.celestopol.SYSTEM.id, game.celestopol.DEFAULT_ROLL_THRESHOLD_SETTING)
const threshold = this.options.isCombat const threshold = this.options.isCombat
? (this.options.difficultyValue ?? 0) ? (this.options.difficultyValue ?? 0)
: 11 : defaultThreshold
const margin = this.options.margin const margin = this.options.margin
const woundMalus = this.options.woundMalus ?? 0 const woundMalus = this.options.woundMalus ?? 0
const armorMalus = this.options.armorMalus ?? 0 const armorMalus = this.options.armorMalus ?? 0
@@ -565,12 +568,12 @@ export class CelestopolRoll extends Roll {
}) })
const actorType = rollingActor?.type ?? this.options.actorType ?? 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 : N"
const difficultyLabel = this.options.isCombat const difficultyLabel = this.options.isCombat
? `${game.i18n.localize("CELESTOPOL.Combat.corpsPnj")} : ${threshold}` ? `${game.i18n.localize("CELESTOPOL.Combat.corpsPnj")} : ${threshold}`
: isOpposition : isOpposition
? `${game.i18n.localize("CELESTOPOL.Roll.oppositionVs")}` ? `${game.i18n.localize("CELESTOPOL.Roll.oppositionVs")}`
: `${game.i18n.localize("CELESTOPOL.Roll.threshold")} : 11` : `${game.i18n.localize("CELESTOPOL.Roll.threshold")} : ${threshold}`
return { return {
cssClass: [SYSTEM.id, "dice-roll"].join(" "), cssClass: [SYSTEM.id, "dice-roll"].join(" "),
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000084 MANIFEST-000110
+7 -11
View File
@@ -1,11 +1,7 @@
2026/04/26-21:30:37.725370 7f57a5fef6c0 Delete type=3 #1 2026/05/29-19:25:48.566717 7f386cbff6c0 Recovering log #107
2026/04/26-22:44:03.500717 7f57977fe6c0 Level-0 table #87: started 2026/05/29-19:25:48.575874 7f386cbff6c0 Delete type=3 #105
2026/04/26-22:44:03.500753 7f57977fe6c0 Level-0 table #87: 0 bytes OK 2026/05/29-19:25:48.575904 7f386cbff6c0 Delete type=0 #107
2026/04/26-22:44:03.506825 7f57977fe6c0 Delete type=0 #85 2026/05/29-19:26:15.982905 7f381e7fc6c0 Level-0 table #113: started
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/05/29-19:26:15.982917 7f381e7fc6c0 Level-0 table #113: 0 bytes OK
2026/04/26-22:44:03.534983 7f57977fe6c0 Compacting 1@0 + 0@1 files 2026/05/29-19:26:15.988613 7f381e7fc6c0 Delete type=0 #111
2026/04/26-22:44:03.538403 7f57977fe6c0 Generated table #88@0: 6 keys, 5441 bytes 2026/05/29-19:26:15.998513 7f381e7fc6c0 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.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)
+11 -4
View File
@@ -1,4 +1,11 @@
2026/04/26-21:30:37.706976 7f57a5fef6c0 Log #82: 0 ops saved to Table #83 OK 2026/05/29-18:25:23.135570 7f381f7fe6c0 Delete type=3 #1
2026/04/26-21:30:37.707127 7f57a5fef6c0 Archiving /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/aides-de-jeu/000082.log: OK 2026/05/29-18:27:57.110280 7f381e7fc6c0 Level-0 table #108: started
2026/04/26-21:30:37.707559 7f57a5fef6c0 Table #5: 6 entries OK 2026/05/29-18:27:57.110317 7f381e7fc6c0 Level-0 table #108: 0 bytes OK
2026/04/26-21:30:37.711062 7f57a5fef6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/aides-de-jeu; recovered 1 files; 5441 bytes. Some data may have been lost. **** 2026/05/29-18:27:57.146936 7f381e7fc6c0 Delete type=0 #106
2026/05/29-18:27:57.291474 7f381e7fc6c0 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/05/29-18:27:57.291484 7f381e7fc6c0 Compacting 1@0 + 0@1 files
2026/05/29-18:27:57.308314 7f381e7fc6c0 Generated table #109@0: 6 keys, 5441 bytes
2026/05/29-18:27:57.308348 7f381e7fc6c0 Compacted 1@0 + 0@1 files => 5441 bytes
2026/05/29-18:27:57.339343 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/05/29-18:27:57.339668 7f381e7fc6c0 Delete type=2 #88
2026/05/29-18:27:57.450192 7f381e7fc6c0 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-000142 MANIFEST-000173
+14 -12
View File
@@ -1,12 +1,14 @@
2026/04/26-21:30:37.676414 7f57a4fed6c0 Delete type=3 #1 2026/05/29-19:25:48.540511 7f381ffff6c0 Recovering log #170
2026/04/26-22:44:03.490255 7f57977fe6c0 Level-0 table #145: started 2026/05/29-19:25:48.551076 7f381ffff6c0 Delete type=3 #168
2026/04/26-22:44:03.493705 7f57977fe6c0 Level-0 table #145: 3524 bytes OK 2026/05/29-19:25:48.551131 7f381ffff6c0 Delete type=0 #170
2026/04/26-22:44:03.500560 7f57977fe6c0 Delete type=0 #143 2026/05/29-19:26:15.960995 7f381e7fc6c0 Level-0 table #176: started
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/05/29-19:26:15.964212 7f381e7fc6c0 Level-0 table #176: 3524 bytes OK
2026/04/26-22:44:03.524743 7f57977fe6c0 Compacting 2@0 + 0@1 files 2026/05/29-19:26:15.970133 7f381e7fc6c0 Delete type=0 #174
2026/04/26-22:44:03.528390 7f57977fe6c0 Generated table #146@0: 9 keys, 6617 bytes 2026/05/29-19:26:15.988655 7f381e7fc6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 145 : 1
2026/04/26-22:44:03.528448 7f57977fe6c0 Compacted 2@0 + 0@1 files => 6617 bytes 2026/05/29-19:26:15.988659 7f381e7fc6c0 Compacting 1@0 + 1@1 files
2026/04/26-22:44:03.534535 7f57977fe6c0 compacted to: files[ 0 1 0 0 0 0 0 ] 2026/05/29-19:26:15.991895 7f381e7fc6c0 Generated table #177@0: 9 keys, 6617 bytes
2026/04/26-22:44:03.534696 7f57977fe6c0 Delete type=2 #140 2026/05/29-19:26:15.991901 7f381e7fc6c0 Compacted 1@0 + 1@1 files => 6617 bytes
2026/04/26-22:44:03.534864 7f57977fe6c0 Delete type=2 #145 2026/05/29-19:26:15.998180 7f381e7fc6c0 compacted to: files[ 0 1 0 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/05/29-19:26:15.998402 7f381e7fc6c0 Delete type=2 #172
2026/05/29-19:26:15.998461 7f381e7fc6c0 Delete type=2 #176
2026/05/29-19:26:16.010680 7f381e7fc6c0 Manual compaction at level-0 from '!items!null' @ 145 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
+12 -4
View File
@@ -1,4 +1,12 @@
2026/04/26-21:30:37.648968 7f57a4fed6c0 Log #138: 0 ops saved to Table #141 OK 2026/05/29-18:25:23.097516 7f381effd6c0 Delete type=3 #1
2026/04/26-21:30:37.649079 7f57a4fed6c0 Archiving /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/anomalies/000138.log: OK 2026/05/29-18:27:57.232279 7f381e7fc6c0 Level-0 table #171: started
2026/04/26-21:30:37.649161 7f57a4fed6c0 Table #140: 9 entries OK 2026/05/29-18:27:57.253183 7f381e7fc6c0 Level-0 table #171: 3524 bytes OK
2026/04/26-21:30:37.652702 7f57a4fed6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/anomalies; recovered 1 files; 6617 bytes. Some data may have been lost. **** 2026/05/29-18:27:57.291326 7f381e7fc6c0 Delete type=0 #169
2026/05/29-18:27:57.404912 7f381e7fc6c0 Manual compaction at level-0 from '!items!anomCommMorts001' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 141 : 1
2026/05/29-18:27:57.404922 7f381e7fc6c0 Compacting 2@0 + 0@1 files
2026/05/29-18:27:57.421172 7f381e7fc6c0 Generated table #172@0: 9 keys, 6617 bytes
2026/05/29-18:27:57.421194 7f381e7fc6c0 Compacted 2@0 + 0@1 files => 6617 bytes
2026/05/29-18:27:57.449840 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/05/29-18:27:57.449959 7f381e7fc6c0 Delete type=2 #166
2026/05/29-18:27:57.450112 7f381e7fc6c0 Delete type=2 #171
2026/05/29-18:27:57.505063 7f381e7fc6c0 Manual compaction at level-0 from '!items!null' @ 141 : 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-000045 MANIFEST-000071
+7 -11
View File
@@ -1,11 +1,7 @@
2026/04/26-21:30:37.703085 7f57a4fed6c0 Delete type=3 #1 2026/05/29-19:25:48.553559 7f386cbff6c0 Recovering log #68
2026/04/26-22:44:03.483917 7f57977fe6c0 Level-0 table #48: started 2026/05/29-19:25:48.563799 7f386cbff6c0 Delete type=3 #66
2026/04/26-22:44:03.483998 7f57977fe6c0 Level-0 table #48: 0 bytes OK 2026/05/29-19:25:48.563837 7f386cbff6c0 Delete type=0 #68
2026/04/26-22:44:03.490106 7f57977fe6c0 Delete type=0 #46 2026/05/29-19:26:15.976984 7f381e7fc6c0 Level-0 table #74: started
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/05/29-19:26:15.976996 7f381e7fc6c0 Level-0 table #74: 0 bytes OK
2026/04/26-22:44:03.513463 7f57977fe6c0 Compacting 1@0 + 0@1 files 2026/05/29-19:26:15.982862 7f381e7fc6c0 Delete type=0 #72
2026/04/26-22:44:03.517217 7f57977fe6c0 Generated table #49@0: 36 keys, 35733 bytes 2026/05/29-19:26:15.998506 7f381e7fc6c0 Manual compaction at level-0 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)
+11 -4
View File
@@ -1,4 +1,11 @@
2026/04/26-21:30:37.679822 7f57a4fed6c0 Log #43: 0 ops saved to Table #44 OK 2026/05/29-18:25:23.116810 7f381ffff6c0 Delete type=3 #1
2026/04/26-21:30:37.679938 7f57a4fed6c0 Archiving /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/pretires/000043.log: OK 2026/05/29-18:27:57.533567 7f381e7fc6c0 Level-0 table #69: started
2026/04/26-21:30:37.680974 7f57a4fed6c0 Table #18: 36 entries OK 2026/05/29-18:27:57.533614 7f381e7fc6c0 Level-0 table #69: 0 bytes OK
2026/04/26-21:30:37.684522 7f57a4fed6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/pretires; recovered 1 files; 35733 bytes. Some data may have been lost. **** 2026/05/29-18:27:57.568380 7f381e7fc6c0 Delete type=0 #67
2026/05/29-18:27:57.662122 7f381e7fc6c0 Manual compaction at level-0 from '!actors!6RZ6IzJUHm4dB5Ut' @ 72057594037927935 : 1 .. '!folders!MbFQgPdF6Gtbj5AU' @ 0 : 0; will stop at '!folders!MbFQgPdF6Gtbj5AU' @ 37 : 1
2026/05/29-18:27:57.662130 7f381e7fc6c0 Compacting 1@0 + 0@1 files
2026/05/29-18:27:57.681906 7f381e7fc6c0 Generated table #70@0: 36 keys, 35733 bytes
2026/05/29-18:27:57.681939 7f381e7fc6c0 Compacted 1@0 + 0@1 files => 35733 bytes
2026/05/29-18:27:57.724776 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/05/29-18:27:57.724885 7f381e7fc6c0 Delete type=2 #49
2026/05/29-18:27:57.817815 7f381e7fc6c0 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.
View File
+1 -1
View File
@@ -1 +1 @@
MANIFEST-000087 MANIFEST-000113
+7 -11
View File
@@ -1,11 +1,7 @@
2026/04/26-21:30:37.754039 7f5797fff6c0 Delete type=3 #1 2026/05/29-19:25:48.578477 7f381f7fe6c0 Recovering log #110
2026/04/26-22:44:03.507044 7f57977fe6c0 Level-0 table #90: started 2026/05/29-19:25:48.589121 7f381f7fe6c0 Delete type=3 #108
2026/04/26-22:44:03.507095 7f57977fe6c0 Level-0 table #90: 0 bytes OK 2026/05/29-19:25:48.589160 7f381f7fe6c0 Delete type=0 #110
2026/04/26-22:44:03.513200 7f57977fe6c0 Delete type=0 #88 2026/05/29-19:26:15.970220 7f381e7fc6c0 Level-0 table #116: started
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/05/29-19:26:15.970241 7f381e7fc6c0 Level-0 table #116: 0 bytes OK
2026/04/26-22:44:03.545342 7f57977fe6c0 Compacting 1@0 + 0@1 files 2026/05/29-19:26:15.976948 7f381e7fc6c0 Delete type=0 #114
2026/04/26-22:44:03.549127 7f57977fe6c0 Generated table #91@0: 4 keys, 1746 bytes 2026/05/29-19:26:15.998499 7f381e7fc6c0 Manual compaction at level-0 from '!scenes!0iGCRqkdJKjmmbl4' @ 72057594037927935 : 1 .. '!scenes.levels!X3XJg7raEXtOFOtj.defaultLevel0000' @ 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)
+11 -4
View File
@@ -1,4 +1,11 @@
2026/04/26-21:30:37.729984 7f5797fff6c0 Log #83: 0 ops saved to Table #86 OK 2026/05/29-18:25:23.154144 7f381ffff6c0 Delete type=3 #1
2026/04/26-21:30:37.730117 7f5797fff6c0 Archiving /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/scenes/000083.log: OK 2026/05/29-18:27:57.197941 7f381e7fc6c0 Level-0 table #111: started
2026/04/26-21:30:37.730175 7f5797fff6c0 Table #85: 4 entries OK 2026/05/29-18:27:57.197975 7f381e7fc6c0 Level-0 table #111: 0 bytes OK
2026/04/26-21:30:37.733573 7f5797fff6c0 **** Repaired leveldb /home/morr/foundry/foundrydata-dev/Data/systems/fvtt-celestopol/packs-system/scenes; recovered 1 files; 1746 bytes. Some data may have been lost. **** 2026/05/29-18:27:57.232075 7f381e7fc6c0 Delete type=0 #109
2026/05/29-18:27:57.339840 7f381e7fc6c0 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/05/29-18:27:57.339849 7f381e7fc6c0 Compacting 1@0 + 0@1 files
2026/05/29-18:27:57.358860 7f381e7fc6c0 Generated table #112@0: 4 keys, 1746 bytes
2026/05/29-18:27:57.358888 7f381e7fc6c0 Compacted 1@0 + 0@1 files => 1746 bytes
2026/05/29-18:27:57.404742 7f381e7fc6c0 compacted to: files[ 0 1 0 0 0 0 0 ]
2026/05/29-18:27:57.404821 7f381e7fc6c0 Delete type=2 #91
2026/05/29-18:27:57.505039 7f381e7fc6c0 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.1576em; 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: 1.1025em; 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.1576em; 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: 1.1025em; 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.2128em; 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: 1.1025em; 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.1246em; 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.9923em; 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.1576em; 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.1576em; 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.2128em; 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.2128em; 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.86em; 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.9923em; 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.9371em; 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: 1.1025em; 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.7938em; 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;
} }
+8 -8
View File
@@ -85,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.5435em; font-size: 1.5em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.06em; letter-spacing: 0.06em;
padding: 2px 4px; padding: 2px 4px;
@@ -94,7 +94,7 @@
.actor-name { .actor-name {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.5435em; font-size: 1.5em;
color: var(--cel-orange); color: var(--cel-orange);
letter-spacing: 0.06em; letter-spacing: 0.06em;
margin: 0; margin: 0;
@@ -120,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);
@@ -131,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);
@@ -173,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.5435em; 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;
@@ -242,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.9371em; font-size: 0.9em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
cursor: pointer; cursor: pointer;
@@ -331,7 +331,7 @@
.wound-value { .wound-value {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.0474em; 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.86em; 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.323em; 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.86em; 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.8269em; 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.9371em; } 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.764em; 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.9845em; 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.86em; 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.882em; 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.2128em; 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.323em; 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.5435em; 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.9923em; 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.9923em; 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: 1.0474em; 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.2128em; 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);
} }
+104 -99
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.9041em; 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.4443em; 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.86em; 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.9625em; 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.82em; 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.77em; 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.68em; font-size: 0.7em;
color: white; color: white;
} }
} }
} }
.moon-icon { font-size: 1.26em; 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: 1.0143em; 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.82em; 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,7 +165,7 @@
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.89em; font-size: 0.9em;
color: var(--cel-text, #2f2413); 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.68em; font-size: 0.7em;
color: white; color: white;
} }
} }
@@ -242,7 +242,7 @@
} }
.destin-icon { .destin-icon {
font-size: 1.16em; 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: 1.0474em; 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.76em; 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.79em; 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);
@@ -326,7 +326,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.79em; font-size: 0.8em;
color: white; color: white;
} }
} }
@@ -338,19 +338,19 @@
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: 1.0474em; 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.73em; font-size: 0.7em;
color: rgba(0,0,0,0.45); color: rgba(0,0,0,0.45);
font-style: italic; font-style: italic;
} }
} }
.puiser-cost { .puiser-cost {
font-size: 0.84em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
color: var(--cel-accent, #6b1e28); color: var(--cel-accent, #6b1e28);
background: rgba(107,30,40,0.1); background: rgba(107,30,40,0.1);
@@ -398,14 +398,14 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.63em; font-size: 0.6em;
color: white; color: white;
} }
} }
} }
.fortune-icon { .fortune-icon {
font-size: 1.16em; font-size: 1.2em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -414,19 +414,19 @@
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: 1.0474em; 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.76em; font-size: 0.8em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
font-style: italic; font-style: italic;
} }
} }
.fortune-badge { .fortune-badge {
font-size: 0.84em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
background: rgba(12,76,12,0.12); background: rgba(12,76,12,0.12);
@@ -450,7 +450,7 @@
gap: 10px; gap: 10px;
.preview-label { .preview-label {
font-size: 0.73em; font-size: 0.7em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
@@ -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.8522em; 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;
@@ -481,7 +481,7 @@
.moon-effect-label { .moon-effect-label {
display: block; display: block;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.8379em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
text-transform: uppercase; text-transform: uppercase;
@@ -498,7 +498,7 @@
.moon-effect-btn { .moon-effect-btn {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 0.9041em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
padding: 4px 11px; padding: 4px 11px;
border-radius: 4px; border-radius: 4px;
@@ -523,7 +523,7 @@
} }
.moon-effect-narrative { .moon-effect-narrative {
font-size: 0.76em; font-size: 0.8em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
font-style: italic; font-style: italic;
align-self: center; align-self: center;
@@ -535,7 +535,7 @@
align-items: center; align-items: center;
gap: 4px; gap: 4px;
margin-top: 6px; margin-top: 6px;
font-size: 0.882em; font-size: 0.9em;
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-style: italic; font-style: italic;
padding: 3px 9px; padding: 3px 9px;
@@ -590,16 +590,16 @@
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: 1.0694em; font-size: 1.1em;
} }
.skill-info { .skill-info {
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
font-size: 0.81em; 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; }
} }
.wound-info { font-size: 0.73em; color: #f0a0a0; } .wound-info { font-size: 0.7em; color: #f0a0a0; }
} }
.moon-badge { display: none; } .moon-badge { display: none; }
@@ -624,7 +624,7 @@
border-radius: 4px; border-radius: 4px;
background: white; background: white;
font-weight: bold; font-weight: bold;
font-size: 1.2128em; 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: var(--cel-text, #2f2413); color: var(--cel-text, #2f2413);
@@ -653,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.87em; font-size: 0.9em;
color: #555; color: #555;
.fl-label { color: rgba(0,0,0,0.4); font-size: 0.92em; 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: var(--cel-text, #2f2413); } .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.742em; 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;
@@ -684,14 +684,14 @@
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.86em; 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: rgba(0,0,0,0.35); text-transform: uppercase; font-size: 0.84em; } .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: rgba(0,0,0,0.45); } .diff-val { color: rgba(0,0,0,0.45); }
@@ -699,7 +699,7 @@
padding: 2px 10px; padding: 2px 10px;
border-radius: 12px; border-radius: 12px;
font-weight: bold; font-weight: bold;
font-size: 1.2128em; 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;
@@ -719,7 +719,7 @@
// ── Destin utilisé ── // ── Destin utilisé ──
.used-info { .used-info {
text-align: center; text-align: center;
font-size: 0.81em; 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);
@@ -757,7 +757,7 @@
} }
.damage-header { .damage-header {
font-size: 0.76em; 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);
@@ -774,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: 2.194em; 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.86em; font-size: 0.9em;
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
font-weight: bold; font-weight: bold;
} }
@@ -814,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.82em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
cursor: pointer; cursor: pointer;
@@ -858,7 +858,7 @@
background: rgba(12,76,12,0.1); background: rgba(12,76,12,0.1);
color: var(--cel-green, #0c4c0c); color: var(--cel-green, #0c4c0c);
font-weight: bold; font-weight: bold;
font-size: 0.95em; font-size: 0.9em;
} }
// ── Résultat dé de lune ── // ── Résultat dé de lune ──
@@ -871,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.89em; font-size: 1.9em;
line-height: 1; line-height: 1;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -884,7 +884,7 @@
} }
.moon-die-phase { .moon-die-phase {
font-size: 0.76em; font-size: 0.8em;
opacity: 0.75; opacity: 0.75;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
@@ -892,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: 1.1025em; 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.76em; font-size: 0.8em;
font-style: italic; font-style: italic;
opacity: 0.85; opacity: 0.85;
line-height: 1.3; line-height: 1.3;
@@ -936,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.89em; font-size: 0.9em;
opacity: 0.85; opacity: 0.85;
letter-spacing: 0.15em; letter-spacing: 0.15em;
} }
.result-label { font-size: 1.26em; line-height: 1.2; } .result-label { font-size: 1.3em; line-height: 1.2; }
.result-desc { .result-desc {
font-size: 0.68em; font-size: 0.7em;
letter-spacing: 0.08em; letter-spacing: 0.08em;
margin-top: 2px; margin-top: 2px;
opacity: 0.8; opacity: 0.8;
@@ -1010,7 +1010,7 @@
.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: 1.1356em; font-size: 1.1em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
} }
@@ -1018,7 +1018,7 @@
.welcome-body { .welcome-body {
padding: 9px 11px 10px; padding: 9px 11px 10px;
color: var(--cel-text, #2f2413); color: var(--cel-text, #2f2413);
font-size: 0.88em; font-size: 0.9em;
line-height: 1.45; line-height: 1.45;
p { p {
@@ -1038,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.76em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
@@ -1088,7 +1088,7 @@
.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: 1.1356em; font-size: 1.1em;
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
} }
@@ -1101,7 +1101,7 @@
.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.88em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
letter-spacing: 0.04em; letter-spacing: 0.04em;
text-transform: uppercase; text-transform: uppercase;
@@ -1208,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: 1.0143em; font-size: 1em;
} }
.faction-aspect-points { .faction-aspect-points {
@@ -1216,7 +1216,7 @@
flex-wrap: wrap; flex-wrap: wrap;
gap: 5px; gap: 5px;
margin-bottom: 4px; margin-bottom: 4px;
font-size: 0.84em; font-size: 0.8em;
} }
.faction-aspect-point-card { .faction-aspect-point-card {
@@ -1230,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.76em; 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);
@@ -1239,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.2128em; 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.82em; font-size: 0.8em;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
} }
@@ -1256,7 +1256,7 @@
border-radius: 4px; border-radius: 4px;
background: rgba(184, 74, 46, 0.08); background: rgba(184, 74, 46, 0.08);
color: var(--cel-accent, #6b1e28); color: var(--cel-accent, #6b1e28);
font-size: 0.84em; font-size: 0.8em;
} }
.faction-aspect-tag-list, .faction-aspect-tag-list,
@@ -1274,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.76em; font-size: 0.8em;
font-weight: bold; font-weight: bold;
} }
@@ -1288,7 +1288,7 @@
label { label {
display: block; display: block;
margin-bottom: 2px; margin-bottom: 2px;
font-size: 0.71em; 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);
@@ -1303,7 +1303,7 @@
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.82em; font-size: 0.8em;
color: var(--cel-text, #2f2413); color: var(--cel-text, #2f2413);
box-sizing: border-box; box-sizing: border-box;
} }
@@ -1335,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.8379em; font-size: 0.8em;
line-height: 1; line-height: 1;
cursor: help; cursor: help;
vertical-align: middle; vertical-align: middle;
@@ -1357,7 +1357,11 @@
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.9482em; font-size: 0.9em;
}
label {
color: var(--cel-border, #7a5c20);
} }
} }
@@ -1365,7 +1369,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
font-size: 0.78em; font-size: 0.8em;
color: var(--cel-border, #7a5c20);
} }
.faction-aspect-active-list { .faction-aspect-active-list {
@@ -1398,13 +1403,13 @@
.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: 1.0694em; font-size: 1.1em;
} }
.faction-aspect-empty { .faction-aspect-empty {
color: rgba(0,0,0,0.5); color: rgba(0,0,0,0.5);
font-style: italic; font-style: italic;
font-size: 0.78em; font-size: 0.8em;
} }
.faction-aspect-remove-block { .faction-aspect-remove-block {
@@ -1433,7 +1438,7 @@
border-left: 3px solid #c0392b; border-left: 3px solid #c0392b;
border-radius: 4px; border-radius: 4px;
color: #f0c0c0; color: #f0c0c0;
font-size: 0.89em; font-size: 0.9em;
.wound-icon { font-size: 1em; } .wound-icon { font-size: 1em; }
} }
} }
@@ -1453,9 +1458,9 @@
align-items: center; align-items: center;
gap: 0.3em; gap: 0.3em;
margin-bottom: 1px; margin-bottom: 1px;
font-size: 0.89em; font-size: 0.9em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
.weapon-icon-small { font-size: 0.95em; } .weapon-icon-small { font-size: 0.9em; }
.weapon-degats-small { .weapon-degats-small {
font-weight: bold; font-weight: bold;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
@@ -1470,20 +1475,20 @@
align-items: center; align-items: center;
gap: 0.4em; gap: 0.4em;
margin-bottom: 2px; margin-bottom: 2px;
font-size: 0.95em; font-size: 0.9em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
.weapon-icon { font-size: 1em; } .weapon-icon { font-size: 1em; }
.weapon-degats { .weapon-degats {
font-weight: bold; font-weight: bold;
color: var(--cel-border, #7a5c20); color: var(--cel-border, #7a5c20);
font-size: 0.89em; font-size: 0.9em;
} }
} }
.form-corps-pnj { .form-corps-pnj {
.corps-pnj-input { .corps-pnj-input {
width: 70px; width: 70px;
font-size: 1.2789em; 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);
@@ -1504,7 +1509,7 @@
label { label {
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-weight: bold; font-weight: bold;
font-size: 0.89em; font-size: 0.9em;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
@@ -1519,7 +1524,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.89em; font-size: 0.9em;
max-width: 200px; max-width: 200px;
} }
} }
@@ -1535,7 +1540,7 @@
align-items: center; align-items: center;
gap: 6px; gap: 6px;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
font-size: 0.92em; font-size: 0.9em;
font-style: italic; font-style: italic;
i { opacity: 0.8; } i { opacity: 0.8; }
@@ -1550,7 +1555,7 @@
label { label {
color: var(--cel-accent, #6b1e28); color: var(--cel-accent, #6b1e28);
font-size: 0.89em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -1566,13 +1571,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.89em; font-size: 0.9em;
} }
} }
.form-threshold-fixed { .form-threshold-fixed {
.threshold-value { .threshold-value {
font-size: 1.3892em; 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);
@@ -1598,7 +1603,7 @@
input[type="checkbox"] { flex-shrink: 0; } input[type="checkbox"] { flex-shrink: 0; }
.opposition-icon { .opposition-icon {
font-size: 1.26em; font-size: 1.3em;
color: var(--cel-orange, #e07b00); color: var(--cel-orange, #e07b00);
} }
@@ -1609,13 +1614,13 @@
.opposition-main { .opposition-main {
font-weight: bold; font-weight: bold;
font-size: 1.0474em; 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.79em; font-size: 0.8em;
color: #8a7060; color: #8a7060;
font-style: italic; font-style: italic;
} }
@@ -1651,7 +1656,7 @@
.moon-standalone-title { .moon-standalone-title {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.1025em; 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;
@@ -1659,7 +1664,7 @@
} }
.moon-standalone-actor { .moon-standalone-actor {
font-size: 0.89em; font-size: 0.9em;
color: var(--cel-text, #333); color: var(--cel-text, #333);
font-style: italic; font-style: italic;
} }
@@ -1688,13 +1693,13 @@
.moon-standalone-phase { .moon-standalone-phase {
font-family: var(--cel-font-title); font-family: var(--cel-font-title);
font-size: 1.1025em; font-size: 1.1em;
font-weight: bold; font-weight: bold;
color: var(--cel-text, #333); color: var(--cel-text, #333);
} }
.moon-standalone-value { .moon-standalone-value {
font-size: 0.84em; font-size: 0.8em;
color: var(--cel-text-light, #666); color: var(--cel-text-light, #666);
font-style: italic; font-style: italic;
} }
@@ -1711,7 +1716,7 @@
gap: 8px; gap: 8px;
.moon-interpret-label { .moon-interpret-label {
font-size: 0.76em; font-size: 0.8em;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.07em; letter-spacing: 0.07em;
color: rgba(0,0,0,0.45); color: rgba(0,0,0,0.45);
@@ -1719,7 +1724,7 @@
} }
.moon-fortune { .moon-fortune {
font-size: 0.89em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
border-radius: 3px; border-radius: 3px;
padding: 1px 8px; padding: 1px 8px;
@@ -1783,11 +1788,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: 1.0694em; font-size: 1.1em;
} }
.skill-info { .skill-info {
color: var(--cel-cream, #f0e8d4); color: var(--cel-cream, #f0e8d4);
font-size: 0.81em; font-size: 0.8em;
font-style: italic; font-style: italic;
} }
} }
@@ -1815,19 +1820,19 @@
} }
.initiative-icon { .initiative-icon {
font-size: 1.16em; font-size: 1.2em;
opacity: 0.9; opacity: 0.9;
font-style: normal; font-style: normal;
} }
.initiative-score { .initiative-score {
font-size: 2.52em; font-size: 2.5em;
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
} }
.initiative-detail { .initiative-detail {
font-size: 0.68em; 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);
+3
View File
@@ -7,6 +7,9 @@
<a class="faction-aspect-manage" data-action="manageFactionAspects"> <a class="faction-aspect-manage" data-action="manageFactionAspects">
<i class="fa-solid fa-sliders"></i> {{localize "CELESTOPOL.FactionAspect.manage"}} <i class="fa-solid fa-sliders"></i> {{localize "CELESTOPOL.FactionAspect.manage"}}
</a> </a>
<a class="faction-aspect-reset" data-action="resetFactionAspects">
<i class="fa-solid fa-rotate-left"></i> {{localize "CELESTOPOL.FactionAspect.resetButton"}}
</a>
{{/if}} {{/if}}
</div> </div>
+2 -2
View File
@@ -42,7 +42,7 @@
<div class="roll-form-rows"> <div class="roll-form-rows">
{{!-- Difficulté : Corps PNJ en combat, fixe 11 en test normal --}} {{!-- Difficulté : Corps PNJ en combat, configurable via setting en test normal --}}
{{#if isCombat}} {{#if isCombat}}
{{!-- Sélecteur de cible PNJ (si des tokens NPCs sont disponibles) --}} {{!-- Sélecteur de cible PNJ (si des tokens NPCs sont disponibles) --}}
@@ -81,7 +81,7 @@
{{else}} {{else}}
<div class="form-row-line form-threshold-fixed"> <div class="form-row-line form-threshold-fixed">
<label>{{localize "CELESTOPOL.Roll.threshold"}}</label> <label>{{localize "CELESTOPOL.Roll.threshold"}}</label>
<span class="threshold-value" id="threshold-display">11</span> <span class="threshold-value" id="threshold-display">{{getSetting "defaultRollThreshold"}}</span>
</div> </div>
{{!-- Test en opposition : le résultat sera masqué, MJ décide --}} {{!-- Test en opposition : le résultat sera masqué, MJ décide --}}