feat: rework percentile roll into a stateful tens+ones flow

Tens and Ones now combine into a real 1-100 percentile result
(00+0 = 100) instead of rolling independently. Ones is disabled
until Tens is rolled, and a pending visual state shows the tens
value while waiting for the ones roll. Adds a Clear button to
reset the flow.
This commit is contained in:
claudecode
2026-07-01 00:34:47 -04:00
parent 40b0e21d9d
commit 736f744c03
3 changed files with 61 additions and 8 deletions
+8
View File
@@ -822,6 +822,14 @@ h1, h2, h3, h4, h5, h6 {
line-height: 1; line-height: 1;
} }
.dice-result-box.pending {
border-color: var(--info);
}
.dice-total.pending-value {
color: var(--info);
}
.dice-breakdown { .dice-breakdown {
margin-top: 6px; margin-top: 6px;
font-family: var(--font-mono); font-family: var(--font-mono);
+3 -2
View File
@@ -273,10 +273,11 @@
<div class="card-title">Percentile</div> <div class="card-title">Percentile</div>
<div class="dice-actions-row"> <div class="dice-actions-row">
<button class="roll-btn" id="percentileTensBtn">Tens</button> <button class="roll-btn" id="percentileTensBtn">Tens</button>
<button class="roll-btn" id="percentileOnesBtn">Ones</button> <button class="roll-btn" id="percentileOnesBtn" disabled>Ones</button>
<button class="clear-btn" id="percentileClearBtn">Clear</button>
</div> </div>
<div class="dice-result-box" style="margin-top:1rem;" id="percentileResult"> <div class="dice-result-box" style="margin-top:1rem;" id="percentileResult">
<span class="placeholder">Roll tens or ones.</span> <span class="placeholder">Roll tens to begin.</span>
</div> </div>
</div> </div>
+50 -6
View File
@@ -122,6 +122,52 @@ function clearCustomRoll() {
box.innerHTML = '<span class="placeholder">Enter a quantity and die size.</span>'; box.innerHTML = '<span class="placeholder">Enter a quantity and die size.</span>';
} }
let percentileTens = null;
function updatePercentileButtons() {
document.getElementById('percentileTensBtn').disabled = percentileTens !== null;
document.getElementById('percentileOnesBtn').disabled = percentileTens === null;
}
function rollPercentileTens() {
percentileTens = Math.floor(Math.random() * 10) * 10; // 0, 10, 20 ... 90
updatePercentileButtons();
const box = document.getElementById('percentileResult');
box.className = 'dice-result-box animate pending';
box.innerHTML = `
<div class="dice-total pending-value">${percentileTens}</div>
<div class="dice-breakdown">Tens rolled — now roll ones.</div>
`;
void box.offsetWidth;
}
function rollPercentileOnes() {
if (percentileTens === null) return;
const ones = Math.floor(Math.random() * 10); // 0-9
const total = percentileTens + ones === 0 ? 100 : percentileTens + ones;
const box = document.getElementById('percentileResult');
box.className = 'dice-result-box animate';
box.innerHTML = `
<div class="dice-total">${total}</div>
<div class="dice-breakdown">Percentile &nbsp;[tens: ${percentileTens}, ones: ${ones}]</div>
`;
void box.offsetWidth;
percentileTens = null;
updatePercentileButtons();
}
function clearPercentile() {
percentileTens = null;
updatePercentileButtons();
const box = document.getElementById('percentileResult');
box.className = 'dice-result-box';
box.innerHTML = '<span class="placeholder">Roll tens to begin.</span>';
}
function quickRoll(sides, qty, mod, label, boxId) { function quickRoll(sides, qty, mod, label, boxId) {
const rolls = []; const rolls = [];
for (let i = 0; i < qty; i++) { for (let i = 0; i < qty; i++) {
@@ -173,12 +219,10 @@ function init() {
document.getElementById('customRollBtn').addEventListener('click', rollCustom); document.getElementById('customRollBtn').addEventListener('click', rollCustom);
document.getElementById('customClearBtn').addEventListener('click', clearCustomRoll); document.getElementById('customClearBtn').addEventListener('click', clearCustomRoll);
document.getElementById('percentileTensBtn').addEventListener('click', () => { document.getElementById('percentileTensBtn').addEventListener('click', rollPercentileTens);
quickRoll(10, 1, 0, 'Percentile (tens)', 'percentileResult'); document.getElementById('percentileOnesBtn').addEventListener('click', rollPercentileOnes);
}); document.getElementById('percentileClearBtn').addEventListener('click', clearPercentile);
document.getElementById('percentileOnesBtn').addEventListener('click', () => { updatePercentileButtons();
quickRoll(10, 1, 0, 'Percentile (ones)', 'percentileResult');
});
document.getElementById('ability4d6Btn').addEventListener('click', () => { document.getElementById('ability4d6Btn').addEventListener('click', () => {
quickRoll(6, 4, -4, '4d6 drop lowest (approx)', 'abilityResult'); quickRoll(6, 4, -4, '4d6 drop lowest (approx)', 'abilityResult');