Redesign setup modal with organized sections and improved layout
This commit is contained in:
219
src/main.ts
219
src/main.ts
@@ -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>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user