<aside @ref="LogPanelRef" class="card log-panel">
    <div class="section-head">
        <h2>Campaign Log</h2>
    </div>
    <div @ref="LogFeedRef" class="log-panel-feed">
        @if (IsCampaignDataLoading)
        {
            <div class="skeleton-stack">
                <div class="skeleton-line"></div>
                <div class="skeleton-line"></div>
                <div class="skeleton-line short"></div>
            </div>
        }
        else if (CampaignLog.Count == 0)
        {
            <p class="empty">No log entries yet.</p>
        }
        else
        {
            <ul class="log-list">
                @foreach (var entry in CampaignLog)
                {
                    var isExpanded = ExpandedRollId == entry.RollId;
                    <li class="log-entry @LogEntryCssClass(entry, isExpanded, FreshRollId == entry.RollId)">
                        <button type="button"
                                class="log-entry-toggle"
                                aria-expanded="@isExpanded"
                                @onclick="() => ToggleRollDetailRequested.InvokeAsync(entry.RollId)">
                            <span class="log-entry-main">
                                <span class="log-entry-copy">
                                    <span class="log-entry-actor">@entry.RollerLabel</span>
                                    <span class="log-entry-action">rolled</span>
                                    <span class="log-entry-skill">@entry.SkillName</span>
                                    <span class="log-entry-action">with</span>
                                    <span class="log-entry-character">@entry.CharacterName</span>
                                </span>
                                <span class="roll-total inline">@entry.Result</span>
                            </span>
                            @if (HasSummary(entry))
                            {
                                <span class="log-summary-row">
                                    @foreach (var badge in GetEventBadges(entry))
                                    {
                                        <span class="log-event-badge @badge.Tone">@badge.Label</span>
                                    }
                                    @if (!string.IsNullOrWhiteSpace(entry.SummaryText))
                                    {
                                        <span class="log-summary-text">@entry.SummaryText</span>
                                    }
                                </span>
                            }
                            <span class="log-meta">
                                <span class="badge @entry.VisibilityStyle">@entry.VisibilityLabel</span>
                                <time
                                    title="@entry.TimestampUtc.ToString("O")">
                                    @entry.TimestampUtc.ToLocalTime().ToString("g")
                                </time>
                            </span>
                        </button>
                        @if (isExpanded)
                        {
                            <div class="log-detail">
                                @if (IsRollDetailLoading(entry.RollId))
                                {
                                    <p class="muted">Loading roll detail...</p>
                                }
                                else if (!string.IsNullOrWhiteSpace(GetRollDetailError(entry.RollId)))
                                {
                                    <p class="field-error">@GetRollDetailError(entry.RollId)</p>
                                }
                                else if (ResolveRollDetail(entry.RollId) is { } detail)
                                {
                                    <RollDiceStrip Dice="detail.Dice" AriaLabel="Log roll dice"/>
                                    <p>@detail.Breakdown</p>
                                }
                            </div>
                        }
                    </li>
                }
            </ul>
        }
    </div>

    <section class="custom-roll-panel" aria-label="Custom roll panel">
        <form class="custom-roll-composer" @onsubmit="SubmitCustomRollAsync" @onsubmit:preventDefault>
            <div class="custom-roll-composer-head">
                <label for="custom-roll-expression" class="custom-roll-label">Custom roll</label>
                <span class="muted">@CustomRollStatusText</span>
            </div>
            <div class="custom-roll-composer-row">
                <input id="custom-roll-expression"
                       @key="CustomRollInputVersion"
                       @ref="CustomRollInputRef"
                       class="@CustomRollInputCssClass"
                       @bind="CustomRollExpression"
                       @bind:event="oninput"
                       placeholder="@CustomRollPlaceholder"
                       title="@CustomRollInputTitle"
                       aria-invalid="@HasCustomRollError"
                       aria-describedby="@CustomRollInputDescribedBy"
                       disabled="@IsCustomRollDisabled"/>
                <button type="submit" disabled="@IsCustomRollDisabled">Roll</button>
            </div>
            <p class="field-help">@CustomRollHelpText</p>
            @if (HasCustomRollError)
            {
                <p id="@CustomRollErrorElementId" class="field-error" role="alert">@CustomRollErrorMessage</p>
            }
        </form>
    </section>
</aside>
