Redesign setup modal with organized sections and improved layout

This commit is contained in:
2026-04-09 13:33:57 -04:00
parent b4de9d112b
commit 6c47b3e288
2 changed files with 318 additions and 664 deletions

View File

@@ -789,122 +789,127 @@ function renderNewGameModal() {
return `
<div class="modal-backdrop" id="new-game-modal-backdrop">
<section class="modal panel" role="dialog" aria-modal="true" aria-labelledby="new-game-title">
<div class="panel__title-row">
<div>
<section class="modal setup-modal" role="dialog" aria-modal="true" aria-labelledby="new-game-title">
<header class="modal-header">
<div class="modal-header__title">
<p class="eyebrow">New Game</p>
<h1 id="new-game-title">Configure the next canopy</h1>
</div>
<button class="ghost-button" id="close-new-game">Close</button>
</div>
<div class="setup-grid modal-setup-grid">
<label>
<span>Players</span>
<input id="player-count" type="range" min="2" max="6" step="1" value="${setup.playerCount}" />
<strong>${setup.playerCount}</strong>
</label>
<label>
<span>Columns</span>
<input id="column-count" type="number" min="6" max="24" step="1" value="${setup.columns}" />
</label>
<label>
<span>Rows</span>
<input id="row-count" type="number" min="6" max="24" step="1" value="${setup.rows}" />
</label>
<label>
<span>Starting nodes each</span>
<input id="starting-nodes" type="number" min="1" max="${maxSeeds}" step="1" value="${setup.startingNodesPerPlayer}" />
</label>
<label class="toggle-row">
<span>Sunbeam %</span>
<input id="sunbeam-chance" type="number" min="0" max="100" step="5" value="${setup.sunbeamChance}" />
</label>
<label class="toggle-row">
<span>Disease %</span>
<input id="disease-chance" type="number" min="0" max="100" step="5" value="${setup.diseaseChance}" />
</label>
<label>
<span>Initiative</span>
<select id="initiative-mode">
<option value="fixed" ${setup.initiativeMode === "fixed" ? "selected" : ""}>Fixed Order</option>
<option value="bid" ${setup.initiativeMode === "bid" ? "selected" : ""}>Seat Draft</option>
</select>
</label>
${setup.initiativeMode === "bid" ? `
<label>
<span>Bid Order</span>
<select id="bidding-order-rule">
<option value="rotating" ${setup.biddingOrderRule === "rotating" ? "selected" : ""}>Rotating</option>
<option value="lowest_growth_income" ${setup.biddingOrderRule === "lowest_growth_income" ? "selected" : ""}>Lowest Growth</option>
</select>
</label>
` : ""}
<label class="toggle-row">
<span>Weather Draft</span>
<input id="weather-draft-toggle" type="checkbox" ${setup.weatherDraftEnabled ? "checked" : ""} />
</label>
<label>
<span>Win Condition</span>
<select id="win-condition">
<option value="rounds" ${setup.winCondition === "rounds" ? "selected" : ""}>Round Limit</option>
<option value="top_leaves" ${setup.winCondition === "top_leaves" ? "selected" : ""}>Top Leaves</option>
</select>
</label>
${setup.winCondition === "rounds" ? `
<label>
<span>Max rounds</span>
<input id="max-rounds" type="number" min="1" max="99" step="1" value="${setup.maxRounds}" />
</label>
` : `
<label>
<span>Top leaf target</span>
<input id="top-leaf-target" type="number" min="1" max="${setup.columns}" step="1" value="${setup.topLeafTarget}" />
</label>
`}
</div>
<div class="modal-grid">
<div class="seed-editor">
<div>
<p class="eyebrow">Turn order and colors</p>
<p class="seed-help">Move players up or down to set the manual color order. Leave shuffle on to randomize the order each new game.</p>
</div>
${previewPlayers.map((currentPlayer, index) => `
<div class="order-row">
<div class="order-row__label">
<span class="player-dot" style="--player-color: ${currentPlayer.color}; --player-glow: ${currentPlayer.glow};"></span>
<span>${currentPlayer.name}</span>
</header>
<div class="modal-body">
<!-- Board Settings Section -->
<section class="setup-section">
<h2 class="setup-section__title">Board Settings</h2>
<div class="setup-grid">
<label class="setup-field setup-field--range">
<span class="setup-field__label">Players</span>
<div class="setup-field__input">
<input id="player-count" type="range" min="2" max="6" step="1" value="${setup.playerCount}" />
<strong class="setup-field__value">${setup.playerCount}</strong>
</div>
<div class="order-row__actions">
<button class="mini-button" data-move-player="${index}" data-direction="up" ${index === 0 ? "disabled" : ""}>Up</button>
<button class="mini-button" data-move-player="${index}" data-direction="down" ${index === previewPlayers.length - 1 ? "disabled" : ""}>Down</button>
</div>
</div>
`).join("")}
</div>
<div class="seed-editor">
<div>
<p class="eyebrow">Starting columns</p>
<p class="seed-help">Use 1-based column numbers, comma-separated. Duplicate or invalid picks are auto-corrected when you start a new game.</p>
</div>
<button class="ghost-button randomize-button" id="randomize-starting-locations">Randomize Starting Locations</button>
${previewPlayers.map((currentPlayer, index) => `
<label class="seed-row">
<span style="color: ${currentPlayer.color};">${currentPlayer.name}</span>
<input
class="seed-input"
data-player-id="${index}"
type="text"
value="${setup.seedInputs[index] ?? ""}"
placeholder="e.g. 2, 5"
/>
</label>
`).join("")}
</div>
<label class="setup-field">
<span class="setup-field__label">Columns</span>
<input id="column-count" type="number" min="6" max="24" step="1" value="${setup.columns}" />
</label>
<label class="setup-field">
<span class="setup-field__label">Rows</span>
<input id="row-count" type="number" min="6" max="24" step="1" value="${setup.rows}" />
</label>
<label class="setup-field">
<span class="setup-field__label">Starting Nodes</span>
<input id="starting-nodes" type="number" min="1" max="${maxSeeds}" step="1" value="${setup.startingNodesPerPlayer}" />
</label>
</div>
</section>
<!-- Game Rules Section -->
<section class="setup-section">
<h2 class="setup-section__title">Game Rules</h2>
<div class="setup-grid setup-grid--2col">
<label class="setup-field">
<span class="setup-field__label">Win Condition</span>
<select id="win-condition">
<option value="rounds" ${setup.winCondition === "rounds" ? "selected" : ""}>Round Limit</option>
<option value="top_leaves" ${setup.winCondition === "top_leaves" ? "selected" : ""}>Top Leaves</option>
</select>
</label>
${setup.winCondition === "rounds" ? `
<label class="setup-field">
<span class="setup-field__label">Max Rounds</span>
<input id="max-rounds" type="number" min="1" max="99" step="1" value="${setup.maxRounds}" />
</label>
` : `
<label class="setup-field">
<span class="setup-field__label">Top Leaf Target</span>
<input id="top-leaf-target" type="number" min="1" max="${setup.columns}" step="1" value="${setup.topLeafTarget}" />
</label>
`}
<label class="setup-field">
<span class="setup-field__label">Initiative</span>
<select id="initiative-mode">
<option value="fixed" ${setup.initiativeMode === "fixed" ? "selected" : ""}>Fixed Order</option>
<option value="bid" ${setup.initiativeMode === "bid" ? "selected" : ""}>Seat Draft</option>
</select>
</label>
${setup.initiativeMode === "bid" ? `
<label class="setup-field">
<span class="setup-field__label">Bid Order</span>
<select id="bidding-order-rule">
<option value="rotating" ${setup.biddingOrderRule === "rotating" ? "selected" : ""}>Rotating</option>
<option value="lowest_growth_income" ${setup.biddingOrderRule === "lowest_growth_income" ? "selected" : ""}>Lowest Growth</option>
</select>
</label>
` : ""}
</div>
</section>
<!-- Random Events Section -->
<section class="setup-section">
<h2 class="setup-section__title">Random Events</h2>
<div class="setup-grid setup-grid--3col">
<label class="setup-field">
<span class="setup-field__label">Sunbeam %</span>
<input id="sunbeam-chance" type="number" min="0" max="100" step="5" value="${setup.sunbeamChance}" />
</label>
<label class="setup-field">
<span class="setup-field__label">Disease %</span>
<input id="disease-chance" type="number" min="0" max="100" step="5" value="${setup.diseaseChance}" />
</label>
<label class="setup-field setup-field--checkbox">
<span class="setup-field__label">Weather Draft</span>
<input id="weather-draft-toggle" type="checkbox" ${setup.weatherDraftEnabled ? "checked" : ""} />
</label>
</div>
</section>
<!-- Players Section -->
<section class="setup-section">
<h2 class="setup-section__title">Players & Colors</h2>
<p class="setup-section__help">Reorder players to set turn order. Starting positions are auto-assigned.</p>
<div class="player-list">
${previewPlayers.map((currentPlayer, index) => `
<div class="player-row">
<div class="player-row__info">
<span class="player-dot" style="--player-color: ${currentPlayer.color}; --player-glow: ${currentPlayer.glow};"></span>
<span class="player-row__name">${currentPlayer.name}</span>
</div>
<div class="player-row__actions">
<button class="mini-button" data-move-player="${index}" data-direction="up" ${index === 0 ? "disabled" : ""}>↑</button>
<button class="mini-button" data-move-player="${index}" data-direction="down" ${index === previewPlayers.length - 1 ? "disabled" : ""}>↓</button>
</div>
</div>
`).join("")}
</div>
</section>
</div>
<div class="button-row modal-actions">
<footer class="modal-footer">
<button class="ghost-button" id="cancel-new-game">Cancel</button>
<button id="start-new-game">Start New Game</button>
</div>
</footer>
</section>
</div>
`;