@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">Character name</label>
                <input id="@NameInputId" @bind="FormState.Model.Name" @bind:event="oninput"/>
                @if (FormState.Errors.TryGetValue("name", out var nameError))
                {
                    <p class="field-error">@nameError</p>
                }
                <label for="@CampaignInputId">Campaign</label>
                <select id="@CampaignInputId" @bind="FormState.Model.CampaignId">
                    <option value="">@(EditingCharacterId.HasValue ? "No campaign" : "Select campaign")</option>
                    @foreach (var campaign in CampaignOptions)
                    {
                        <option value="@campaign.Id">@campaign.Name</option>
                    }
                </select>
                @if (FormState.Errors.TryGetValue("campaignId", out var campaignError))
                {
                    <p class="field-error">@campaignError</p>
                }
                @if (AllowOwnerEdit)
                {
                    <label for="@OwnerUsernameInputId">Owner username</label>
                    <select id="@OwnerUsernameInputId" @bind="FormState.Model.OwnerUsername">
                        <option value="">Keep current owner</option>
                        @foreach (var username in AvailableUsernames.OrderBy(username => username, StringComparer.OrdinalIgnoreCase))
                        {
                            <option value="@username">@username</option>
                        }
                    </select>
                    @if (FormState.Errors.TryGetValue("ownerUsername", out var ownerUsernameError))
                    {
                        <p class="field-error">@ownerUsernameError</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>
}