.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #d0d7de;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: #1b6ec2;
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ═══════════════════════════════════════════════════════════════════════
   KSNZ Public Incident Log — theme (light)
   ═══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

:root {
    --bg:          #ffffff;
    --surface:     #f6f8fa;
    --surface2:    #eaeef2;
    --border:      #d0d7de;
    --text:        #1f2328;
    --text-dim:    #656d76;
    --accent:      #0969da;
    --green:       #1a7f37;
    --yellow:      #9a6700;
    --red:         #cf222e;
    --gold:        #9a6700;
    --purple:      #8250df;
    --radius:      6px;
    --font-mono:   'Courier New', Courier, monospace;
}

html, body {
    height: 100%;
    background: var(--bg);
    color: var(--text);
    font-family: system-ui, -apple-system, sans-serif;
    margin: 0;
}

/* ── App shell ────────────────────────────────────────────────────── */
.app-shell { display: flex; flex-direction: column; min-height: 100vh; }

.top-bar {
    background: var(--surface); border-bottom: 1px solid var(--border);
    padding: .6rem 1.2rem; display: flex; align-items: center;
    gap: 1.2rem; flex-wrap: wrap;
}

.brand {
    font-size: 1.1rem; font-weight: 700; color: var(--accent);
    letter-spacing: .05em; text-decoration: none;
}

.status-bar {
    margin-left: auto; display: flex; align-items: center; gap: .6rem;
    font-size: .8rem; color: var(--text-dim);
}

.dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--text-dim); flex-shrink: 0;
}
.dot.live { background: var(--green); box-shadow: 0 0 6px var(--green); }

.main-content { flex: 1; padding: 1.2rem; max-width: 1600px; width: 100%; margin: 0 auto; }

/* ── Page heading / event selector ───────────────────────────────── */
.page-heading { margin-bottom: 1.2rem; }
.page-heading h2 { margin: 0 0 .3rem 0; }

.event-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 1rem;
}

.event-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 1rem; text-decoration: none;
    color: var(--text); transition: border-color .15s, transform .15s;
    display: block;
}
.event-card:hover { border-color: var(--accent); transform: translateY(-1px); }
.event-card-name { font-weight: 700; margin-bottom: .3rem; }
.event-card-dates { font-size: .8rem; margin-top: .3rem; }

/* ── Split layout: incidents (2/3) + totem pole (1/3) ────────────── */
.split-layout { display: flex; gap: 1.2rem; align-items: flex-start; }
.incidents-pane { flex: 5 1 0; min-width: 0; }
.totem-pane { flex: 1 1 0; min-width: 0; position: sticky; top: 1.2rem; }

@media (max-width: 900px) {
    .split-layout { flex-direction: column; }
    .totem-pane { position: static; width: 100%; }

    /* flex-basis:100% forces each filter control onto its own line — a <select>'s
       intrinsic content width (its longest option) resists shrinking to fit three
       across on a phone-width row even with flex-wrap, so give up on fitting them
       side by side rather than let the row force the whole page wider. */
    .filter-bar input, .filter-bar select { flex: 1 1 100%; min-width: 0; }

    /* Card-ify the incident table — no horizontal scrolling/overflow on a phone.
       Each <tr> becomes a bordered card; each <td> becomes a label/value row via
       data-label (set in IncidentLog.razor), except the Time/Status pair which are
       marked .card-row-header and read as the card's title instead. */
    .incident-table thead { display: none; }
    .incident-table, .incident-table tbody, .incident-table tr, .incident-table td {
        display: block; width: 100%;
    }
    .incident-table tr {
        border: 1px solid var(--border); border-radius: var(--radius);
        background: var(--surface); margin-bottom: .75rem; padding: .5rem .75rem;
    }
    .incident-table tr:hover td { background: none; }
    .incident-table tr.row-protest { background-color: #ffebe9; }
    .incident-table tr.row-protest:hover { background-color: #ffd7d5; }
    .incident-table tr.row-cancelled { text-decoration: line-through; opacity: .65; }
    .incident-table tr.group-start { border-top: 3px solid var(--accent); }

    /* Plain rows: normal inline text flow ("LABEL: value") so long content (notes,
       location) wraps naturally instead of overflowing — a two-column flex layout here
       would let the value's anonymous flex item overflow the viewport instead of
       wrapping, since flex items don't shrink below their content's intrinsic width
       without an explicit min-width:0 on the (unwrappable) text node. */
    .incident-table td {
        border-bottom: none; padding: .3rem 0; overflow-wrap: break-word;
    }
    .incident-table td:empty { display: none; }
    .incident-table td::before {
        content: attr(data-label) ": "; font-weight: 600; color: var(--text-dim);
        font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
    }

    /* Time + Status ride together as the card's title row instead of a labelled line. */
    .incident-table td.card-row-header {
        display: inline-flex; align-items: center; margin-right: .75rem;
        padding-bottom: .5rem; margin-bottom: .3rem;
        font-size: 1rem; font-weight: 600;
    }
    .incident-table td.card-row-header::before { content: none; }
    .incident-table td.card-row-header-end {
        width: 100%; border-bottom: 1px solid var(--border);
    }

    .incident-table .notes { max-width: none; }
}

/* ── Cards / tables (shared) ─────────────────────────────────────── */
.card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); overflow: hidden; margin-bottom: 1.2rem;
}
.card-header {
    padding: .7rem 1rem; border-bottom: 1px solid var(--border);
    font-size: .85rem; font-weight: 600; color: var(--text-dim);
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
}
.card-header span:first-child { color: var(--text); }

.timing-table { width: 100%; border-collapse: collapse; font-size: .875rem; }
.timing-table th {
    background: var(--surface); color: var(--text-dim);
    font-weight: 600; font-size: .75rem; text-transform: uppercase;
    letter-spacing: .06em; padding: .6rem .8rem;
    text-align: left; border-bottom: 1px solid var(--border);
}
.timing-table td {
    padding: .55rem .8rem; border-bottom: 1px solid var(--border);
    vertical-align: middle;
}
.timing-table tr:hover td { background: var(--surface2); }

.incident-table .notes { color: var(--text-dim); max-width: 24rem; }

.video-link {
    color: var(--accent); text-decoration: none; font-size: .8rem;
    white-space: nowrap; border: 1px solid var(--border); border-radius: 3px;
    padding: .15rem .5rem; background: var(--surface2);
}
.video-link:hover { border-color: var(--accent); }

.mono  { font-family: var(--font-mono); }
.dim   { color: var(--text-dim); }
.green { color: var(--green); }
.gold  { color: var(--gold); }
.truncate { max-width: 10rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.pos    { font-weight: 700; font-family: var(--font-mono); color: var(--text-dim); }
.pos.p1 { color: var(--gold); }
.pos.p2 { color: #6e7781; }
.pos.p3 { color: #954c11; }

/* ── Incident state badges ───────────────────────────────────────── */
.state-badge {
    display: inline-block; border-radius: 3px; padding: .15rem .5rem;
    font-size: .75rem; border: 1px solid var(--border); background: var(--surface2);
    color: var(--text-dim); white-space: nowrap;
}

/* ── Incident row styling ────────────────────────────────────────── */
.timing-table tr.row-protest td { background-color: #ffebe9; }
.timing-table tr.row-protest:hover td { background-color: #ffd7d5; }
.timing-table tr.row-cancelled td { text-decoration: line-through; opacity: .65; }

/* Visual gap between rows when the Class/Session changes — a thick page-coloured
   top border reads as a break without needing extra spacer rows in the table. */
.timing-table tr.group-start td { border-top: 8px solid var(--bg); }

/* ── Incident filter bar ─────────────────────────────────────────── */
.filter-bar {
    display: flex; flex-wrap: wrap; gap: .6rem; align-items: center;
    padding: .7rem 1rem; border-bottom: 1px solid var(--border);
}
.filter-bar input, .filter-bar select {
    background: var(--bg); border: 1px solid var(--border); color: var(--text);
    border-radius: var(--radius); padding: .4rem .6rem; font-size: .85rem; outline: none;
}
.filter-bar input:focus, .filter-bar select:focus { border-color: var(--accent); }
.filter-bar input { width: 8rem; }
.filter-bar .clear-filters {
    background: none; border: 1px solid var(--border); color: var(--text-dim);
    border-radius: var(--radius); padding: .4rem .7rem; font-size: .8rem; cursor: pointer;
}
.filter-bar .clear-filters:hover { border-color: var(--accent); color: var(--text); }

/* ── Totem pole (compact live timing) ────────────────────────────── */
.totem .card-header { padding-bottom: .6rem; }
.session-meta-compact { padding: .6rem 1rem 0 1rem; }
.session-name { font-weight: 700; }

.timing-pills.compact { display: flex; gap: .5rem; padding: .6rem 1rem; flex-wrap: wrap; }
.pill {
    background: var(--surface2); border: 1px solid var(--border);
    border-radius: var(--radius); padding: .3rem .6rem; font-size: .75rem;
}
.pill-label { color: var(--text-dim); margin-right: .3rem; }
.pill-value { font-weight: 600; font-family: var(--font-mono); }

.timing-table.compact th, .timing-table.compact td { padding: .4rem .5rem; font-size: .8rem; }

.flag-banner {
    margin: 0 1rem .6rem 1rem; padding: .4rem .6rem; border-radius: var(--radius);
    font-weight: 700; font-size: .75rem; letter-spacing: .06em; text-transform: uppercase;
    display: none;
}
.flag-banner.visible { display: block; }
.flag-green  { background: #dafbe1; color: var(--green);  border: 1px solid var(--green); }
.flag-yellow { background: #fff8c5; color: var(--yellow); border: 1px solid var(--yellow); }
.flag-red    { background: #ffebe9; color: var(--red);    border: 1px solid var(--red); }
.flag-finish { background: var(--surface2); color: var(--text); border: 1px solid var(--border); }

/* ── State messages ───────────────────────────────────────────────── */
.empty-state { padding: 3rem; text-align: center; color: var(--text-dim); }
.empty-state.small { padding: 1.5rem; font-size: .85rem; }
.loading-spinner {
    display: inline-block; width: 1.2rem; height: 1.2rem;
    border: 2px solid var(--border); border-top-color: var(--accent);
    border-radius: 50%; animation: spin .7s linear infinite;
    margin-right: .5rem; vertical-align: middle;
}
@keyframes spin { to { transform: rotate(360deg); } }