/* =====================================================================
   Gym Management — slate & amber theme (light + dark)
   Style copied from the approved dashboard mockup:
   dark slate surfaces, amber-400 accent, glassy rounded-2xl cards,
   translucent pill badges, custom scrollbar.
   ===================================================================== */

:root {
    /* Re-point Bootstrap's primary palette at amber so utilities like
       bg-primary + bg-opacity-* and text-primary keep working natively. */
    --bs-primary: #f59e0b;
    --bs-primary-rgb: 245, 158, 11;
    --bs-primary-bg-subtle: #fef3c7;
    --bs-primary-text-emphasis: #92400e;

    --accent: #f59e0b;              /* amber-500: readable on light bg */
    --accent-strong: #d97706;
    --accent-contrast: #0f172a;     /* dark slate text on amber buttons */
    --accent-soft: rgba(245, 158, 11, 0.12);
    --accent-border: rgba(245, 158, 11, 0.35);

    --app-bg: #f1f5f9;
    --card-bg: #ffffff;
    --card-border: #e2e8f0;
    --card-header-bg: #ffffff;
    --text-main: #1e293b;
    --text-muted: #64748b;
    --topbar-bg: #ffffff;
    --topbar-border: #e2e8f0;
    --chip-bg: #f8fafc;
    --chip-border: #e2e8f0;
    --thead-bg: #f8fafc;
    --thead-color: #64748b;
    --row-border: #eef2f7;
    --row-hover: #f8fafc;
    --scroll-track: #e2e8f0;
    --scroll-thumb: #cbd5e1;

    --sidebar-bg: #ffffff;
    --sidebar-shadow: 0 0 20px rgba(15, 23, 42, 0.05);
    --sidebar-border: #e2e8f0;
    --sidebar-divider: #eef2f7;
    --sidebar-brand: #0f172a;
    --sidebar-section: #94a3b8;
    --sidebar-text: #475569;
    --sidebar-icon: #94a3b8;
    --sidebar-hover-bg: #f1f5f9;
    --sidebar-hover-text: #0f172a;
    --sidebar-active-text: #b45309;
    --logout-color: #dc2626;
    --logout-border: rgba(220, 38, 38, 0.35);

    --radius: 1rem;                 /* rounded-2xl */
    --card-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 16px rgba(15, 23, 42, 0.06);
}

[data-bs-theme="dark"] {
    --bs-primary: #fbbf24;
    --bs-primary-rgb: 251, 191, 36;
    --bs-primary-bg-subtle: rgba(251, 191, 36, 0.15);
    --bs-primary-text-emphasis: #fcd34d;

    --accent: #fbbf24;              /* amber-400 as in the mockup */
    --accent-strong: #f59e0b;
    --accent-contrast: #0f172a;
    --accent-soft: rgba(251, 191, 36, 0.1);
    --accent-border: rgba(251, 191, 36, 0.25);

    --app-bg: #0f172a;              /* slate-900 */
    --card-bg: #1a2436;             /* solid slate-800/70-equivalent: cheap to scroll */
    --card-border: rgba(51, 65, 85, 0.4);
    --card-header-bg: transparent;
    --text-main: #e2e8f0;
    --text-muted: #94a3b8;
    --topbar-bg: #16202f;
    --topbar-border: rgba(51, 65, 85, 0.4);
    --chip-bg: rgba(51, 65, 85, 0.3);
    --chip-border: rgba(71, 85, 105, 0.3);
    --thead-bg: transparent;
    --thead-color: #94a3b8;
    --row-border: rgba(51, 65, 85, 0.3);
    --row-hover: rgba(51, 65, 85, 0.2);
    --scroll-track: #1e293b;
    --scroll-thumb: #facc15;

    --sidebar-bg: linear-gradient(180deg, rgba(30, 41, 59, 0.97) 0%, #0f172a 100%);
    --sidebar-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
    --sidebar-border: rgba(51, 65, 85, 0.5);
    --sidebar-divider: rgba(148, 163, 184, 0.15);
    --sidebar-brand: #ffffff;
    --sidebar-section: #64748b;
    --sidebar-text: #cbd5e1;
    --sidebar-icon: #94a3b8;
    --sidebar-hover-bg: rgba(51, 65, 85, 0.5);
    --sidebar-hover-text: #ffffff;
    --sidebar-active-text: #fbbf24;
    --logout-color: #fca5a5;
    --logout-border: rgba(252, 165, 165, 0.35);

    --card-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}

body {
    background-color: var(--app-bg);
    font-family: "Tajawal", "Segoe UI", Tahoma, Arial, sans-serif;
    color: var(--text-main);
}

/* Custom scrollbar (from the mockup) */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--scroll-track); }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 20px; }

/* ------------------------------------------------------------------ */
/* Bootstrap re-skin: amber accent                                     */
/* ------------------------------------------------------------------ */

.btn-primary {
    --bs-btn-bg: var(--accent);
    --bs-btn-border-color: var(--accent);
    --bs-btn-color: var(--accent-contrast);
    --bs-btn-hover-bg: var(--accent-strong);
    --bs-btn-hover-border-color: var(--accent-strong);
    --bs-btn-hover-color: var(--accent-contrast);
    --bs-btn-active-bg: var(--accent-strong);
    --bs-btn-active-border-color: var(--accent-strong);
    --bs-btn-active-color: var(--accent-contrast);
    font-weight: 700;
}

.btn-outline-primary {
    --bs-btn-color: var(--accent);
    --bs-btn-border-color: var(--accent-border);
    --bs-btn-hover-bg: var(--accent);
    --bs-btn-hover-border-color: var(--accent);
    --bs-btn-hover-color: var(--accent-contrast);
    --bs-btn-active-bg: var(--accent);
    --bs-btn-active-border-color: var(--accent);
    --bs-btn-active-color: var(--accent-contrast);
}

/* Solid amber badges need dark text for contrast (dark mode has its own
   translucent override further down). */
.badge.bg-primary { color: #0f172a; }

a { color: var(--accent-strong); }
[data-bs-theme="dark"] a { color: var(--accent); }

.form-control:focus,
.form-select:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 0.2rem rgba(251, 191, 36, 0.2);
}

.page-link { color: var(--accent-strong); }
.page-item.active .page-link {
    background-color: var(--accent);
    border-color: var(--accent);
    color: var(--accent-contrast);
}

/* ------------------------------------------------------------------ */
/* Sidebar — dark slate in both themes, amber active pill              */
/* ------------------------------------------------------------------ */

.sidebar {
    width: 258px;
    min-height: 100vh;
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    z-index: 1045;
    /* Logical property: renders on the edge facing the content in both
       directions (left in RTL, right in LTR) without a language-specific rule. */
    border-inline-end: 1px solid var(--sidebar-border);
    box-shadow: var(--sidebar-shadow);
}

.sidebar .sidebar-brand,
[data-bs-theme="dark"] .sidebar .sidebar-brand { color: var(--sidebar-brand); }

.brand-icon {
    width: 40px;
    height: 40px;
    border-radius: 0.75rem;
    background: #fbbf24;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    color: #0f172a;
    box-shadow: 0 10px 15px rgba(251, 191, 36, 0.2);
}

/* A real uploaded club logo replaces the amber dumbbell box: plain white
   background (arbitrary logo colors clash with amber) and a little padding
   so the image doesn't touch the rounded corners. */
.brand-icon.has-logo,
.login-icon.has-logo {
    background: #fff;
    box-shadow: none;
    padding: 4px;
}

.brand-icon img,
.login-icon img {
    max-width: 100%;
    max-height: 100%;
}

.sidebar-divider {
    height: 1px;
    margin: 0 1rem;
    background: var(--sidebar-divider);
}

.sidebar-section {
    list-style: none;
    font-size: 0.72rem;
    letter-spacing: 0.5px;
    color: var(--sidebar-section);
    font-weight: 700;
    padding: 0.9rem 0.9rem 0.35rem;
    text-transform: uppercase;
}

.sidebar .nav-link {
    color: var(--sidebar-text);
    border-radius: 0.75rem;
    border: 1px solid transparent;
    margin-bottom: 0.2rem;
    padding: 0.6rem 1rem;
    font-weight: 500;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.sidebar .nav-link i { color: var(--sidebar-icon); transition: color 0.15s ease; }

.sidebar .nav-link:hover {
    color: var(--sidebar-hover-text);
    background-color: var(--sidebar-hover-bg);
}

.sidebar .nav-link:hover i { color: var(--accent); }

.sidebar .nav-link.active {
    background-color: var(--accent-soft);
    color: var(--sidebar-active-text);
    border-color: var(--accent-border);
    box-shadow: 0 10px 15px rgba(251, 191, 36, 0.05);
    font-weight: 700;
}

.sidebar .nav-link.active i { color: var(--sidebar-active-text); }

.btn-logout {
    color: var(--logout-color);
    border: 1px solid var(--logout-border);
    border-radius: 0.75rem;
    font-weight: 500;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.btn-logout:hover {
    background-color: #dc2626;
    border-color: #dc2626;
    color: #fff;
}

/* Mobile: off-canvas drawer + backdrop */
.sidebar-backdrop { display: none; }

@media (max-width: 991.98px) {
    .sidebar {
        position: fixed;
        top: 0;
        /* Logical inset: resolves to `right` in RTL (current behaviour) and
           `left` in LTR, so the drawer hides/slides from the correct edge
           in French without a separate rule. */
        inset-inline-start: -270px;
        transition: inset-inline-start 0.25s ease;
    }

    .sidebar.show { inset-inline-start: 0; }

    .sidebar-backdrop.show {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, 0.6);
        z-index: 1040;
    }
}

/* ------------------------------------------------------------------ */
/* Topbar                                                              */
/* ------------------------------------------------------------------ */

/* The content column must be allowed to be narrower than what is inside it.
   A flex item defaults to min-width:auto, which means "never shrink below my
   content" — so one wide table (members, subscriptions, payments) stretched
   this whole column past the screen. On a phone the result was a page that
   scrolled sideways underneath a sticky header that stayed where it was, so
   the header no longer lined up with anything. Pages built from cards, like
   the dashboard and the attendance screen, fit and looked fine, which is
   what made it look like only "some" pages were broken.
   With min-width:0 the column stops at the screen edge and .table-responsive
   finally does its job: the table scrolls inside its own box. */
#main-content,
#main-content > main {
    min-width: 0;
}

.topbar {
    /* Solid background — backdrop blur on a sticky bar repaints on every
       scroll frame and makes scrolling feel sluggish. */
    background: var(--topbar-bg);
    border-bottom: 1px solid var(--topbar-border);
    min-height: 64px;
}

.topbar-title {
    font-weight: 800;
    font-size: 1.15rem;
    color: var(--text-main);
}

.btn-icon {
    border: none;
    background: transparent;
    color: var(--text-muted);
}

.btn-icon:hover { color: var(--accent); }

.theme-toggle { font-size: 1.25rem; }

/* Language switcher: two small pill buttons, active one filled with the accent. */
.lang-switch {
    background: var(--chip-bg);
    border: 1px solid var(--chip-border);
    border-radius: 50rem;
    padding: 2px;
    gap: 2px;
}

.lang-btn {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 700;
    padding: 0.25rem 0.65rem;
    border-radius: 50rem;
    line-height: 1.4;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.lang-btn:hover { color: var(--text-main); }

.lang-btn.active {
    background: var(--accent);
    color: var(--accent-contrast);
}

.user-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--chip-bg);
    border: 1px solid var(--chip-border);
    border-radius: 50rem;
    padding-block: 0.3rem;
    /* Logical padding: the avatar sits at the start edge in both directions,
       so the asymmetry (more room near the avatar) follows it automatically. */
    padding-inline-start: 0.9rem;
    padding-inline-end: 0.6rem;
    font-weight: 500;
    color: var(--text-main);
}

.role-badge { font-size: 0.7rem; }

/* ------------------------------------------------------------------ */
/* Avatars — amber gradient with dark text (mockup style)              */
/* ------------------------------------------------------------------ */

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, #fcd34d 0%, #f59e0b 100%);
    color: #0f172a;
    font-weight: 800;
    flex-shrink: 0;
    box-shadow: 0 4px 10px rgba(251, 191, 36, 0.2);
}

.avatar-sm { width: 30px; height: 30px; font-size: 0.85rem; }

.avatar-lg { width: 110px; height: 110px; font-size: 2.6rem; }

/* ------------------------------------------------------------------ */
/* Cards & tables                                                      */
/* ------------------------------------------------------------------ */

.card {
    border: 1px solid var(--card-border);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
    background-color: var(--card-bg);
}


.card-header {
    background-color: var(--card-header-bg);
    border-bottom: 1px solid var(--row-border);
    border-radius: var(--radius) var(--radius) 0 0 !important;
    padding: 0.9rem 1.25rem;
    color: var(--text-main);
}

.stat-card .card-body {
    /* Text on one edge, icon on the other — icons line up across cards. */
    justify-content: space-between;
    gap: 1rem;
}

.stat-card .stat-icon {
    width: 52px;
    height: 52px;
    border-radius: 1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    flex-shrink: 0;
}

.stat-card {
    /* Animate transform only — box-shadow transitions trigger repaints. */
    transition: transform 0.15s ease;
}

.stat-card:hover {
    transform: translateY(-3px);
}

/* Stat icon palette — translucent tint + vivid glyph, per theme
   (mirrors the mockup's bg-*-400/10 + text-*-400 pattern). */
.si-amber { background: rgba(245, 158, 11, 0.12); color: #d97706; }
.si-emerald { background: rgba(16, 185, 129, 0.12); color: #059669; }
.si-sky { background: rgba(14, 165, 233, 0.12); color: #0284c7; }
.si-orange { background: rgba(249, 115, 22, 0.12); color: #ea580c; }
.si-rose { background: rgba(244, 63, 94, 0.1); color: #e11d48; }
.si-violet { background: #ede9fe; color: #7c3aed; }

[data-bs-theme="dark"] .si-amber { background: rgba(251, 191, 36, 0.1); color: #fbbf24; }
[data-bs-theme="dark"] .si-emerald { background: rgba(52, 211, 153, 0.1); color: #34d399; }
[data-bs-theme="dark"] .si-sky { background: rgba(56, 189, 248, 0.1); color: #38bdf8; }
[data-bs-theme="dark"] .si-orange { background: rgba(251, 146, 60, 0.1); color: #fb923c; }
[data-bs-theme="dark"] .si-rose { background: rgba(251, 113, 133, 0.1); color: #fb7185; }
[data-bs-theme="dark"] .si-violet { background: rgba(167, 139, 250, 0.1); color: #a78bfa; }

.table {
    --bs-table-bg: transparent;
    --bs-table-hover-bg: var(--row-hover);
    color: var(--text-main);
}

.table thead th {
    background-color: var(--thead-bg);
    color: var(--thead-color);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    white-space: nowrap;
    border-bottom: 1px solid var(--card-border);
}

.table td { border-color: var(--row-border); }

.badge {
    font-weight: 700;
    padding: 0.42em 0.8em;
    border-radius: 50rem;
}

/* Dark mode: translucent pill badges like the mockup */
[data-bs-theme="dark"] .badge.bg-success {
    background-color: rgba(52, 211, 153, 0.2) !important;
    color: #6ee7b7;
}

[data-bs-theme="dark"] .badge.bg-warning {
    background-color: rgba(251, 191, 36, 0.2) !important;
    color: #fcd34d !important;
}

[data-bs-theme="dark"] .badge.bg-danger {
    background-color: rgba(251, 113, 133, 0.2) !important;
    color: #fda4af;
}

[data-bs-theme="dark"] .badge.bg-secondary {
    background-color: rgba(148, 163, 184, 0.2) !important;
    color: #cbd5e1;
}

[data-bs-theme="dark"] .badge.bg-info {
    background-color: rgba(56, 189, 248, 0.2) !important;
    color: #7dd3fc;
}

[data-bs-theme="dark"] .badge.bg-dark {
    background-color: rgba(251, 191, 36, 0.25) !important;
    color: #fcd34d;
}

[data-bs-theme="dark"] .badge.bg-primary {
    background-color: rgba(251, 191, 36, 0.2) !important;
    color: #fcd34d;
}

/* Text helpers keep contrast in dark */
[data-bs-theme="dark"] .text-muted { color: #94a3b8 !important; }
[data-bs-theme="dark"] .text-danger { color: #fda4af !important; }
[data-bs-theme="dark"] .text-success { color: #6ee7b7 !important; }
[data-bs-theme="dark"] .text-warning { color: #fcd34d !important; }

/* Templates use bg-white / table-light in a few places — neutralize them
   in dark mode so surfaces follow the theme without editing the markup. */
[data-bs-theme="dark"] .bg-white { background-color: transparent !important; }
/* Bootstrap's table variants hardcode black text through several custom
   properties; reset every one of them or cells stay black on dark. */
[data-bs-theme="dark"] .table-light,
[data-bs-theme="dark"] .table-secondary,
[data-bs-theme="dark"] .table-primary,
[data-bs-theme="dark"] .table-success,
[data-bs-theme="dark"] .table-warning,
[data-bs-theme="dark"] .table-danger,
[data-bs-theme="dark"] .table-info {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text-main);
    --bs-table-color-type: var(--text-main);
    --bs-table-color-state: var(--text-main);
    --bs-table-striped-color: var(--text-main);
    --bs-table-active-color: var(--text-main);
    --bs-table-hover-color: var(--text-main);
    --bs-table-border-color: var(--card-border);
    color: var(--text-main);
}

/* Column headers keep the quieter label color. */
[data-bs-theme="dark"] .table thead.table-light,
[data-bs-theme="dark"] .table thead.table-light th {
    --bs-table-color: var(--thead-color);
    --bs-table-color-type: var(--thead-color);
    --bs-table-color-state: var(--thead-color);
    color: var(--thead-color);
}

/* Utility classes that force dark text on now-translucent surfaces. */
[data-bs-theme="dark"] .text-dark,
[data-bs-theme="dark"] .text-black,
[data-bs-theme="dark"] .text-body { color: var(--text-main) !important; }

[data-bs-theme="dark"] .bg-light {
    background-color: var(--chip-bg) !important;
    color: var(--text-main);
}
[data-bs-theme="dark"] .alert-light {
    background-color: rgba(51, 65, 85, 0.3);
    border-color: rgba(71, 85, 105, 0.4);
    color: #cbd5e1;
}
[data-bs-theme="dark"] .list-group-item { background-color: transparent; }

/* ------------------------------------------------------------------ */
/* Login page                                                          */
/* ------------------------------------------------------------------ */

.login-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(ellipse at top right, rgba(251, 191, 36, 0.18) 0%, transparent 55%),
        radial-gradient(ellipse at bottom left, rgba(245, 158, 11, 0.12) 0%, transparent 55%),
        linear-gradient(160deg, #0f172a 0%, #1e293b 100%);
}

.login-card {
    max-width: 430px;
    width: 100%;
    border-radius: 1.2rem;
    box-shadow: 0 25px 60px rgba(0, 0, 0, 0.45);
}

.login-icon {
    width: 74px;
    height: 74px;
    border-radius: 1.2rem;
    background: linear-gradient(135deg, #fcd34d 0%, #f59e0b 100%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 2.2rem;
    color: #0f172a;
    box-shadow: 0 10px 30px rgba(251, 191, 36, 0.35);
}

/* ------------------------------------------------------------------ */
/* Footer                                                              */
/* ------------------------------------------------------------------ */

.app-footer {
    color: var(--text-muted);
    font-size: 0.85rem;
    border-top: 1px solid var(--topbar-border);
    background: transparent;
}

/* ------------------------------------------------------------------ */
/* Barcode check-in                                                    */
/* ------------------------------------------------------------------ */

.scan-card { border-width: 2px !important; }

#scan-input {
    font-size: 1.25rem;
    letter-spacing: 2px;
    text-align: center;
}

.scan-result {
    min-height: 92px;
    border-radius: var(--radius);
    padding: 0.9rem 1.1rem;
    display: flex;
    align-items: center;
    border: 1px dashed var(--card-border);
    transition: background-color 0.12s ease;
}

.scan-result.scan-ok {
    background: rgba(16, 185, 129, 0.12);
    border: 1px solid rgba(16, 185, 129, 0.35);
    color: #047857;
}

.scan-result.scan-warn {
    background: rgba(245, 158, 11, 0.12);
    border: 1px solid rgba(245, 158, 11, 0.35);
    color: #b45309;
}

.scan-result.scan-bad {
    background: rgba(225, 29, 72, 0.1);
    border: 1px solid rgba(225, 29, 72, 0.3);
    color: #be123c;
}

[data-bs-theme="dark"] .scan-result.scan-ok { color: #6ee7b7; }
[data-bs-theme="dark"] .scan-result.scan-warn { color: #fcd34d; }
[data-bs-theme="dark"] .scan-result.scan-bad { color: #fda4af; }

/* Camera barcode scan (modal on the attendance page) */
.camera-frame {
    position: relative;
    margin: 0 auto;
    width: 100%;
    max-width: 420px;
    aspect-ratio: 4 / 3;
    background: #000;
    border-radius: var(--radius);
    overflow: hidden;
    border: 2px solid var(--card-border);
    transition: border-color 0.15s ease;
}

.camera-frame video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* A still guide line, not a decoder overlay — the library scans the whole
   frame regardless, this just tells the person where to hold the card. */
.camera-guide {
    position: absolute;
    inset: 38% 8% 38% 8%;
    border: 2px dashed rgba(255, 255, 255, 0.65);
    border-radius: 6px;
    pointer-events: none;
}

.camera-frame.camera-frame-ok { border-color: #10b981; }
.camera-frame.camera-frame-bad { border-color: #e11d48; }

/* ------------------------------------------------------------------ */
/* Printable member cards                                              */
/* ------------------------------------------------------------------ */

.cards-sheet {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
}

.member-card {
    border: 1px dashed #94a3b8;
    border-radius: 10px;
    padding: 10px 12px 6px;
    text-align: center;
    background: #fff;
    color: #0f172a;
    break-inside: avoid;
}

.member-card-head { border-bottom: 1px solid #e2e8f0; padding-bottom: 5px; margin-bottom: 6px; }
.member-card-gym { font-weight: 800; font-size: 0.85rem; color: #b45309; }
.member-card-name { font-weight: 700; font-size: 1rem; }
.member-card-phone { font-size: 0.8rem; color: #64748b; margin-bottom: 2px; }
.member-card-barcode svg { max-width: 100%; height: auto; }

@media print {
    .cards-sheet { grid-template-columns: repeat(3, 1fr); gap: 8px; }
    .member-card { border-style: dashed; }
}

/* ------------------------------------------------------------------ */
/* Receipt print view — always print light                             */
/* ------------------------------------------------------------------ */

/* Hide the app chrome and print the content itself. (An earlier version hid
   everything except #receipt, which left pages without one — such as the
   member cards — printing blank.) */
@media print {
    .sidebar,
    .sidebar-backdrop,
    .topbar,
    .app-footer,
    .d-print-none { display: none !important; }

    body { background: #fff !important; }

    #main-content,
    main.container-fluid {
        margin: 0 !important;
        padding: 0 !important;
    }

    .card { box-shadow: none !important; }

    #receipt {
        box-shadow: none !important;
        border: none !important;
        background: #fff !important;
        color: #000 !important;
    }

    #receipt table, #receipt th, #receipt td { color: #000 !important; }
}

/* ------------------------------------------------------------------ */
/* Receipt print view — narrow 58mm thermal printers                   */
/* ------------------------------------------------------------------ */

/* Without an explicit page size, the browser lays the receipt out at
   the printer's default (usually A4) and a 58mm roll then only ever
   gets a thin, mostly-empty sliver of that page - the "blank page"
   symptom reported with the 617-R58P Bluetooth printer. Naming the page
   and applying it only to .thermal-receipt keeps every other printed
   screen on the normal A4 default - notably dashboard/report_print.html,
   which (confusingly) reuses the same #receipt id for its own unrelated
   print/PDF layout, so scoping by id alone would have shrunk the whole
   financial report to 58mm too.

   58mm is the ROLL width, not the printable width - confirmed live on a
   real 617-R58P: Windows reports the driver's page as 48mm wide (the
   industry-standard printable area for 58mm paper; ~5mm is eaten by the
   mechanism on each edge). Sizing to 58mm let Chrome ignore our custom
   @page and fall back to the driver's own 48x210mm preset instead, and
   the leftover REM-based Bootstrap spacing (mb-3/pb-3/pt-3/mt-3 - these
   don't scale with the font-size override below, since rem is relative
   to the document root, not this element) pushed the total content
   height just past that page, printing a near-empty second sheet. */
@media print {
    #receipt.thermal-receipt {
        page: thermal-receipt;
        max-width: 44mm;
        margin: 0 auto;
        font-size: 2.6mm;
        line-height: 1.3;
        break-inside: avoid;
        page-break-inside: avoid;
    }
    #receipt.thermal-receipt .card-body { padding: 1mm !important; }
    #receipt.thermal-receipt .fs-2 { font-size: 5.5mm !important; }
    #receipt.thermal-receipt h1 { font-size: 3.2mm !important; margin: 0.5mm 0 !important; }
    #receipt.thermal-receipt .small, #receipt.thermal-receipt .text-muted { font-size: 2.1mm; }
    #receipt.thermal-receipt .fs-5 { font-size: 3mm !important; }
    /* Bootstrap's pb-3/mb-3/pt-3/mt-3 are rem-based (relative to the
       document root font-size), so the font-size override above never
       shrinks them - override the actual spacing explicitly instead. */
    #receipt.thermal-receipt .pb-3 { padding-bottom: 1mm !important; }
    #receipt.thermal-receipt .mb-3 { margin-bottom: 1mm !important; }
    #receipt.thermal-receipt .pt-3 { padding-top: 1mm !important; }
    #receipt.thermal-receipt .mt-3 { margin-top: 1mm !important; }

    /* Bootstrap's table lays th/td side by side - far too cramped at
       this width, so stack label above value like a real receipt. */
    #receipt.thermal-receipt table,
    #receipt.thermal-receipt tbody,
    #receipt.thermal-receipt tr,
    #receipt.thermal-receipt th,
    #receipt.thermal-receipt td {
        display: block;
        width: 100%;
        text-align: start !important;
        border: none !important;
        padding: 0.2mm 0 !important;
    }
    #receipt.thermal-receipt th { font-weight: 600; padding-top: 0.8mm !important; }
    #receipt.thermal-receipt tr.border-top { border-top: 1px dashed #000 !important; margin-top: 0.6mm; }
}

@page thermal-receipt {
    size: 48mm auto;
    margin: 1mm;
}

/* ------------------------------------------------------------------ */
/* Official association paperwork (paid extra — paperwork app)         */
/* ------------------------------------------------------------------ */

/* These are forms handed in to the Directorate of Youth and Sports and to
   the club's insurer, so they are laid out as plain official paper: black
   on white, ruled tables, no rounded corners or brand colours. They must
   look the same printed as the blank forms the club used before. */
.doc-sheet {
    background: #fff;
    color: #000;
    max-width: 21cm;
    min-height: 27cm;
    margin: 0 auto;
    padding: 1.6cm 1.5cm;
    border: 1px solid var(--card-border);
    font-size: 12.5pt;
    line-height: 1.9;
}

/* Always ink-on-paper, even when the interface is in dark mode: this sheet
   is a document, not part of the app's chrome. */
[data-bs-theme="dark"] .doc-sheet { background: #fff; color: #000; }
[data-bs-theme="dark"] .doc-sheet .doc-table th,
[data-bs-theme="dark"] .doc-sheet .doc-table td { border-color: #000; color: #000; }

.doc-state { text-align: center; font-size: 11.5pt; letter-spacing: 1px; margin-bottom: 4mm; }

.doc-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 6mm; }
.doc-head .doc-logo { width: 2.4cm; flex-shrink: 0; }
.doc-head .doc-logo img { width: 100%; height: auto; object-fit: contain; }
.doc-head .doc-identity { flex: 1; text-align: center; line-height: 1.7; }
.doc-head .doc-identity .club { font-weight: 700; font-size: 13pt; }
.doc-head .doc-meta { min-width: 4.5cm; font-size: 11pt; text-align: start; }

.doc-title {
    text-align: center;
    font-size: 19pt;
    font-weight: 700;
    margin: 8mm auto 6mm;
    padding: 2mm 0;
    border-top: 2px solid #000;
    border-bottom: 2px solid #000;
    width: fit-content;
    min-width: 7cm;
}

.doc-fields { margin: 6mm 0; }
.doc-fields .row-line { display: flex; gap: 8px; margin-bottom: 4.5mm; }
.doc-fields .row-line .label { font-weight: 700; min-width: 4.2cm; }
/* Dotted rule so a field left empty is still obviously a field to fill in
   by hand — several of these forms are half-typed, half-handwritten. */
.doc-fields .row-line .value { flex: 1; border-bottom: 1px dotted #555; min-height: 1.4em; }

.doc-table { width: 100%; border-collapse: collapse; margin: 5mm 0; font-size: 11.5pt; }
.doc-table th, .doc-table td { border: 1px solid #000; padding: 1.6mm 2mm; text-align: center; }
.doc-table th { font-weight: 700; background: #f2f2f2; }
.doc-table td.text-start { text-align: start; }
.doc-table tr { break-inside: avoid; page-break-inside: avoid; }

.doc-total { font-weight: 700; }

.doc-signatures { display: flex; justify-content: space-between; gap: 24px; margin-top: 14mm; }
.doc-signatures .sig { min-width: 5.5cm; }
.doc-signatures .sig .who { font-weight: 700; margin-bottom: 1.6cm; }

.doc-place { margin-top: 10mm; }

@media print {
    /* The sheet is the page: no frame, no app background around it. */
    .doc-sheet {
        border: 0;
        margin: 0;
        padding: 0;
        max-width: 100%;
        min-height: auto;
        font-size: 12pt;
    }
    .doc-table th { background: #f2f2f2 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

@page { size: A4; margin: 12mm; }

/* ---------------------------------------------------------------- phones
   The lists are built for a desk screen. Below 768px the secondary columns
   already fold away in the templates; these two rules do the rest, so what
   is left fits the width of a phone instead of asking for a sideways drag:
   a slightly smaller type, tighter cells, and text allowed to wrap rather
   than forcing the table wider than the card holding it. */
@media (max-width: 767.98px) {
    .table-responsive table { font-size: .875rem; }
    .table-responsive th,
    .table-responsive td {
        padding-inline: .45rem;
        white-space: normal;
    }
}

/* ------------------------------------------------------------------ */

/* Deliberately covers the page rather than sitting in a corner: at a busy
   desk the staff member is looking at the queue, not the screen, and the
   whole point is that an unpaid balance or an expired card is impossible to
   miss. It dismisses itself so nobody has to click between scans. */
.checkin-screen {
    position: fixed;
    inset: 0;
    z-index: 1080;              /* over Bootstrap modals (1055) and the sidebar */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(15, 23, 42, 0.72);
    backdrop-filter: blur(3px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease, visibility 0.18s ease;
}

.checkin-screen.show { opacity: 1; visibility: visible; }

.checkin-card {
    background: var(--card-bg);
    color: var(--text-main);
    border-radius: var(--radius);
    width: min(680px, 100%);
    max-height: 100%;
    overflow-y: auto;
    box-shadow: 0 25px 60px rgba(0, 0, 0, 0.35);
    /* A thick edge in the result colour: readable from a step back, which is
       where the person at the desk usually is. */
    border-top: 10px solid var(--accent);
    transform: translateY(12px) scale(0.98);
    transition: transform 0.18s ease;
}
.checkin-screen.show .checkin-card { transform: none; }

.checkin-card.ok   { border-top-color: #10b981; }
.checkin-card.warn { border-top-color: #f59e0b; }
.checkin-card.bad  { border-top-color: #e11d48; }

.checkin-body { display: flex; gap: 1.25rem; padding: 1.5rem; align-items: flex-start; }

.checkin-photo {
    width: 118px; height: 118px; flex-shrink: 0;
    border-radius: var(--radius);
    object-fit: cover;
    background: var(--chip-bg);
    border: 1px solid var(--card-border);
}
/* Same square as the photo, so a member without one does not shift the layout. */
.checkin-photo.is-initial {
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 3rem; font-weight: 700; color: var(--accent-strong);
}

.checkin-name { font-size: 1.6rem; font-weight: 800; line-height: 1.25; }
.checkin-meta { color: var(--text-muted); font-size: .95rem; }

.checkin-verdict {
    display: flex; align-items: center; gap: .6rem;
    font-size: 1.05rem; font-weight: 700;
    padding: .7rem 1rem; margin: .9rem 0 0; border-radius: .75rem;
}
.checkin-verdict.ok   { background: rgba(16, 185, 129, .12); color: #047857; }
.checkin-verdict.warn { background: rgba(245, 158, 11, .14); color: #b45309; }
.checkin-verdict.bad  { background: rgba(225, 29, 72, .12);  color: #be123c; }
[data-bs-theme="dark"] .checkin-verdict.ok   { color: #6ee7b7; }
[data-bs-theme="dark"] .checkin-verdict.warn { color: #fcd34d; }
[data-bs-theme="dark"] .checkin-verdict.bad  { color: #fda4af; }

.checkin-rows { border-top: 1px solid var(--card-border); }
.checkin-row {
    display: flex; justify-content: space-between; gap: 1rem;
    padding: .65rem 1.5rem; border-bottom: 1px solid var(--row-border);
}
.checkin-row .label { color: var(--text-muted); }
.checkin-row .value { font-weight: 700; }

/* The debt line is the reason this screen exists — it should read as an
   alarm, not as one more row of data. */
.checkin-debt {
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
    padding: .9rem 1.5rem;
    background: rgba(225, 29, 72, .1);
    border-top: 1px solid rgba(225, 29, 72, .3);
    color: #be123c; font-weight: 800; font-size: 1.15rem;
}
[data-bs-theme="dark"] .checkin-debt { color: #fda4af; }

.checkin-foot {
    display: flex; justify-content: space-between; align-items: center;
    gap: .75rem; padding: .8rem 1.5rem 1.1rem;
}
/* Counts the seconds left before it hides itself, so the staff member can see
   the screen is about to go rather than wondering if it froze. */
.checkin-timer { color: var(--text-muted); font-size: .85rem; }

@media (max-width: 575.98px) {
    .checkin-body { flex-direction: column; align-items: center; text-align: center; }
    .checkin-name { font-size: 1.35rem; }
}

@media print { .checkin-screen { display: none !important; } }
