:root {
    --navy: #000858;
    --navy-light: #041b7a;
    --cyan: #00b3e2;
    --cyan-dark: #00789e;
    --ink: #14161f;
    --muted: #5b5f6e;
    --paper: #f6f7fb;
    --card: #ffffff;
    --line: #dfe2ee;
    --danger: #b91c1c;
    --danger-bg: #fef2f2;
    --success: #166534;
    --success-bg: #f0fdf4;
    --warn: #92400e;
    --warn-bg: #fffbeb;
    --font-display: "Archivo", "Segoe UI", Helvetica, Arial, sans-serif;
    --font-body: "Inter", "Segoe UI", Helvetica, Arial, sans-serif;
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

body {
    font-family: var(--font-body);
    color: var(--ink);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 800;
    color: var(--navy);
    line-height: 1.15;
    margin: 0 0 0.75rem;
}

h1 {
    font-size: 1.75rem;
}

h1:focus {
    outline: none;
}

h2 {
    font-size: 1.2rem;
}

h3 {
    font-size: 1.05rem;
}

p {
    line-height: 1.6;
}

a {
    color: var(--cyan-dark);
    text-decoration: none;
}

    a:hover {
        text-decoration: underline;
    }

code, pre {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

code {
    color: #b3306e;
    background: rgba(0, 8, 88, 0.06);
    padding: 0.1rem 0.35rem;
    border-radius: 4px;
    font-size: 0.9em;
}

pre {
    background: rgba(0, 8, 88, 0.06);
    padding: 0.75rem 1rem;
    border-radius: 8px;
    overflow-x: auto;
}

    pre code {
        background: none;
        padding: 0;
    }

/* Layout */
.app-main {
    max-width: 68rem;
    margin: 0 auto;
    padding: 2rem 1.5rem 4rem;
}

section {
    margin: 0 0 2.5rem;
}

    section:last-child {
        margin-bottom: 0;
    }

/* Page headers */
.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 2rem;
}

.eyebrow {
    margin: 0;
    font-family: var(--font-display);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cyan-dark);
}

.page-head h1 {
    margin: 0.35rem 0 0;
    font-size: 1.9rem;
}

.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

    .section-head h2 {
        margin: 0;
    }

.muted {
    color: var(--muted);
}

.small {
    font-size: 0.85rem;
}

/* Badges */
.badge {
    display: inline-block;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    background: rgba(0, 8, 88, 0.08);
    color: var(--navy);
    white-space: nowrap;
}

.badge-published {
    background: rgba(0, 179, 226, 0.16);
    color: var(--cyan-dark);
}

.badge-completed {
    background: var(--success-bg);
    color: var(--success);
}

.badge-cancelled {
    background: var(--danger-bg);
    color: var(--danger);
}

/* Invitation statuses: Pending / Accepted / Revoked / Expired. Pending keeps the neutral base —
   it is the one that still needs someone to act. */
.badge-accepted {
    background: var(--success-bg);
    color: var(--success);
}

.badge-revoked, .badge-expired {
    background: var(--danger-bg);
    color: var(--danger);
}

/* Buttons — every <button> in this app is a bare element, so the theme is applied here once
   instead of retrofitting a class onto every call site. */
button {
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 600;
    color: #fff;
    background: var(--navy);
    border: 1px solid var(--navy);
    border-radius: 8px;
    padding: 0.5rem 1rem;
    cursor: pointer;
    transition: background-color 0.15s ease, opacity 0.15s ease;
}

    button:hover:not(:disabled) {
        background: var(--navy-light);
    }

    button:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }

    button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, a:focus-visible {
        outline: 2px solid var(--cyan);
        outline-offset: 2px;
    }

.btn-outline {
    background: transparent;
    color: var(--navy);
}

.btn-danger {
    background: #fff;
    color: var(--danger);
    border-color: var(--danger);
}

    .btn-danger:hover:not(:disabled) {
        background: var(--danger-bg);
    }

/* Forms */
label {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--muted);
    margin: 0.9rem 0 0.35rem;
}

input, select, textarea {
    font-family: var(--font-body);
    font-size: 0.95rem;
    color: var(--ink);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 0.5rem 0.7rem;
    width: 100%;
    max-width: 26rem;
}

input[type="checkbox"], input[type="color"] {
    width: auto;
    max-width: none;
}

input[type="color"] {
    padding: 0.2rem;
    height: 2.25rem;
}

/* A .field wraps exactly one label + its control, so the gap between a label and its box is the
   same on every form. The bare `label` rule above is the fallback for the forms that still nest
   their input inside the label. */
.field + .field {
    margin-top: 1.1rem;
}

    .field label {
        margin: 0 0 0.4rem;
        color: var(--ink);
    }

    .field input, .field select, .field textarea {
        max-width: none;
        padding: 0.6rem 0.75rem;
    }

/* Pairs up the short fields instead of stacking every form into one long ladder of half-empty
   boxes. The grid gap owns the vertical rhythm, so the .field + .field margin is reset inside. */
.field-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.1rem 1.25rem;
    align-items: start;
}

    .field-grid .field + .field {
        margin-top: 0;
    }

.field-wide {
    grid-column: 1 / -1;
}

.field-hint {
    margin: 0.35rem 0 0;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--muted);
}

/* Password field with an inline show/hide toggle. Global rather than scoped to one page: sign-in
   and the two password-reset pages all use it, and Blazor scoped CSS would style only whichever
   component held the copy. */
.password-wrap {
    position: relative;
}

.password-wrap input {
    /* Room for the toggle so a long password never runs underneath it. */
    padding-right: 4rem;
}

.password-toggle {
    position: absolute;
    top: 50%;
    right: 0.4rem;
    transform: translateY(-50%);
    padding: 0.3rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--cyan-dark);
    background: transparent;
    border: none;
    border-radius: 6px;
}

.password-toggle:hover:not(:disabled) {
    background: rgba(0, 179, 226, 0.12);
}

/* A group of checkboxes, or a set of repeating sub-fields, has no single control to point a
   <label for> at, so the group heading is a span that borrows the same rhythm `.field label`
   gives every other field. */
.field-label {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    margin: 0 0 0.55rem;
    color: var(--ink);
}

/* Lays the sub-fields of one entry side by side — day start / day end / remove, or the two payout
   percentage boxes. Without it they stack, which turns a three-day tournament's editor into a
   ladder of nine full-width boxes. */
.field-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 1rem 1.25rem;
}

    .field-row .field {
        flex: 1 1 12rem;
        margin-top: 0;
    }

    /* The remove button lines up with the inputs beside it rather than their labels. */
    .field-row > button {
        margin-bottom: 0.15rem;
    }

/* One competition day per ruled line. The day number sits in a gutter instead of being repeated
   in both labels, the two boxes are sized to what they actually hold, and a hairline between days
   separates them without nesting a card inside the card the form already is. */
.day-line {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem 1rem;
    padding: 0.85rem 0;
    border-top: 1px solid var(--line);
}

    .day-line:last-of-type {
        border-bottom: 1px solid var(--line);
    }

    .day-line .day-no {
        flex: 0 0 3.2rem;
        padding-bottom: 0.6rem;
        font-size: 0.85rem;
        font-weight: 600;
        color: var(--muted);
    }

    .day-line .field {
        flex: 0 1 15rem;
        margin-top: 0;
    }

    /* A time is half the characters of a date and time, and matching the box beside it only makes
       the row look padded out. */
    .day-line .field-time {
        flex: 0 1 9rem;
    }

    /* Hard right, away from the two boxes: it destroys a day rather than editing one. */
    .day-line > button {
        margin-left: auto;
        margin-bottom: 0.15rem;
    }

/* "Add a day" is the next thing after the last day, not part of it. The gap has to hold up in the
   wrapped case too, where the last day's Remove button drops onto its own line and would otherwise
   sit directly on top of this one — two outlined buttons a few pixels apart read as one control. */
.day-line + button {
    margin-top: 1.5rem;
}

/* A hint that explains a button rather than an input needs the same room the button has above it;
   at the .field-hint default it reads as the button's own caption. */
button + .field-hint {
    margin-top: 0.6rem;
}

/* Pill row under a page heading. Global rather than per-page: Edit.razor links out with it and
   Leaderboard.razor selects a day with it, and CSS isolation would otherwise mean a copy each. */
.sub-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: -0.75rem 0 2rem;
}

    .sub-nav a {
        padding: 0.4rem 0.85rem;
        border: 1px solid var(--line);
        border-radius: 999px;
        background: var(--card);
        font-size: 0.85rem;
        font-weight: 600;
        cursor: pointer;
    }

    .sub-nav a:hover {
        border-color: var(--cyan);
        text-decoration: none;
    }

    /* Where the sub-nav is a selector rather than links elsewhere, which one is on screen has to
       be legible at a glance — otherwise Overall and Day 2 are the same pill. */
    .sub-nav a.active {
        border-color: var(--cyan);
        background: var(--cyan);
        color: var(--card);
    }

@media (max-width: 40rem) {
    .field-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Stacked, the day number has nothing to sit beside, so it becomes the row's heading and the
       Remove button stops trying to hold the right edge of a row that no longer has one. */
    .day-line {
        display: block;
    }

        .day-line .day-no {
            display: block;
            padding-bottom: 0.5rem;
        }

        .day-line .field + .field {
            margin-top: 0.75rem;
        }

        .day-line > button {
            margin-top: 0.9rem;
        }
}

/* Filter controls above a table. They sit on the section heading line, so they drop the
   full-width sizing that inputs get on a form. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

    .filter-bar input, .filter-bar select {
        width: auto;
        max-width: none;
        padding: 0.4rem 0.6rem;
        font-size: 0.85rem;
    }

.filter-search {
    min-width: 14rem;
}

.filter-select {
    min-width: 9rem;
}

/* Buttons sitting side by side need a real gap; the whitespace between them collapses to ~4px. */
.button-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

form button[type="submit"] {
    margin-top: 1.1rem;
}

/* Tables */
table {
    width: 100%;
    border-collapse: collapse;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
}

th, td {
    text-align: left;
    padding: 0.65rem 0.9rem;
    border-bottom: 1px solid var(--line);
}

th {
    font-family: var(--font-display);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    background: rgba(0, 8, 88, 0.04);
}

tbody tr:last-child td {
    border-bottom: none;
}

tbody tr:hover {
    background: rgba(0, 179, 226, 0.06);
}

/* The trailing cell that holds a row's action control. width:1% collapses it to its content so
   the data columns keep the rest of the table. */
.row-actions {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

    .row-actions button {
        padding: 0.35rem 0.75rem;
        font-size: 0.82rem;
    }

/* Cards */
.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 1.25rem 1.5rem;
}

/* Alerts */
.alert {
    border: 1px solid;
    border-radius: 8px;
    padding: 0.85rem 1.1rem;
    margin: 0.75rem 0;
}

.alert-danger {
    border-color: var(--danger);
    background: var(--danger-bg);
    color: var(--danger);
}

.alert-success {
    border-color: var(--success);
    background: var(--success-bg);
    color: var(--success);
}

.alert-warning {
    border-color: var(--warn);
    background: var(--warn-bg);
    color: var(--warn);
}

/* Blazor framework UI */
#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.";
    }

/* The DNR catch report. Laid out to be printed and signed, so it is the one page in the admin
   whose on-screen appearance is a preview of a piece of paper rather than an end in itself. */
.dnr-report {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 0.5rem;
    padding: 1.5rem;
}

.dnr-title {
    margin-top: 0;
    text-align: center;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.dnr-header th, .dnr-header td {
    font-size: 0.85rem;
}

    /* The label half of each pair, not a column heading — it reads as the caption on a form box. */
    .dnr-header th {
        width: 15%;
        color: var(--muted);
        font-weight: 600;
        text-transform: none;
        letter-spacing: 0;
    }

.dnr-grid td, .dnr-grid th {
    font-size: 0.85rem;
}

/* Signature lines, which have to survive onto paper — the DNR wants the permittee's own hand. */
.dnr-signature {
    display: flex;
    gap: 3rem;
    margin-top: 2.5rem;
    font-size: 0.8rem;
    color: var(--muted);
}

    .dnr-signature > div {
        flex: 1;
    }

    .dnr-rule {
        display: block;
        border-bottom: 1px solid var(--ink);
        margin-bottom: 0.35rem;
        height: 2rem;
    }

@media print {
    /* Navigation, buttons and the guidance notes are for the person at the screen; the sheet that
       comes out of the printer is the form. */
    .no-print,
    .site-header,
    .field-hint {
        display: none !important;
    }

    /* The app chrome paints a tinted ground and a card shadow that print as grey boxes. */
    body, .dnr-report {
        background: #fff;
        color: #000;
    }

    /* The main column is centred and padded for a browser window; on paper the margin is the
       printer's job and this would only narrow the table. */
    .app-main {
        max-width: none;
        margin: 0;
        padding: 0;
    }

    .dnr-report {
        border: none;
        padding: 0;
    }

    /* A multi-day event's catch record can run past one page; a row split across the break is
       unreadable and a repeated header is what makes the second page make sense. */
    .dnr-grid tr {
        break-inside: avoid;
    }

    .dnr-grid thead {
        display: table-header-group;
    }
}
