Refonte complète : dialogues de jet + messages de chat
- Nouveau layout roll-dialog.hbs : header, grille lune 3×3, sélecteur visibility, ligne Destin avec compteur disponible, preview formule améliorée - Fix JS : data-moon-bonus sur chaque option, formule − si négatif - Fix roll.mjs : passe destActuel au dialog, déduit automatiquement 1 point de Destin (system.destin.lvl++) après chaque jet avec Destin - character.mjs : passe destActuel = 8 - destin.lvl au prompt() - chat-message.hbs : icônes résultat (✦✦/✖✖ pour critiques), label Formule, margin-badge right-aligned vs difficulté left-aligned - roll.less : refonte complète couleurs (#0c4c0c/#e07b00), grille lune, destin row, visibility subtil, bandeau critiques améliorés - lang/fr.json : clés Roll.visibility*, destinAvailable, destinNone, destinBonus, formula Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
12
lang/fr.json
12
lang/fr.json
@@ -122,7 +122,10 @@
|
||||
"margin": "Marge",
|
||||
"above": "au-dessus du seuil",
|
||||
"below": "en dessous du seuil",
|
||||
"destin": "Dépenser 1 Destin (+2 dés)",
|
||||
"destin": "Dépenser 1 Destin",
|
||||
"destinBonus": "+2 dés",
|
||||
"destinAvailable": "disponible(s)",
|
||||
"destinNone": "Aucun Destin disponible",
|
||||
"usedAspect": "Aspect utilisé",
|
||||
"usedDestin": "Destin dépensé",
|
||||
"criticalSuccessDesc": "Marge ≥ 5 — résultat exceptionnel !",
|
||||
@@ -130,7 +133,12 @@
|
||||
"woundLevel": "Niveau de blessures",
|
||||
"diceBreakdown": "Détail du jet",
|
||||
"threshold": "Seuil",
|
||||
"nbDiceBase": "Dés de base"
|
||||
"nbDiceBase": "Dés de base",
|
||||
"formula": "Formule",
|
||||
"visibility": "Visibilité",
|
||||
"visibilityPublic": "Public",
|
||||
"visibilityGM": "MJ uniquement",
|
||||
"visibilitySelf": "Secret (moi)"
|
||||
},
|
||||
"Moon": {
|
||||
"none": "Aucune phase",
|
||||
|
||||
@@ -69,6 +69,7 @@ export class CelestopolRoll extends Roll {
|
||||
moonPhaseChoices,
|
||||
defaultDifficulty: options.difficulty ?? "normal",
|
||||
defaultMoonPhase: options.moonPhase ?? "none",
|
||||
destActuel: options.destActuel ?? null,
|
||||
}
|
||||
|
||||
const content = await foundry.applications.handlebars.renderTemplate(
|
||||
@@ -142,8 +143,18 @@ export class CelestopolRoll extends Roll {
|
||||
roll.computeResult()
|
||||
await roll.toMessage({}, { rollMode: rollData.rollMode })
|
||||
|
||||
// Mémoriser les préférences sur l'acteur
|
||||
// Déduire automatiquement 1 point de Destin si utilisé
|
||||
const actor = game.actors.get(options.actorId)
|
||||
if (useDestin && actor && (options.destActuel ?? 1) > 0) {
|
||||
const currentLvl = actor.system.destin?.lvl ?? 0
|
||||
const newLvl = Math.min(8, currentLvl + 1)
|
||||
await actor.update({
|
||||
"system.destin.lvl": newLvl,
|
||||
[`system.destin.d${newLvl}.checked`]: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Mémoriser les préférences sur l'acteur
|
||||
if (actor) {
|
||||
await actor.update({
|
||||
"system.prefs.moonPhase": moonPhase,
|
||||
|
||||
@@ -177,18 +177,19 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
|
||||
if (!skill) return null
|
||||
|
||||
return CelestopolRoll.prompt({
|
||||
actorId: this.parent.id,
|
||||
actorName: this.parent.name,
|
||||
actorImage: this.parent.img,
|
||||
actorId: this.parent.id,
|
||||
actorName: this.parent.name,
|
||||
actorImage: this.parent.img,
|
||||
statId,
|
||||
skillId,
|
||||
statLabel: SYSTEM.STATS[statId]?.label,
|
||||
skillLabel: skill.label,
|
||||
skillValue: skill.value,
|
||||
woundMalus: this.getWoundMalus(),
|
||||
woundLevel: this.blessures.lvl,
|
||||
moonPhase: this.prefs.moonPhase,
|
||||
difficulty: this.prefs.difficulty,
|
||||
statLabel: SYSTEM.STATS[statId]?.label,
|
||||
skillLabel: skill.label,
|
||||
skillValue: skill.value,
|
||||
woundMalus: this.getWoundMalus(),
|
||||
woundLevel: this.blessures.lvl,
|
||||
moonPhase: this.prefs.moonPhase,
|
||||
difficulty: this.prefs.difficulty,
|
||||
destActuel: Math.max(0, 8 - (this.destin.lvl ?? 0)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
427
styles/roll.less
427
styles/roll.less
@@ -1,8 +1,5 @@
|
||||
// ─── Roll dialog ─────────────────────────────────────────────────────────────
|
||||
|
||||
// DialogV2 sets roll-dialog class on the .application element, not on the form.
|
||||
// All dialog content lives in .application.roll-dialog .dialog-content
|
||||
|
||||
.application.roll-dialog .window-content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
@@ -13,94 +10,97 @@
|
||||
}
|
||||
|
||||
.application.roll-dialog .roll-dialog-content {
|
||||
padding: 10px 14px;
|
||||
padding: 10px 14px 14px;
|
||||
font-family: var(--cel-font-body, "Palatino Linotype", serif);
|
||||
min-width: 340px;
|
||||
min-width: 360px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
|
||||
// ── Bloc infos acteur ──
|
||||
// ── Bloc info acteur ──
|
||||
.roll-info-block {
|
||||
background: var(--cel-green, #1b3828);
|
||||
background: var(--cel-green, #0c4c0c);
|
||||
background-image: url("../assets/ui/fond_cadrille.jpg");
|
||||
background-blend-mode: soft-light;
|
||||
border-bottom: 2px solid var(--cel-orange, #c49a1a);
|
||||
border-bottom: 2px solid var(--cel-orange, #e07b00);
|
||||
padding: 10px 14px 12px;
|
||||
margin: -10px -14px 14px;
|
||||
margin: -10px -14px 12px;
|
||||
text-align: center;
|
||||
|
||||
.roll-actor {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
color: var(--cel-orange-light, #ddb84a);
|
||||
font-size: 0.82em;
|
||||
letter-spacing: 0.06em;
|
||||
opacity: 0.85;
|
||||
font-size: 0.78em;
|
||||
letter-spacing: 0.07em;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.roll-skill-line {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
font-size: 1.2em;
|
||||
font-size: 1.25em;
|
||||
color: var(--cel-cream, #f0e8d4);
|
||||
margin-top: 1px;
|
||||
margin-top: 2px;
|
||||
|
||||
.stat-label { color: var(--cel-orange-light, #ddb84a); }
|
||||
.sep { color: var(--cel-border, #7a5c20); margin: 0 4px; }
|
||||
.sep { color: rgba(196,154,26,0.45); margin: 0 5px; }
|
||||
}
|
||||
|
||||
.roll-dice-summary {
|
||||
margin-top: 8px;
|
||||
padding: 5px 10px;
|
||||
background: rgba(0,0,0,0.25);
|
||||
padding: 5px 12px;
|
||||
background: rgba(0,0,0,0.28);
|
||||
border-radius: 4px;
|
||||
|
||||
.dice-breakdown {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
font-size: 0.85em;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
font-size: 0.82em;
|
||||
color: var(--cel-cream, #f0e8d4);
|
||||
|
||||
.dval, .nb-dice {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
font-size: 1.6em;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
font-size: 1.7em;
|
||||
color: var(--cel-orange, #e07b00);
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.dlabel { font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.8; }
|
||||
.dminus { color: #e8a0a0; font-weight: bold; }
|
||||
.deq { opacity: 0.6; }
|
||||
.ddice { font-size: 1em; color: var(--cel-orange, #c49a1a); }
|
||||
.dlabel { font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; }
|
||||
.dminus { color: #f0a0a0; font-weight: bold; }
|
||||
.deq { opacity: 0.55; }
|
||||
.ddice { color: var(--cel-orange, #e07b00); }
|
||||
}
|
||||
|
||||
.wound-info {
|
||||
font-size: 0.75em;
|
||||
color: #e8a0a0;
|
||||
font-size: 0.73em;
|
||||
color: #f0a0a0;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Phases de lune ──
|
||||
// ── Phases de lune : grille 3 colonnes ──
|
||||
.moon-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
margin-bottom: 10px;
|
||||
gap: 5px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.moon-section-label {
|
||||
font-size: 0.75em;
|
||||
font-size: 0.72em;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
letter-spacing: 0.07em;
|
||||
color: var(--cel-orange, #e07b00);
|
||||
border-bottom: 1px solid rgba(122,92,32,0.3);
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
.moon-phases {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 4px;
|
||||
|
||||
.moon-option {
|
||||
@@ -108,106 +108,204 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
padding: 4px 5px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid transparent;
|
||||
flex: 1;
|
||||
min-width: 52px;
|
||||
padding: 5px 4px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(122,92,32,0.25);
|
||||
transition: all 0.15s;
|
||||
background: rgba(255,255,255,0.4);
|
||||
|
||||
&:hover {
|
||||
background: rgba(196,154,26,0.12);
|
||||
border-color: var(--cel-border, #7a5c20);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: rgba(27,56,40,0.15);
|
||||
border-color: var(--cel-orange, #c49a1a);
|
||||
background: linear-gradient(160deg, #f5ecd4, #e8d8a0);
|
||||
border: 2px solid var(--cel-orange, #e07b00);
|
||||
box-shadow: inset 0 0 6px rgba(196,154,26,0.3);
|
||||
}
|
||||
|
||||
.moon-symbol { font-size: 1.4em; line-height: 1; }
|
||||
.moon-name { font-size: 0.6em; text-align: center; margin-top: 2px; color: #555; }
|
||||
.moon-bonus { font-size: 0.7em; color: var(--cel-orange, #c49a1a); font-weight: bold; }
|
||||
.moon-symbol { font-size: 1.5em; line-height: 1; }
|
||||
.moon-name { font-size: 0.58em; text-align: center; margin-top: 2px; color: #444; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
|
||||
.moon-bonus { font-size: 0.68em; color: var(--cel-orange, #e07b00); font-weight: bold; margin-top: 1px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Champs de formulaire ──
|
||||
.form-group {
|
||||
// ── Lignes de formulaire ──
|
||||
.roll-form-rows {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 7px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.form-row-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
label {
|
||||
flex: 0 0 130px;
|
||||
font-size: 0.82em;
|
||||
flex: 0 0 110px;
|
||||
font-size: 0.78em;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
color: var(--cel-border, #7a5c20);
|
||||
}
|
||||
|
||||
select, input[type="number"] {
|
||||
flex: 1;
|
||||
border: 1px solid var(--cel-border, #7a5c20);
|
||||
border-radius: 2px;
|
||||
padding: 3px 6px;
|
||||
background: rgba(255,255,255,0.75);
|
||||
border: 1px solid rgba(122,92,32,0.5);
|
||||
border-radius: 3px;
|
||||
padding: 3px 7px;
|
||||
background: rgba(255,255,255,0.85);
|
||||
font-family: inherit;
|
||||
}
|
||||
font-size: 0.85em;
|
||||
color: #333;
|
||||
|
||||
&.form-row label { flex: 0 0 130px; }
|
||||
&:focus { outline: 1px solid var(--cel-orange, #e07b00); }
|
||||
}
|
||||
}
|
||||
|
||||
.form-two-col {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.form-group {
|
||||
.form-row-line {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
margin-bottom: 0;
|
||||
gap: 2px;
|
||||
|
||||
label {
|
||||
flex: none;
|
||||
margin-bottom: 2px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
input { width: 100%; box-sizing: border-box; }
|
||||
}
|
||||
}
|
||||
|
||||
// ── Ligne Destin ──
|
||||
.form-destin-row {
|
||||
border: 1px solid var(--cel-orange, #e07b00);
|
||||
border-radius: 4px;
|
||||
background: rgba(196,154,26,0.08);
|
||||
padding: 7px 10px;
|
||||
|
||||
&.destin-disabled {
|
||||
border-color: rgba(122,92,32,0.3);
|
||||
background: rgba(0,0,0,0.04);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.destin-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
|
||||
input[type="checkbox"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
border: 2px solid var(--cel-border, #7a5c20);
|
||||
border-radius: 2px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
&:checked {
|
||||
background: var(--cel-orange, #e07b00);
|
||||
border-color: var(--cel-orange, #e07b00);
|
||||
&::after {
|
||||
content: "✦";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.65em;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
}
|
||||
|
||||
.destin-icon {
|
||||
font-size: 1.1em;
|
||||
color: var(--cel-orange, #e07b00);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.destin-text {
|
||||
flex: 1;
|
||||
|
||||
.destin-main {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
font-size: 0.9em;
|
||||
color: var(--cel-green, #0c4c0c);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.destin-bonus {
|
||||
font-size: 0.72em;
|
||||
color: var(--cel-border, #7a5c20);
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.destin-count {
|
||||
font-size: 0.75em;
|
||||
font-weight: bold;
|
||||
color: var(--cel-green, #0c4c0c);
|
||||
background: rgba(196,154,26,0.2);
|
||||
border: 1px solid rgba(196,154,26,0.4);
|
||||
border-radius: 10px;
|
||||
padding: 1px 8px;
|
||||
white-space: nowrap;
|
||||
|
||||
&.no-destin {
|
||||
color: #888;
|
||||
background: rgba(0,0,0,0.05);
|
||||
border-color: rgba(0,0,0,0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-destin {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.destin-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
cursor: pointer;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
font-size: 0.85em;
|
||||
white-space: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
input[type="checkbox"] { width: 14px; height: 14px; flex-shrink: 0; }
|
||||
.destin-icon { font-size: 1em; flex-shrink: 0; }
|
||||
}
|
||||
}
|
||||
.form-visibility label { color: #888; }
|
||||
|
||||
// ── Prévisualisation ──
|
||||
.dice-preview {
|
||||
text-align: center;
|
||||
margin-top: 4px;
|
||||
padding: 8px;
|
||||
background: rgba(27,56,40,0.08);
|
||||
border-radius: 3px;
|
||||
border: 1px solid var(--cel-green, #1b3828);
|
||||
padding: 10px 8px;
|
||||
background: linear-gradient(160deg, rgba(12,76,12,0.06), rgba(12,76,12,0.12));
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(12,76,12,0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
|
||||
.preview-label {
|
||||
font-size: 0.7em;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.07em;
|
||||
color: var(--cel-border, #7a5c20);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.preview-formula {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
font-size: 1.4em;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
font-size: 1.6em;
|
||||
color: var(--cel-orange, #e07b00);
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,19 +323,18 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background-color: var(--cel-green, #1b3828);
|
||||
background-color: var(--cel-green, #0c4c0c);
|
||||
background-image: url("../assets/ui/fond_cadrille.jpg");
|
||||
background-blend-mode: soft-light;
|
||||
padding: 6px 8px;
|
||||
border-bottom: 2px solid var(--cel-orange, #c49a1a);
|
||||
border-bottom: 2px solid var(--cel-orange, #e07b00);
|
||||
|
||||
.actor-img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: cover;
|
||||
border: 1px solid var(--cel-orange, #c49a1a);
|
||||
border: 1px solid var(--cel-orange, #e07b00);
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 0 4px rgba(196,154,26,0.3);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -249,31 +346,28 @@
|
||||
|
||||
.actor-name {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
color: var(--cel-orange, #e07b00);
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 0.95em;
|
||||
font-size: 0.92em;
|
||||
}
|
||||
.skill-info {
|
||||
color: var(--cel-cream, #f0e8d4);
|
||||
font-size: 0.78em;
|
||||
font-size: 0.77em;
|
||||
font-style: italic;
|
||||
.stat-lbl { color: var(--cel-orange-light, #ddb84a); }
|
||||
.sep { margin: 0 2px; color: var(--cel-border, #7a5c20); }
|
||||
}
|
||||
.wound-info {
|
||||
font-size: 0.72em;
|
||||
color: #e8a0a0;
|
||||
.sep { margin: 0 2px; opacity: 0.5; }
|
||||
}
|
||||
.wound-info { font-size: 0.7em; color: #f0a0a0; }
|
||||
}
|
||||
|
||||
.moon-badge {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 0.75em;
|
||||
.moon-sym { font-size: 1.3em; line-height: 1; }
|
||||
.moon-bon { color: var(--cel-orange-light, #ddb84a); font-weight: bold; }
|
||||
gap: 1px;
|
||||
.moon-sym { font-size: 1.35em; line-height: 1; }
|
||||
.moon-bon { font-size: 0.72em; color: var(--cel-orange-light, #ddb84a); font-weight: bold; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +376,7 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
padding: 8px 10px 4px;
|
||||
padding: 8px 10px 5px;
|
||||
background: var(--cel-cream, #f0e8d4);
|
||||
justify-content: center;
|
||||
|
||||
@@ -290,23 +384,25 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 2px solid var(--cel-border, #7a5c20);
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
font-size: 1.05em;
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
box-shadow: 1px 1px 2px rgba(0,0,0,0.15);
|
||||
box-shadow: 1px 1px 2px rgba(0,0,0,0.12);
|
||||
color: #222;
|
||||
|
||||
&.max {
|
||||
background: var(--cel-green, #1b3828);
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
border-color: var(--cel-orange, #c49a1a);
|
||||
background: var(--cel-green, #0c4c0c);
|
||||
color: var(--cel-orange, #e07b00);
|
||||
border-color: var(--cel-orange, #e07b00);
|
||||
box-shadow: 0 0 5px rgba(224,123,0,0.3);
|
||||
}
|
||||
&.min {
|
||||
background: #f9e8e8;
|
||||
background: #fae8e8;
|
||||
color: #a03030;
|
||||
border-color: #c07070;
|
||||
}
|
||||
@@ -319,59 +415,66 @@
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
padding: 4px 10px;
|
||||
gap: 4px;
|
||||
padding: 5px 10px 4px;
|
||||
background: var(--cel-cream, #f0e8d4);
|
||||
font-size: 0.85em;
|
||||
border-top: 1px solid rgba(122,92,32,0.2);
|
||||
font-size: 0.83em;
|
||||
color: #555;
|
||||
|
||||
.fl-ndice { color: var(--cel-green, #1b3828); font-weight: bold; }
|
||||
.fl-sum { font-weight: bold; }
|
||||
.fl-label { color: #999; font-size: 0.88em; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 2px; }
|
||||
.fl-ndice { color: var(--cel-green, #0c4c0c); font-weight: bold; }
|
||||
.fl-sum { font-weight: bold; color: #333; }
|
||||
.fl-total {
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
font-size: 1.4em;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
font-size: 1.5em;
|
||||
color: var(--cel-orange, #e07b00);
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
.fl-moon { color: #666; }
|
||||
.fl-mod { color: #444; }
|
||||
.fl-asp { color: var(--cel-orange, #c49a1a); }
|
||||
.fl-mod { color: #444; font-weight: bold; }
|
||||
.fl-asp { color: var(--cel-orange, #e07b00); font-weight: bold; }
|
||||
.fl-sep { font-weight: bold; color: var(--cel-border, #7a5c20); margin: 0 2px; }
|
||||
.fl-eq { color: #888; }
|
||||
.fl-op { color: #888; }
|
||||
.fl-eq { color: #aaa; }
|
||||
.fl-op { color: #aaa; }
|
||||
}
|
||||
|
||||
// ── Seuil et marge ──
|
||||
.threshold-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
padding: 4px 10px 6px;
|
||||
justify-content: space-between;
|
||||
padding: 5px 12px 6px;
|
||||
background: var(--cel-cream, #f0e8d4);
|
||||
border-top: 1px solid rgba(122,92,32,0.25);
|
||||
border-top: 1px solid rgba(122,92,32,0.2);
|
||||
font-size: 0.82em;
|
||||
|
||||
.vs-label { color: #888; text-transform: uppercase; font-size: 0.85em; }
|
||||
.diff-label{ font-style: italic; color: var(--cel-green, #1b3828); }
|
||||
.vs-wrap {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 5px;
|
||||
}
|
||||
.vs-label { color: #aaa; text-transform: uppercase; font-size: 0.8em; }
|
||||
.diff-label{ font-style: italic; color: var(--cel-green, #0c4c0c); }
|
||||
.diff-val { color: #888; }
|
||||
|
||||
.margin-badge {
|
||||
margin-left: 6px;
|
||||
padding: 1px 7px;
|
||||
border-radius: 10px;
|
||||
padding: 2px 10px;
|
||||
border-radius: 12px;
|
||||
font-weight: bold;
|
||||
font-size: 0.95em;
|
||||
font-size: 1.05em;
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
letter-spacing: 0.05em;
|
||||
|
||||
&.above {
|
||||
background: var(--cel-green, #1b3828);
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
border: 1px solid var(--cel-orange, #c49a1a);
|
||||
background: var(--cel-green, #0c4c0c);
|
||||
color: var(--cel-orange, #e07b00);
|
||||
border: 1px solid var(--cel-orange, #e07b00);
|
||||
}
|
||||
&.below {
|
||||
background: var(--cel-accent, #6b1e28);
|
||||
color: #e8c8c8;
|
||||
color: #f0d0d0;
|
||||
border: 1px solid #8b3e48;
|
||||
}
|
||||
}
|
||||
@@ -380,11 +483,13 @@
|
||||
// ── Destin utilisé ──
|
||||
.used-info {
|
||||
text-align: center;
|
||||
font-size: 0.78em;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
padding: 2px 8px;
|
||||
background: var(--cel-cream-dark, #e0d4b8);
|
||||
font-size: 0.77em;
|
||||
color: var(--cel-orange, #e07b00);
|
||||
padding: 3px 8px;
|
||||
background: rgba(196,154,26,0.1);
|
||||
border-top: 1px dashed var(--cel-border, #7a5c20);
|
||||
|
||||
.used-destin { font-weight: bold; }
|
||||
}
|
||||
|
||||
// ── Bandeau résultat ──
|
||||
@@ -392,50 +497,56 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 6px 8px;
|
||||
padding: 7px 8px;
|
||||
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
border-top: 2px solid rgba(0,0,0,0.1);
|
||||
|
||||
.result-icon { font-size: 0.9em; opacity: 0.8; }
|
||||
.result-label { font-size: 1.15em; line-height: 1.2; }
|
||||
.result-icon {
|
||||
font-size: 0.85em;
|
||||
opacity: 0.85;
|
||||
letter-spacing: 0.15em;
|
||||
}
|
||||
.result-label { font-size: 1.2em; line-height: 1.2; }
|
||||
.result-desc {
|
||||
font-size: 0.65em;
|
||||
letter-spacing: 0.12em;
|
||||
margin-top: 1px;
|
||||
opacity: 0.85;
|
||||
letter-spacing: 0.08em;
|
||||
margin-top: 2px;
|
||||
opacity: 0.8;
|
||||
text-transform: none;
|
||||
font-style: italic;
|
||||
font-family: var(--cel-font-body, serif);
|
||||
}
|
||||
|
||||
&.success {
|
||||
background-color: var(--cel-green, #1b3828);
|
||||
background-color: var(--cel-green, #0c4c0c);
|
||||
background-image: url("../assets/ui/fond_cadrille.jpg");
|
||||
background-blend-mode: soft-light;
|
||||
color: var(--cel-orange, #c49a1a);
|
||||
color: var(--cel-orange, #e07b00);
|
||||
}
|
||||
|
||||
&.critical-success {
|
||||
background: linear-gradient(135deg, #1b3828, #2c5a3f);
|
||||
background: linear-gradient(135deg, #0c4c0c 0%, #1a6e1a 50%, #0c4c0c 100%);
|
||||
background-image: url("../assets/ui/fond_cadrille.jpg");
|
||||
background-blend-mode: soft-light;
|
||||
color: var(--cel-orange-light, #ddb84a);
|
||||
border-top: 2px solid var(--cel-orange, #c49a1a);
|
||||
border-bottom: 2px solid var(--cel-orange, #c49a1a);
|
||||
text-shadow: 0 0 8px rgba(196,154,26,0.5);
|
||||
color: #ffd870;
|
||||
border-top: 3px solid var(--cel-orange, #e07b00);
|
||||
border-bottom: 3px solid var(--cel-orange, #e07b00);
|
||||
text-shadow: 0 0 10px rgba(255,216,112,0.6);
|
||||
}
|
||||
|
||||
&.failure {
|
||||
background: var(--cel-accent, #6b1e28);
|
||||
color: #e8c8c8;
|
||||
background: #4a1520;
|
||||
color: #f0c0c0;
|
||||
}
|
||||
|
||||
&.critical-failure {
|
||||
background: linear-gradient(135deg, #3d0f18, #6b1e28);
|
||||
color: #f0c8c8;
|
||||
border-top: 2px solid #8b3e48;
|
||||
border-bottom: 2px solid #8b3e48;
|
||||
background: linear-gradient(135deg, #3d0f18 0%, #5c1a25 50%, #3d0f18 100%);
|
||||
color: #ffd0d0;
|
||||
border-top: 3px solid #8b3e48;
|
||||
border-bottom: 3px solid #8b3e48;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
{{#if statLabel}}<span class="stat-lbl">{{statLabel}}</span><span class="sep"> › </span>{{/if}}
|
||||
<span class="skill-lbl">{{skillLabel}}</span>
|
||||
</span>
|
||||
{{#if woundLabel}}
|
||||
<span class="wound-info">⚠ {{woundLabel}}</span>
|
||||
{{/if}}
|
||||
{{#if woundLabel}}<span class="wound-info">⚠ {{woundLabel}}</span>{{/if}}
|
||||
</div>
|
||||
<div class="moon-badge" title="{{moonPhaseLabel}}">
|
||||
<span class="moon-sym">{{moonSymbol}}</span>
|
||||
@@ -21,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Dés --}}
|
||||
{{!-- Zone dés --}}
|
||||
<div class="dice-zone">
|
||||
{{#each diceResults as |die|}}
|
||||
<span class="die-face d6 {{#if (eq die 6)}}max{{/if}}{{#if (eq die 1)}}min{{/if}}">{{die}}</span>
|
||||
@@ -30,30 +28,33 @@
|
||||
|
||||
{{!-- Formule détaillée --}}
|
||||
<div class="formula-line">
|
||||
<span class="fl-label">{{localize "CELESTOPOL.Roll.formula"}} :</span>
|
||||
<span class="fl-ndice">{{nbDice}}d6</span>
|
||||
<span class="fl-eq"> = </span>
|
||||
<span class="fl-sum">{{diceSum}}</span>
|
||||
{{#if moonBonus}}
|
||||
<span class="fl-op"> + </span>
|
||||
<span class="fl-moon" title="{{moonPhaseLabel}}">{{moonSymbol}} {{moonBonus}}</span>
|
||||
<span class="fl-op">+</span>
|
||||
<span class="fl-moon" title="{{moonPhaseLabel}}">{{moonSymbol}}{{moonBonus}}</span>
|
||||
{{/if}}
|
||||
{{#if modifier}}
|
||||
<span class="fl-op"> {{#if (gt modifier 0)}}+{{else}}−{{/if}} </span>
|
||||
<span class="fl-op">{{#if (gt modifier 0)}}+{{else}}−{{/if}}</span>
|
||||
<span class="fl-mod">{{abs modifier}}</span>
|
||||
{{/if}}
|
||||
{{#if aspectMod}}
|
||||
<span class="fl-op"> {{#if (gt aspectMod 0)}}+{{else}}−{{/if}} </span>
|
||||
<span class="fl-asp" title="{{localize "CELESTOPOL.Roll.usedAspect"}}">✦ {{abs aspectMod}}</span>
|
||||
<span class="fl-op">{{#if (gt aspectMod 0)}}+{{else}}−{{/if}}</span>
|
||||
<span class="fl-asp" title="{{localize "CELESTOPOL.Roll.usedAspect"}}">✦{{abs aspectMod}}</span>
|
||||
{{/if}}
|
||||
<span class="fl-sep"> = </span>
|
||||
<span class="fl-sep">=</span>
|
||||
<span class="fl-total">{{total}}</span>
|
||||
</div>
|
||||
|
||||
{{!-- Seuil et marge --}}
|
||||
<div class="threshold-line">
|
||||
<span class="vs-label">vs</span>
|
||||
<span class="diff-label">{{difficultyLabel}}</span>
|
||||
<span class="diff-val">({{difficultyValue}})</span>
|
||||
<span class="vs-wrap">
|
||||
<span class="vs-label">vs</span>
|
||||
<span class="diff-label">{{difficultyLabel}}</span>
|
||||
<span class="diff-val">({{difficultyValue}})</span>
|
||||
</span>
|
||||
{{#if margin}}
|
||||
<span class="margin-badge {{#if marginAbove}}above{{else}}below{{/if}}">
|
||||
{{#if marginAbove}}+{{/if}}{{margin}}
|
||||
@@ -61,26 +62,28 @@
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{!-- Infos bonus (Destin utilisé) --}}
|
||||
{{!-- Infos bonus (Destin, Aspect) --}}
|
||||
{{#if useDestin}}
|
||||
<div class="used-info">
|
||||
<span class="used-destin">⭐ {{localize "CELESTOPOL.Roll.usedDestin"}}</span>
|
||||
<span class="used-destin">✦ {{localize "CELESTOPOL.Roll.usedDestin"}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{!-- Bandeau résultat --}}
|
||||
<div class="roll-result-banner {{resultClass}}">
|
||||
{{#if isCriticalSuccess}}
|
||||
<span class="result-icon">✦</span>
|
||||
<span class="result-icon">✦✦</span>
|
||||
<span class="result-label">{{localize "CELESTOPOL.Roll.criticalSuccess"}}</span>
|
||||
<span class="result-desc">{{localize "CELESTOPOL.Roll.criticalSuccessDesc"}}</span>
|
||||
{{else if isSuccess}}
|
||||
<span class="result-icon">✦</span>
|
||||
<span class="result-label">{{localize "CELESTOPOL.Roll.success"}}</span>
|
||||
{{else if isCriticalFailure}}
|
||||
<span class="result-icon">✖</span>
|
||||
<span class="result-icon">✖✖</span>
|
||||
<span class="result-label">{{localize "CELESTOPOL.Roll.criticalFailure"}}</span>
|
||||
<span class="result-desc">{{localize "CELESTOPOL.Roll.criticalFailureDesc"}}</span>
|
||||
{{else if isFailure}}
|
||||
<span class="result-icon">✖</span>
|
||||
<span class="result-label">{{localize "CELESTOPOL.Roll.failure"}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<div class="roll-dialog-content">
|
||||
|
||||
{{!-- Info bloc : acteur + domaine --}}
|
||||
{{!-- En-tête : acteur + domaine + dés de base --}}
|
||||
<div class="roll-info-block">
|
||||
<div class="roll-actor">{{actorName}}</div>
|
||||
<div class="roll-skill-line">
|
||||
{{#if statLabel}}<span class="stat-label">{{localize statLabel}}</span><span class="sep"> › </span>{{/if}}
|
||||
<span class="skill-label">{{localize skillLabel}}</span>
|
||||
</div>
|
||||
|
||||
<div class="roll-dice-summary">
|
||||
<div class="dice-breakdown">
|
||||
<span class="dval">{{skillValue}}</span>
|
||||
@@ -26,12 +25,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Sélecteur Phase de Lune --}}
|
||||
{{!-- Phases de lune : grille 3 × 3 --}}
|
||||
<div class="moon-section">
|
||||
<div class="moon-section-label">{{localize "CELESTOPOL.Roll.moonPhase"}}</div>
|
||||
<div class="moon-phases" id="moon-phases">
|
||||
{{#each moonPhaseChoices as |phase key|}}
|
||||
<label class="moon-option {{#if (eq key ../defaultMoonPhase)}}active{{/if}}" data-moon="{{key}}" title="{{localize phase.label}}{{#if phase.bonus}} (+{{phase.bonus}}){{else}} (+0){{/if}}">
|
||||
<label class="moon-option {{#if (eq key ../defaultMoonPhase)}}active{{/if}}" data-moon="{{key}}" data-moon-bonus="{{#if phase.bonus}}{{phase.bonus}}{{else}}0{{/if}}" title="{{localize phase.label}}">
|
||||
<input type="radio" name="moonPhase" value="{{key}}" {{#if (eq key ../defaultMoonPhase)}}checked{{/if}} hidden>
|
||||
<span class="moon-symbol">{{phase.symbol}}</span>
|
||||
<span class="moon-name">{{localize phase.label}}</span>
|
||||
@@ -41,41 +40,64 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Seuil de difficulté --}}
|
||||
<div class="form-group form-row">
|
||||
<label for="difficulty">{{localize "CELESTOPOL.Roll.difficulty"}}</label>
|
||||
<select id="difficulty" name="difficulty">
|
||||
{{#each difficultyChoices as |diff key|}}
|
||||
<option value="{{key}}" {{#if (eq key ../defaultDifficulty)}}selected{{/if}}>
|
||||
{{localize diff.label}}{{#if diff.value}} ({{diff.value}}){{/if}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="roll-form-rows">
|
||||
|
||||
{{!-- Modificateur & Aspect en ligne --}}
|
||||
<div class="form-two-col">
|
||||
<div class="form-group">
|
||||
<label for="modifier">{{localize "CELESTOPOL.Roll.modifier"}}</label>
|
||||
<input type="number" id="modifier" name="modifier" value="0" min="-10" max="10">
|
||||
{{!-- Difficulté --}}
|
||||
<div class="form-row-line">
|
||||
<label for="difficulty">{{localize "CELESTOPOL.Roll.difficulty"}}</label>
|
||||
<select id="difficulty" name="difficulty">
|
||||
{{#each difficultyChoices as |diff key|}}
|
||||
<option value="{{key}}" {{#if (eq key ../defaultDifficulty)}}selected{{/if}}>
|
||||
{{localize diff.label}}{{#if diff.value}} ({{diff.value}}){{/if}}
|
||||
</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="aspectModifier">{{localize "CELESTOPOL.Roll.aspect"}}</label>
|
||||
<input type="number" id="aspectModifier" name="aspectModifier" value="0" min="-4" max="4">
|
||||
|
||||
{{!-- Modificateur & Aspect côte à côte --}}
|
||||
<div class="form-two-col">
|
||||
<div class="form-row-line">
|
||||
<label for="modifier">{{localize "CELESTOPOL.Roll.modifier"}}</label>
|
||||
<input type="number" id="modifier" name="modifier" value="0" min="-10" max="10">
|
||||
</div>
|
||||
<div class="form-row-line">
|
||||
<label for="aspectModifier">{{localize "CELESTOPOL.Roll.aspect"}}</label>
|
||||
<input type="number" id="aspectModifier" name="aspectModifier" value="0" min="-4" max="4">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Destin --}}
|
||||
<div class="form-destin-row {{#unless destActuel}}destin-disabled{{/unless}}">
|
||||
<label class="destin-toggle" for="useDestin">
|
||||
<input type="checkbox" id="useDestin" name="useDestin" {{#unless destActuel}}disabled{{/unless}}>
|
||||
<span class="destin-icon">✦</span>
|
||||
<span class="destin-text">
|
||||
<span class="destin-main">{{localize "CELESTOPOL.Roll.destin"}}</span>
|
||||
<span class="destin-bonus">{{localize "CELESTOPOL.Roll.destinBonus"}}</span>
|
||||
</span>
|
||||
{{#if destActuel}}
|
||||
<span class="destin-count">{{destActuel}} {{localize "CELESTOPOL.Roll.destinAvailable"}}</span>
|
||||
{{else}}
|
||||
<span class="destin-count no-destin">{{localize "CELESTOPOL.Roll.destinNone"}}</span>
|
||||
{{/if}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{{!-- Visibilité --}}
|
||||
<div class="form-row-line form-visibility">
|
||||
<label for="visibility">{{localize "CELESTOPOL.Roll.visibility"}}</label>
|
||||
<select id="visibility" name="visibility">
|
||||
<option value="publicroll">{{localize "CELESTOPOL.Roll.visibilityPublic"}}</option>
|
||||
<option value="gmroll">{{localize "CELESTOPOL.Roll.visibilityGM"}}</option>
|
||||
<option value="selfroll">{{localize "CELESTOPOL.Roll.visibilitySelf"}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{!-- Destin --}}
|
||||
<div class="form-group form-destin">
|
||||
<label class="destin-label" for="useDestin">
|
||||
<input type="checkbox" id="useDestin" name="useDestin">
|
||||
<span class="destin-icon">⭐</span>
|
||||
{{localize "CELESTOPOL.Roll.destin"}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{{!-- Prévisualisation dynamique --}}
|
||||
<div class="dice-preview" id="dice-preview">
|
||||
{{!-- Prévisualisation formule --}}
|
||||
<div class="dice-preview">
|
||||
<span class="preview-label">{{localize "CELESTOPOL.Roll.formula"}}</span>
|
||||
<span class="preview-formula" id="preview-formula">{{nbDiceBase}}d6</span>
|
||||
</div>
|
||||
|
||||
@@ -91,27 +113,26 @@
|
||||
const base = Math.max(1, skillVal + woundMalus);
|
||||
|
||||
function update() {
|
||||
const moonBonus = parseInt(wrap.querySelector('input[name="moonPhase"]:checked')?.closest('[data-moon]')
|
||||
?.dataset.moonBonus ?? 0);
|
||||
const moonOpt = wrap.querySelector('input[name="moonPhase"]:checked')?.closest('[data-moon]');
|
||||
const moonBonus = parseInt(moonOpt?.dataset.moonBonus ?? 0) || 0;
|
||||
const modifier = parseInt(wrap.querySelector('#modifier')?.value ?? 0) || 0;
|
||||
const aspectMod = parseInt(wrap.querySelector('#aspectModifier')?.value ?? 0) || 0;
|
||||
const useDestin = wrap.querySelector('#useDestin')?.checked ? 2 : 0;
|
||||
const ndice = Math.max(1, base + useDestin);
|
||||
const totalMod = moonBonus + modifier + aspectMod;
|
||||
const formula = totalMod !== 0 ? `${ndice}d6 + ${totalMod}` : `${ndice}d6`;
|
||||
|
||||
const previewEl = wrap.querySelector('#preview-formula');
|
||||
const ndiceEl = wrap.querySelector('#preview-ndice');
|
||||
if (previewEl) previewEl.textContent = formula;
|
||||
if (ndiceEl) ndiceEl.textContent = ndice;
|
||||
let formula = `${ndice}d6`;
|
||||
if (totalMod > 0) formula += ` + ${totalMod}`;
|
||||
if (totalMod < 0) formula += ` − ${Math.abs(totalMod)}`;
|
||||
|
||||
const previewEl = wrap.querySelector('#preview-formula');
|
||||
const ndiceEl = wrap.querySelector('#preview-ndice');
|
||||
if (previewEl) previewEl.textContent = formula;
|
||||
if (ndiceEl) ndiceEl.textContent = ndice;
|
||||
}
|
||||
|
||||
// Mettre à jour les classes actives des lunes + moon-bonus
|
||||
wrap.querySelectorAll('.moon-option').forEach(opt => {
|
||||
const input = opt.querySelector('input[type="radio"]');
|
||||
const key = opt.dataset.moon;
|
||||
const bonusMap = { {{#each moonPhaseChoices}}"{{@key}}": {{#if bonus}}{{bonus}}{{else}}0{{/if}}, {{/each}} };
|
||||
opt.dataset.moonBonus = bonusMap[key] ?? 0;
|
||||
input.addEventListener('change', () => {
|
||||
wrap.querySelectorAll('.moon-option').forEach(o => o.classList.remove('active'));
|
||||
opt.classList.add('active');
|
||||
@@ -121,7 +142,7 @@
|
||||
|
||||
wrap.querySelectorAll('#modifier, #aspectModifier, #useDestin').forEach(el => {
|
||||
el.addEventListener('change', update);
|
||||
el.addEventListener('input', update);
|
||||
el.addEventListener('input', update);
|
||||
});
|
||||
|
||||
update();
|
||||
|
||||
Reference in New Issue
Block a user