@if (Visible)
{
    <div class="modal-overlay" role="presentation">
        <section class="modal-card" role="dialog" aria-modal="true" aria-label="@Title">
            <h2>@Title</h2>
            @if (!string.IsNullOrWhiteSpace(FormState.ErrorMessage))
            {
                <p class="form-error">@FormState.ErrorMessage</p>
            }
            <form class="form-grid" @onsubmit="SubmitAsync" @onsubmit:preventDefault>
                <label for="@NameInputId">Skill name</label>
                <input id="@NameInputId" @ref="NameInputElement" @bind="FormState.Model.Name" @bind:event="oninput"/>
                @if (FormState.Errors.TryGetValue("name", out var skillNameError))
                {
                    <p class="field-error">@skillNameError</p>
                }
                <label for="@ExpressionInputId">Expression</label>
                <input id="@ExpressionInputId" value="@FormState.Model.DiceRollDefinition" @oninput="OnExpressionChanged"/>
                <p class="field-help">@ExpressionHelpText</p>
                @if (FormState.Errors.TryGetValue("diceRollDefinition", out var expressionError))
                {
                    <p class="field-error">@expressionError</p>
                }
                <label for="@SkillGroupInputId">Group</label>
                <select id="@SkillGroupInputId" @bind="FormState.Model.SkillGroupId">
                    <option value="">No group</option>
                    @foreach (var group in AvailableSkillGroups)
                    {
                        <option value="@group.Id">@group.Name</option>
                    }
                </select>
                @if (FormState.Errors.TryGetValue("skillGroupId", out var skillGroupError))
                {
                    <p class="field-error">@skillGroupError</p>
                }
                @if (IsD6Ruleset)
                {
                    <label for="@WildDiceInputId">Wild dice</label>
                    <input id="@WildDiceInputId" type="number" min="1" step="1" @bind="FormState.Model.WildDice"/>
                    @if (FormState.Errors.TryGetValue("wildDice", out var wildDiceError))
                    {
                        <p class="field-error">@wildDiceError</p>
                    }

                    <label for="@AllowFumbleInputId">Allow fumble</label>
                    <input id="@AllowFumbleInputId" type="checkbox" @bind="FormState.Model.AllowFumble"/>
                }
                else if (IsRolemasterRuleset)
                {
                    @if (IsRolemasterOpenEndedSelected)
                    {
                        <label for="@FumbleRangeInputId">Fumble range</label>
                        <input id="@FumbleRangeInputId" type="number" min="0" max="95" step="1" @bind="FormState.Model.FumbleRange"/>
                        <p class="field-help">Used only for low-end open-ended rolls. Allowed range: 0 to 95.</p>
                        @if (FormState.Errors.TryGetValue("fumbleRange", out var fumbleRangeError))
                        {
                            <p class="field-error">@fumbleRangeError</p>
                        }

                        <label for="skill-auto-retry">Automatic retry</label>
                        <input id="skill-auto-retry" type="checkbox" @bind="FormState.Model.RolemasterAutoRetry"/>
                        <p class="field-help">When later enabled in rolling, retry bands are 76-90 and 91-110.</p>
                    }
                }
                <div class="inline-actions">
                    <button type="submit" disabled="@(IsMutating || IsSubmitting)">@SubmitLabel</button>
                    <button type="button" class="ghost" @onclick="CancelRequested">Cancel</button>
                </div>
            </form>
        </section>
    </div>
}