html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

/* Bootstrap colours inactive tab (.nav-link) text with its default link blue
   (#0d6efd), which doesn't match the site palette. Align it to our link/green. */
.nav-tabs {
    --bs-nav-link-color: #0071c1;
    --bs-nav-link-hover-color: #004A33;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
    /* Breathing room so the last element on a page isn't flush against the bottom edge. */
    padding-bottom: 2.5rem;
}

/* Score table: the page becomes a viewport-tall flex column so ONLY the table
   region scrolls (one scrollbar, not two), and its header freezes at the top —
   so on a small screen you keep track of which column is which while scrolling. */
/* Make the whole shell a viewport-tall flex column while the score page is mounted,
   so ONLY the table region scrolls (one scrollbar, not two) and the sticky header
   stays put. Scoped with :has() so it applies only on the score page and needs no
   magic offset — MainLayout banners (pending-apps / unpaid) above @Body just take
   their space and the table region fills what's left (a fixed 100dvh − Nrem calc
   didn't account for those banners and reintroduced the double scrollbar). */
.page:has(.score-page) {
    height: 100dvh;
    overflow: hidden;
}
.page:has(.score-page) main {
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0;
}
/* Only the grid region gives up space; everything above it keeps its natural height.
   As flex items in the column these default to flex-shrink:1, so once the riders
   loaded and the column wanted more than 100dvh, the browser took the difference out
   of the 3.5rem top row — it loaded correct, then visibly shrank and went cramped. */
.page:has(.score-page) .top-row,
.page:has(.score-page) .content > .alert {
    flex: 0 0 auto;
}
.page:has(.score-page) .content {
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
    overflow: hidden;
    /* The article must itself be a flex column, or .score-page's flex sizing
       is inert and the overflow simply CLIPS - no scrollbar at all. */
    display: flex;
    flex-direction: column;
}
.score-page {
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    /* The grid below trims its columns on the width IT has, not the window's. Keyed
       to the viewport it broke twice over: the sidebar returns at 641px, so between
       641 and 700 the grid was squeezed into a narrow column at full width; and above
       700 every column came back even when the sidebar had left it no room. */
    container: wsc-score / inline-size;
}
.score-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}
/* Ringside quick-add strip. Sits below .score-scroll (never inside it) so it stays
   on screen at any scroll position and its typeahead lists aren't clipped by the
   grid's overflow. Collapsed behind a button by default — see _addOpen. */
.score-addbar {
    border-top: 1px solid #dee2e6;
    padding-top: 0.5rem;
}
.score-addfield {
    min-width: 10rem;
    flex: 0 1 12rem;
}

/* Scoring on a phone. The grid carries up to a dozen columns, so the generic
   scroll-sideways rule left you seeing Rider/Horse and nothing else. It stays a
   TABLE — a scorer works down a list and wants several riders in view at once —
   but drops to the columns that are actually used at the ringside and tightens
   the spacing. Everything hidden here (horse, category, test, collectives, the
   jump-off detail, manual TB, sub-league) is set on the start list or on a
   desktop; nothing is only reachable on a phone. Keyed to the GRID's width via a
   container query, not the window's, so the sidebar can't push it out of step. */
@container wsc-score (max-width: 700px) {
    table.score-grid th.col-secondary,
    table.score-grid td.col-secondary { display: none; }

    table.score-grid { font-size: 0.9rem; }
    table.score-grid th,
    table.score-grid td { padding: 0.3rem 0.35rem; }
    table.score-grid td .form-select,
    table.score-grid td .form-control { min-width: 0 !important; }
    /* ...except Status, which collapsed to an empty box you had to open to read.
       Enough width to show the value, truncating rather than vanishing. */
    table.score-grid td[data-label="Status"] .form-select {
        min-width: 5.5rem !important;
        padding-left: 0.35rem;
        padding-right: 1.1rem;
    }
    /* The rider is what you scan down, so give it the room the dropped columns
       freed and let a long name wrap rather than squeezing the score box. */
    table.score-grid td.cell-rider {
        white-space: normal;
        font-weight: 600;
        min-width: 6rem;
    }

    /* The Manual TB note explains a column that isn't shown here. */
    .score-note { display: none; }

    /* The add panel's fields go full width rather than three cramped columns. */
    .score-addfield { flex: 1 1 100%; min-width: 0; }
    .score-actions .btn { flex: 1 1 auto; }
}
/* The account bar is a whole row of screen for a name and a Log out button,
   neither of which is any use mid-class; the menu still reaches both. A MEDIA
   query, not the container query above: .top-row is a sibling of .content and so
   sits outside .score-page, and @container only ever styles a container's own
   descendants — inside that block this rule silently matched nothing. */
@media (max-width: 700px) {
    .page:has(.score-page) main > .top-row { display: none; }
}

.score-scroll thead th {
    position: sticky;
    top: 0;
    z-index: 3;
    background-color: #fff;
    box-shadow: inset 0 -2px 0 #dee2e6;
}

/* Test sheet totals bar. Figure over label, centred: the numbers are what's read
   at a glance while marking, so they get the size, and stacking the label under
   each one keeps the whole bar on a single line — set beside their labels at this
   size they wrapped onto a second row. */
.sheet-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.15;
}
/* One size and weight for EVERY figure, percentage included. Sizing the
   percentage up put it on a different baseline from the rest, so the row of
   numbers stepped up and down instead of reading as one line. */
.sheet-stat-value {
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
}
.sheet-stat-label {
    font-size: 0.72rem;
    color: #6c757d;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
/* The "/ 230" denominator is context, not a figure in its own right. */
.sheet-stat-of {
    font-size: 0.9rem;
    font-weight: 400;
    color: #6c757d;
}

/* Sub-league tints for the scoring grid's Pos/Pts cells — bronze/silver/gold
   match the league names; the rest are soft, distinct pastels. */
.sl-bronze { background-color: #e9cfae !important; }
.sl-silver { background-color: #e0e0e0 !important; }
.sl-gold   { background-color: #f7e08a !important; }
.sl-staff  { background-color: #cfdce8 !important; }
.sl-ol     { background-color: #d7e8d4 !important; }
.sl-school { background-color: #e6d9f2 !important; }
.sl-do     { background-color: #cfe8e5 !important; }

/* Past events in the list view — a light grey wash so they read as history
   when shown alongside upcoming ones. */
.event-past {
    background-color: #f1f3f5;
}
.event-past .event-title strong {
    color: #6c757d;
}

/* Device-specific UI. touch-only = phones/tablets, where a file input's capture
   attribute hands off to the native camera app. desktop-only = mouse devices,
   where the camera needs the in-page webcam (getUserMedia) route instead. */
.desktop-only { display: none !important; }
@media (hover: hover) and (pointer: fine) {
    .touch-only { display: none !important; }
    .desktop-only { display: inline-block !important; }
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

/* Club-branded version of Blazor's unhandled-error banner (see index.html).
   Dark green to match the boot screen and the site header, rather than the
   stock lightyellow. color-scheme is pinned so a dark-mode browser can't
   invert the colours we set here. */
#blazor-error-ui {
    color-scheme: light only;
    background: #14342a;
    color: #fff;
    border-top: 3px solid #14663f;
    bottom: 0;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.25);
    box-sizing: border-box;
    display: none;
    font-size: 0.95rem;
    left: 0;
    line-height: 1.5;
    padding: 0.75rem 2.75rem 0.85rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui a {
        color: #9fe0bd;
        font-weight: 600;
    }

    #blazor-error-ui .reload {
        margin-left: 0.5rem;
        white-space: nowrap;
    }

    #blazor-error-ui .dismiss {
        color: #fff;
        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: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        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;
}

/* ===== Wellington Saddle Club branding ===== */
:root {
    --wsc-green: #004A33;
    --wsc-green-dark: #003322;
    --wsc-green-light: #1f6b50;
}

a, .btn-link { color: var(--wsc-green); }
a:hover { color: var(--wsc-green-dark); }

h1, h2, h3 { color: var(--wsc-green); }

.btn-primary {
    background-color: var(--wsc-green);
    border-color: var(--wsc-green-dark);
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
    background-color: var(--wsc-green-dark) !important;
    border-color: var(--wsc-green-dark) !important;
}
.btn-outline-primary { color: var(--wsc-green); border-color: var(--wsc-green); }
.btn-outline-primary:hover { background-color: var(--wsc-green); border-color: var(--wsc-green); color: #fff; }

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem var(--wsc-green-light);
}

.form-check-input:checked { background-color: var(--wsc-green); border-color: var(--wsc-green); }

table thead th { color: var(--wsc-green); }

.loading-progress circle:last-child { stroke: var(--wsc-green); }

.wsc-login-logo { display: block; max-width: 220px; height: auto; margin: 0 0 1rem; }
.rosette { color: #b8860b; font-weight: 700; }

.login-title { margin: -0.25rem 0 0.75rem; font-weight: 700; }

/* Rich text (Quill) editor for committee minutes. The editable area grows with the
   viewport and scrolls INSIDE itself, so the toolbar (above) and Save buttons (below)
   stay visible on long minutes without the page needing to scroll. The min-height is
   the practical floor on short screens (below which two scrollbars are unavoidable). */
.wsc-rte { max-width: 100%; }
/* The editable area's max-height is set by JS (wscQuill.fit) to the real available
   space; min-height is the floor on short screens. */
.wsc-rte .ql-editor {
    min-height: 10rem;
    overflow-y: auto;
    font-size: 1rem;
}
/* Read-only minutes view scrolls internally too, keeping the Print/Word buttons in view. */
.wsc-rte-view {
    max-height: calc(100vh - 20rem);
    overflow-y: auto;
}
.wsc-rte-view :is(h1,h2,h3) { font-size: 1.15rem; font-weight: 700; margin: .6rem 0 .3rem; }
.wsc-rte-view ul, .wsc-rte-view ol { padding-left: 1.4rem; }
.wsc-rte-view blockquote {
    margin: .5rem 0;
    padding: .25rem 0 .25rem .9rem;
    border-left: 3px solid #ccc;
    color: #555;
}

/* Centre the login / sign-up column on the page. Each block (logo, title, text,
   card) has its own max-width, so margin auto centres them in the content area. */
.auth-page { margin-top: 1.5rem; }
.auth-page > * { margin-left: auto; margin-right: auto; }
.auth-page .login-title { text-align: center; }

.calendar-cell { height: 5.5rem; vertical-align: top; overflow: hidden; }
.calendar-other { background-color: #f8f9fa; }
.calendar-cell a { color: var(--wsc-green); text-decoration: none; }
.calendar-cell a:hover { text-decoration: underline; }

/* Home dashboard — tap tiles for every feature the signed-in user can reach, so
   nothing important is hidden behind the (collapsed-on-mobile) menu. */
.dash-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75rem;
    max-width: 52rem;
}
.dash-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    text-align: center;
    min-height: 6.5rem;
    padding: 1rem 0.75rem;
    border: 1px solid #e2e2e2;
    border-radius: 0.6rem;
    background: #fff;
    color: var(--wsc-green);
    text-decoration: none;
    box-shadow: 0 1px 2px rgba(0,0,0,.05);
    transition: transform .06s ease, box-shadow .12s ease, border-color .12s ease;
}
.dash-tile:hover, .dash-tile:focus {
    border-color: var(--wsc-green);
    box-shadow: 0 3px 8px rgba(0,0,0,.12);
    color: var(--wsc-green-dark);
    transform: translateY(-1px);
}
.dash-tile:active { transform: translateY(0); }
.dash-icon { font-size: 1.9rem; line-height: 1; }
.dash-label { font-weight: 600; font-size: 0.95rem; }
.dash-tile-admin { background: #f6f9f7; }
.dash-badge { position: absolute; top: 0.5rem; right: 0.5rem; }
.dash-divider {
    display: flex;
    align-items: center;
    text-align: center;
    color: #888;
    margin: 1.5rem 0 0.9rem;
    max-width: 52rem;
}
.dash-divider::before, .dash-divider::after { content: ""; flex: 1; border-bottom: 1px solid #ddd; }
.dash-divider span {
    padding: 0 0.75rem;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
@media (min-width: 700px) {
    .dash-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Events list rows — robust on narrow phones. Title + badges wrap together on top,
   date/time/type sit on a muted line below, and the action buttons drop to their own
   full-width line rather than squashing into a centred jumble. */
.event-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
}
.event-row-clickable { cursor: pointer; }
.event-main { flex: 1 1 16rem; min-width: 0; }
.event-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.5rem;
}
.event-title .badge { font-weight: 600; }
.event-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.1rem 0.6rem;
    margin-top: 0.15rem;
}
.event-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-left: auto;
}
/* Uniform-width primary buttons so Start list / Score / Minutes align in neat columns
   across rows (the icon-only delete button keeps its natural size). */
.event-actions .btn:not(.btn-link) { min-width: 5.25rem; }
/* Always reserve the trailing delete slot for admins so its presence/absence on a row
   (finalised events have none) doesn't shift the other buttons out of alignment. */
.event-delete-slot {
    flex: 0 0 auto;
    width: 1.1rem;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
}
@media (max-width: 575.98px) {
    .event-actions { margin-left: 0; width: 100%; }
}

/* Public home / landing page */
.home-hero { position: relative; border-radius: 0.5rem; overflow: hidden; margin-bottom: 1.75rem; }
.home-hero-img { width: 100%; height: 340px; object-fit: cover; display: block; filter: brightness(0.55); }
.home-hero-overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; color: #fff; padding: 1rem; }
.home-hero-logo { width: 84px; height: auto; margin-bottom: 0.5rem; background: #fff; border-radius: 50%; padding: 5px; }
.home-hero-title { color: #fff !important; margin: 0; font-weight: 700; }
.home-hero-tagline { font-size: 1.15rem; margin: 0.25rem 0 1.1rem; }
.home-hero-actions { display: flex; gap: 0.75rem; flex-wrap: wrap; justify-content: center; }
.home-section { max-width: 52rem; margin: 0 auto 1.75rem; }

/* Home calendar: let event cells grow and wrap so names are fully readable. */
.home-calendar .calendar-cell { height: auto; min-height: 2.5rem; overflow: visible; padding: 0.35rem 0.5rem; vertical-align: top; }
.home-cal-event { white-space: normal; overflow-wrap: anywhere; line-height: 1.2; }

.login-or { display: flex; align-items: center; text-align: center; color: #888; margin: 1.25rem 0; }
.login-or::before, .login-or::after { content: ""; flex: 1; border-bottom: 1px solid #ddd; }
.login-or span { padding: 0 0.75rem; font-size: 0.85rem; font-weight: 600; }

/* Mobile: let any wide table scroll sideways instead of breaking the layout. */
@media (max-width: 700px) {
    .table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
    }
    .wsc-login-logo { max-width: 170px; }
}
/* Click-to-sort tables (see wscSortable in interop.js) */
table.js-sortable thead th:not([data-nosort]) {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
table.js-sortable thead th:not([data-nosort]):hover {
    text-decoration: underline;
}
.sort-ind {
    opacity: 0.8;
    font-size: 0.8em;
}
/* Start list "Add entry" on a phone. Below Bootstrap's sm breakpoint the fields
   stack full width, which put each label on its own line — three labels and three
   controls filled the screen before you reached the start list itself. Pair each
   label with its control on one line instead. */
@media (max-width: 575.98px) {
    .entry-add .entry-add-field {
        display: flex;
        align-items: center;
        gap: 0.5rem;
    }
    .entry-add .entry-add-field > .form-label {
        flex: 0 0 4.75rem;
        margin-bottom: 0;
    }
    .entry-add .entry-add-field > .wsc-combo,
    .entry-add .entry-add-field > .form-control {
        flex: 1 1 auto;
        min-width: 0;
        width: auto;
    }
}
.entry-add-bar { width: 6rem; }

/* Start-list running order: the time column. "17:00" is five characters, so on a
   phone the 5.5rem column was spending width the Rider and Horse columns needed —
   they were being cut off at the screen edge while the time sat in whitespace. */
.col-start-time { width: 5.5rem; }
.start-time-input { width: 5rem; }
@media (max-width: 700px) {
    .col-start-time { width: 4.1rem; }
    .start-time-input {
        width: 4.1rem;
        padding-left: 0.3rem;
        padding-right: 0.3rem;
        text-align: center;
    }
}

/* Drag-to-reorder handle (start list rows) */
.drag-handle {
    cursor: grab;
    color: #adb5bd;
    touch-action: none; /* let SortableJS own the drag gesture on touch */
    user-select: none;
}
.drag-handle:hover { color: #6c757d; }
.drag-handle:active { cursor: grabbing; }
.sortable-ghost { opacity: 0.4; }
.sortable-chosen { background: #eef4ff; }

/* ComboBox typeahead */
.wsc-combo { position: relative; }
.wsc-combo-list {
    position: absolute;
    z-index: 1050;
    left: 0; right: 0;
    background: #fff;
    border: 1px solid #ced4da;
    border-radius: 0.375rem;
    max-height: 14rem;
    overflow-y: auto;
    box-shadow: 0 0.25rem 0.5rem rgba(0,0,0,.15);
}
.wsc-combo-item {
    padding: 0.35rem 0.75rem;
    cursor: pointer;
    font-size: 0.875rem;
    line-height: 1.4;
}
.wsc-combo-item:hover,
.wsc-combo-item.active {
    background: #1b6ec2;
    color: #fff;
}
.wsc-combo-list-up {
    bottom: 100%;
    top: auto;
}

/* A cancelled event stays in the list — greyed back so it reads as "was on, isn't
   now" rather than competing with the events that are still going ahead. */
.event-cancelled {
    background-color: #f8f9fa;
    opacity: 0.75;
}

/* Test sheet: the live totals card. On desktop the top bar is sticky and
   3.5rem tall, so the card parks just below it instead of sliding underneath;
   on phones the bar scrolls away and the card can hug the top. */
.sheet-totals {
    position: sticky;
    top: 0.5rem;
    z-index: 5;
    max-width: 30rem;
}
@media (min-width: 641px) {
    .sheet-totals { top: 4rem; }
}
