:root {
    /* Single source of truth for gender-based name/initials colours. Used by the
       Members tab (name cells + photo-fallback initials) and the live session
       Attendee Stats names so the two never drift. CSS custom properties inherit
       through the cascade, so Blazor scoped component CSS (PegboardApp.styles.css)
       can read these despite the scoping attribute. */
    --gender-male: #2e6fa9;
    --gender-female: #a85283;
}

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    width: 100%;
    min-height: 100vh;
    margin: 0;
}

a, .btn-link {
    color: #006bb7;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

/* #268: Bootstrap's default .btn-outline-secondary is grey ink + grey border on
   a transparent fill, which reads as a disabled control in our UI - reported on
   End session / Kiosk (full screen) but the washed-out look is shared by every
   outline-secondary button, so fix it at the source. Give it a tangible surface
   and darker ink so it's obviously an active button; genuinely-disabled buttons
   still fade out via Bootstrap's .65 :disabled opacity, restoring the contrast
   between enabled and disabled. */
.btn-outline-secondary {
    color: #2d3540;
    border-color: #97a0aa;
    background-color: #eef1f4;
}

.btn-outline-secondary:hover,
.btn-outline-secondary:focus-visible,
.btn-outline-secondary:active {
    color: #fff;
    background-color: #5a636d;
    border-color: #545d66;
}

.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;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.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."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.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;
}

@media (min-width: 641px) {
    /* In fullscreen the sidebar is hidden by default but stays in the DOM so
       the hamburger overlay (BL-008) can slide it in on demand. The .page--kiosk
       overlay rules in MainLayout.razor.css already handle the open/closed state. */
    body.clubSession-dashboard-fullscreen .content {
        padding-left: 0.35rem !important;
        padding-right: 0.35rem !important;
    }
}

/* BL-008 / #276 / #298: the top bar (hamburger + any status banner) flows
   normally in fullscreen, the same as in every other mode. It used to float as
   an absolute 0-height layer to reclaim a row, but since #298 the status banner
   shares that bar - floating it overlaid the dashboard's own kiosk header
   (hamburger over the session title, banner over the controls; screenshot
   2026-06-09). A normal-flow row sits cleanly above the dashboard header with
   nothing overlapping and the banner still clickable; the profile menu is
   reachable via the hamburger-opened sidebar footer. So: no special fullscreen
   positioning for the top bar. */
body.clubSession-dashboard-fullscreen .clubSession-dashboard-shell {
    min-height: 100vh;
}

.legal-page {
    max-width: 48rem;
    margin: 0 auto;
    padding: 1.5rem 1rem 3rem;
    color: #2a3a4d;
    line-height: 1.55;
}

.legal-page h1 {
    color: #1f3f5e;
    margin: 0 0 0.35rem;
}

.legal-page h2 {
    color: #1f3f5e;
    margin: 1.4rem 0 0.4rem;
    font-size: 1.15rem;
}

.legal-page p,
.legal-page ul {
    margin: 0 0 0.75rem;
}

.legal-page ul {
    padding-left: 1.25rem;
}

.legal-page .legal-meta {
    background: #f6f9fc;
    border: 1px solid #c4d1de;
    border-radius: 0.5rem;
    padding: 0.5rem 0.7rem;
    font-size: 0.9rem;
    color: #4d6177;
}

/* Shared auth-page layout — used by /login, /signup, /forgot-password, /reset-password, /confirm-email.
   Previously scoped to Login.razor.css, which meant the other auth pages rendered unstyled
   (inputs and buttons collapsed against each other). */
/* Shared form markers used across auth + admin forms. */
.required-marker {
    color: #b34040;
    margin-left: 0.1rem;
}

.required-legend {
    margin: 0.4rem 0 0;
    color: #6c7a8c;
    font-size: 0.8rem;
}

.field-hint {
    color: #6c7a8c;
    font-weight: 400;
    font-size: 0.8rem;
    margin-left: 0.25rem;
}

.login-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Top padding 3rem → 1rem so the brand block sits closer to the top
       and the auth card stays in the visible viewport on tablet portrait. */
    padding: 1rem 1.5rem 2rem;
    background:
        radial-gradient(circle at 28% 18%, rgba(140, 190, 240, 0.22) 0%, transparent 55%),
        radial-gradient(circle at 78% 88%, rgba(93, 176, 97, 0.10) 0%, transparent 55%),
        linear-gradient(180deg, #294f76 0%, #1f3d5b 100%);
    margin: -1rem -1.5rem -1rem;
}

/* MainLayout's .content padding goes asymmetric at >=1280px (2rem left,
   1.5rem right). Match that on the left so the gradient bleeds flush. */
@media (min-width: 1280px) {
    .login-shell {
        margin-left: -2rem;
    }
}

.login-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    margin-bottom: 0.75rem;
}

.login-brand-mark {
    font-size: 2.4rem;
    font-weight: 800;
    color: #ffffff;
    letter-spacing: 0.6px;
    line-height: 1;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
}

/* BL-057 (2026-04-26 v6): split assets — figures + wordmark sized
   independently. Mike: "people in the logo are too large vs the text".
   Figures shrunk relative to wordmark; on tablet portrait the form now
   stays in view. Both PNGs are transparent so they sit natively on the
   navy gradient. */
.login-brand-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.login-brand-logo .login-brand-figures {
    display: block;
    height: 3.5rem;
    width: auto;
}

.login-brand-logo .login-brand-wordmark {
    display: block;
    height: 3.5rem;
    width: auto;
    max-width: 100%;
}

.login-brand-tagline {
    color: #cfe1f3;
    font-size: 0.95rem;
    font-weight: 500;
    letter-spacing: 0.2px;
}

.login-card {
    width: min(30rem, 92vw);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 0.85rem;
    background: #ffffff;
    padding: 1.5rem 1.5rem 1.3rem;
    box-shadow: 0 14px 32px rgba(8, 24, 50, 0.34);
}

.login-card h1 {
    margin: 0 0 0.35rem;
    color: #1f3f5e;
}

.login-card .form-control {
    margin-bottom: 0.5rem;
}

.login-help {
    color: #5e748a;
    margin: 0 0 0.8rem;
}

.login-actions {
    margin-top: 1.0rem;
}

.login-signup-link {
    margin-top: 0.75rem;
    color: #4d6177;
    font-size: 0.92rem;
}

.login-signup-link a,
.login-forgot-link a {
    color: #0f4f8b;
    font-weight: 600;
}

.login-forgot-link {
    margin-top: 0.35rem;
    color: #4d6177;
    font-size: 0.9rem;
}

.login-demo-help {
    margin: 0;
    color: #5f7083;
    font-size: 0.85rem;
}

/* #683 (portal S9a): the "email me a code" passwordless block below the password form. */
.login-emailcode {
    margin-top: 0.25rem;
}

.login-emailcode .login-help {
    margin-bottom: 0.5rem;
}

/* #683: off-screen honeypot on the login page (Login.razor reuses the name but the
   Signup scoped style doesn't reach here — provide a global visually-hidden style). */
.login-emailcode .signup-website-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Top-level honeypot hider: the .signup-website-field field must be off-screen ANYWHERE
   the class is used — /forgot-password (ForgotPassword.razor) renders it with no
   .login-emailcode wrapper, so the scoped rule above never reached it and the "Club
   website" honeypot showed (a visible field that real users can fill, rejecting genuine
   requests). This unscoped rule covers every host of the class. */
.signup-website-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.login-error {
    margin-top: 0.75rem;
    border: 1px solid #d88f8f;
    background: #f7e3e3;
    color: #8a2d2d;
    border-radius: 0.5rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.88rem;
}

.login-notice {
    margin-top: 0.75rem;
    border: 1px solid #9ec3e6;
    background: #eaf3fc;
    color: #1c4b78;
    border-radius: 0.5rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.88rem;
}

.login-readonly-field {
    color: #4d6177;
    background: #eef3f8;
}

.legal-page a {
    color: #0f4f8b;
    font-weight: 600;
}

/* MCP track 3 — kiosk PIN UI (settings card + unlock modal + sidebar indicator) */

.kiosk-pin-card {
    border-color: #d7e0ec;
}

.kiosk-pin-status {
    color: #4e6f8e;
    margin-bottom: 0.5rem;
}

.kiosk-pin-form .form-label {
    font-size: 0.85rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.2rem;
}

.kiosk-pin-form input.form-control {
    max-width: 16rem;
    letter-spacing: 0.4em;
    font-family: monospace;
    font-size: 1.05rem;
}

.kiosk-unlock-modal {
    position: fixed;
    inset: 0;
    z-index: 1090;
    display: flex;
    align-items: center;
    justify-content: center;
}

.kiosk-unlock-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(13, 44, 85, 0.45);
}

.kiosk-unlock-dialog {
    position: relative;
    background: #ffffff;
    border-radius: 0.5rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
    padding: 1.25rem 1.4rem;
    max-width: 22rem;
    width: 92%;
}

.kiosk-unlock-dialog h3 {
    font-size: 1.05rem;
    margin-bottom: 0.4rem;
    color: #0d2c55;
}

.kiosk-unlock-dialog input.form-control {
    letter-spacing: 0.4em;
    font-family: monospace;
    font-size: 1.1rem;
}

.kiosk-admin-indicator {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.78rem;
    color: #14532d;
    background: #dcfce7;
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
    margin-left: 0.5rem;
}

.kiosk-admin-indicator-locked {
    color: #6c7a8c;
    background: #f1f5f9;
}

/* Shared password / PIN length-hint styles. Used by /signup, /reset-password,
   and the kiosk PIN setup card so the live feedback pattern is consistent. */
.signup-password-hint {
    font-size: 0.82rem;
    margin-bottom: 0;
}

.signup-password-hint-neutral {
    color: #6c757d;
}

.signup-password-hint-short {
    color: #8a5a00;
}

.signup-password-hint-ok {
    color: #1e7e34;
}

/* Tile-grid bulk session check-in (#194) */
.bulk-check-in-hint {
    color: #4a5870;
    font-size: 0.88rem;
    margin: 0 0 0.6rem 0;
}
/* Single-tap A-Z letter filter for the bulk-add modal (#200) */
.bulk-check-in-letters-special {
    display: flex;
    gap: 0.3rem;
    margin: 0 0 0.4rem 0;
}
/* 26 letters across 13 columns -> exactly two full rows. */
.bulk-check-in-letters {
    display: grid;
    grid-template-columns: repeat(13, 1fr);
    gap: 0.3rem;
    margin: 0 0 0.7rem 0;
}
.bulk-check-in-letter {
    padding: 0.5rem 0.35rem;
    border: 1px solid #c5cfde;
    border-radius: 6px;
    background: #fff;
    color: #1f3f5e;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background 80ms ease, border-color 80ms ease, color 80ms ease;
}
.bulk-check-in-letters-special .bulk-check-in-letter {
    padding-left: 0.9rem;
    padding-right: 0.9rem;
}
.bulk-check-in-letter:hover:not(:disabled) {
    border-color: #2962ff;
    background: #f4f8ff;
}
.bulk-check-in-letter.active {
    background: #2962ff;
    border-color: #2962ff;
    color: #fff;
}
.bulk-check-in-letter:disabled {
    opacity: 0.3;
    cursor: default;
}
.bulk-check-in-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
    grid-auto-rows: min-content;
    gap: 0.5rem;
    /* FIXED height (not min/max) so the pane is exactly the same size whether the
       filter shows 1 tile or 50 - it never shrinks/shifts when you pick a letter
       (#200 feedback). Tiles top-align; the list scrolls inside when long. */
    height: 50vh;
    overflow-y: auto;
    align-content: start;
}
.bulk-check-in-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 0.5rem 0.3rem;
    border: 1px solid #c5cfde;
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
    position: relative;
    text-align: center;
    transition: border-color 80ms ease, background 80ms ease, box-shadow 80ms ease;
}
/* Tone each tile by gender, matching the waiting-queue chips (blue = men, pink =
   women). The gender tone is KEPT through hover AND selection — interaction is shown
   with a shadow / ring (+ the check glyph), NOT by replacing the gender background,
   which would wash every tile blue regardless of gender. */
.bulk-check-in-tile.gender-male {
    background: #dfeeff;
    border-color: #8fb6e0;
}
.bulk-check-in-tile.gender-female {
    background: #ffe4f3;
    border-color: #e3a4c7;
}
.bulk-check-in-tile:hover {
    box-shadow: 0 2px 6px rgba(13, 44, 85, 0.18);
}
.bulk-check-in-tile.selected {
    box-shadow: inset 0 0 0 2px #2962ff;
}
.bulk-check-in-tile:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}
.bulk-check-in-tile-photo {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    object-fit: cover;
    background: #e6ebf3;
}
.bulk-check-in-tile-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 1rem;
    color: #4a5870;
}
.bulk-check-in-tile-name {
    font-size: 0.78rem;
    line-height: 1.1;
    color: #28344a;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    word-break: break-word;
}
.bulk-check-in-tile-check {
    position: absolute;
    top: 0.2rem;
    right: 0.3rem;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    background: #2962ff;
    color: #fff;
    font-size: 0.72rem;
    line-height: 1.1rem;
    text-align: center;
}

/* CSV import self-service panel on Members (#95) */
.member-import-panel {
    border: 1px solid #c5cfde;
    border-radius: 8px;
    background: #f8fafc;
    padding: 1rem 1.2rem;
    margin: 0.5rem 0 1rem 0;
}
.member-import-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.member-import-input-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0.5rem 0;
    flex-wrap: wrap;
}
.member-import-file-btn {
    position: relative;
    overflow: hidden;
    cursor: pointer;
    margin: 0;
}
.member-import-file-input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
    width: 100%;
    height: 100%;
}
.member-import-file-name {
    font-size: 0.85rem;
    color: #4a5870;
    word-break: break-all;
}
.member-import-textarea {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85rem;
}
.member-import-summary {
    font-size: 0.9rem;
}
.member-import-preview {
    max-height: 22rem;
    overflow-y: auto;
}

/* #393: the floating "Feedback" button (.quick-feedback-fab, position:fixed bottom-right,
   z-index 1900) sat on top of the score-entry popover and its Save control, obscuring score
   entry during a live session. Hide it whenever an overlay that the operator is actively
   working in is open - the score-entry popover (which renders .score-combo-backdrop) or any
   Bootstrap-style modal (.modal.show). The Feedback button reappears once the overlay closes. */
body:has(.score-combo-backdrop) .quick-feedback-fab,
body:has(.modal.show) .quick-feedback-fab {
    display: none !important;
}
